Compare commits

...

10 Commits

Author SHA1 Message Date
SmallJoker
8b63913bf8 Prevent error on incorrect index selection 2023-09-03 08:38:03 +02:00
fluxionary
8085ab8988
Fix logic error due to operator precedence when checking item name (#8) 2023-05-23 20:34:16 +02:00
ThePython
994c1a263d
Various small improvements (#7)
* Crafting recipe for item is now shapeless
* Item now uses right click to open in MineClone (otherwise still left click)
* Added `personal_log_teleport` privilege (and `personal_log_teleport_privilege` setting to enable), in case you only want people to teleport to places they've already been to and saved in the log, and not use `/teleport`
* Replaced `priviledge` with `privilege` everywhere it's misspelled
* Tested in both MineClone and Minetest Game
2023-04-11 19:29:08 +02:00
blaboing
ad6c6b1138
Fix undeclared "mcl_formspec" on non mcl games (#6) 2023-01-24 11:54:59 +01:00
Nathaniel Freeman
021052f434
Add Spanish translation (#2)
Co-authored-by: PsycoJaker <psycojaker@tutanota.com>
2021-04-05 19:03:52 +02:00
FaceDeer
c751e3681f fix undeclared local 2020-11-27 22:56:43 -07:00
FaceDeer
0fe47ebaad add an API for other mods to add new entries with 2020-11-27 22:38:27 -07:00
FaceDeer
acf796e9b8 update readme 2020-11-22 20:02:52 -07:00
FaceDeer
f429507c74 add ability to open via chat command (disabled by default) 2020-11-22 19:55:07 -07:00
FaceDeer
0569927f33 basic mineclone2 compatibility 2020-07-15 21:49:19 -06:00
7 changed files with 314 additions and 71 deletions

53
i18n.py
View File

@ -13,19 +13,22 @@
from __future__ import print_function
import os, fnmatch, re, shutil, errno
from sys import argv as _argv
from sys import stderr as _stderr
# Running params
params = {"recursive": False,
"help": False,
"mods": False,
"verbose": False,
"folders": []
"folders": [],
"no-old-file": False
}
# Available CLI options
options = {"recursive": ['--recursive', '-r'],
"help": ['--help', '-h'],
"mods": ['--installed-mods'],
"verbose": ['--verbose', '-v']
"verbose": ['--verbose', '-v'],
"no-old-file": ['--no-old-file']
}
# Strings longer than this will have extra space added between
@ -64,6 +67,8 @@ DESCRIPTION
run on all subfolders of paths given
{', '.join(options["mods"])}
run on locally installed modules
{', '.join(options["no-old-file"])}
do not create *.old files
{', '.join(options["verbose"])}
add output information
''')
@ -108,13 +113,15 @@ def main():
#group 2 will be the string, groups 1 and 3 will be the delimiters (" or ')
#See https://stackoverflow.com/questions/46967465/regex-match-text-in-either-single-or-double-quote
pattern_lua = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
pattern_lua_bracketed = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL)
pattern_lua_s = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
pattern_lua_fs = re.compile(r'[\.=^\t,{\(\s]N?FS\(\s*(["\'])((?:\\\1|(?:(?!\1)).)*)(\1)[\s,\)]', re.DOTALL)
pattern_lua_bracketed_s = re.compile(r'[\.=^\t,{\(\s]N?S\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL)
pattern_lua_bracketed_fs = re.compile(r'[\.=^\t,{\(\s]N?FS\(\s*\[\[(.*?)\]\][\s,\)]', re.DOTALL)
# Handles "concatenation" .. " of strings"
pattern_concat = re.compile(r'["\'][\s]*\.\.[\s]*["\']', re.DOTALL)
pattern_tr = re.compile(r'(.+?[^@])=(.*)')
pattern_tr = re.compile(r'(.*?[^@])=(.*)')
pattern_name = re.compile(r'^name[ ]*=[ ]*([^ \n]*)')
pattern_tr_filename = re.compile(r'\.tr$')
pattern_po_language_code = re.compile(r'(.*)\.po$')
@ -205,8 +212,10 @@ def mkdir_p(path):
# dKeyStrings is a dictionary of localized string to source file sets
# dOld is a dictionary of existing translations and comments from
# the previous version of this text
def strings_to_text(dkeyStrings, dOld, mod_name):
def strings_to_text(dkeyStrings, dOld, mod_name, header_comments):
lOut = [f"# textdomain: {mod_name}\n"]
if header_comments is not None:
lOut.append(header_comments)
dGroupedBySource = {}
@ -266,7 +275,7 @@ def write_template(templ_file, dkeyStrings, mod_name):
# read existing template file to preserve comments
existing_template = import_tr_file(templ_file)
text = strings_to_text(dkeyStrings, existing_template[0], mod_name)
text = strings_to_text(dkeyStrings, existing_template[0], mod_name, existing_template[2])
mkdir_p(os.path.dirname(templ_file))
with open(templ_file, "wt", encoding='utf-8') as template_file:
template_file.write(text)
@ -282,9 +291,13 @@ def read_lua_file_strings(lua_file):
text = re.sub(pattern_concat, "", text)
strings = []
for s in pattern_lua.findall(text):
for s in pattern_lua_s.findall(text):
strings.append(s[1])
for s in pattern_lua_bracketed.findall(text):
for s in pattern_lua_bracketed_s.findall(text):
strings.append(s)
for s in pattern_lua_fs.findall(text):
strings.append(s[1])
for s in pattern_lua_bracketed_fs.findall(text):
strings.append(s)
for s in strings:
@ -302,9 +315,11 @@ def read_lua_file_strings(lua_file):
# returns both a dictionary of translations
# and the full original source text so that the new text
# can be compared to it for changes.
# Returns also header comments in the third return value.
def import_tr_file(tr_file):
dOut = {}
text = None
header_comment = None
if os.path.exists(tr_file):
with open(tr_file, "r", encoding='utf-8') as existing_file :
# save the full text to allow for comparison
@ -318,6 +333,16 @@ def import_tr_file(tr_file):
for line in existing_file.readlines():
line = line.rstrip('\n')
if line[:3] == "###":
if header_comment is None:
# Save header comments
header_comment = latest_comment_block
# Stip textdomain line
tmp_h_c = ""
for l in header_comment.split('\n'):
if not l.startswith("# textdomain:"):
tmp_h_c += l + '\n'
header_comment = tmp_h_c
# Reset comment block if we hit a header
latest_comment_block = None
continue
@ -338,7 +363,7 @@ def import_tr_file(tr_file):
outval["comment"] = latest_comment_block
latest_comment_block = None
dOut[match.group(1)] = outval
return (dOut, text)
return (dOut, text, header_comment)
# Walks all lua files in the mod folder, collects translatable strings,
# and writes it to a template.txt file
@ -377,11 +402,12 @@ def update_tr_file(dNew, mod_name, tr_file):
dOld = tr_import[0]
textOld = tr_import[1]
textNew = strings_to_text(dNew, dOld, mod_name)
textNew = strings_to_text(dNew, dOld, mod_name, tr_import[2])
if textOld and textOld != textNew:
print(f"{tr_file} has changed.")
shutil.copyfile(tr_file, f"{tr_file}.old")
if not params["no-old-file"]:
shutil.copyfile(tr_file, f"{tr_file}.old")
with open(tr_file, "w", encoding='utf-8') as new_tr_file:
new_tr_file.write(textNew)
@ -399,7 +425,8 @@ def update_mod(folder):
for tr_file in get_existing_tr_files(folder):
update_tr_file(data, modname, os.path.join(folder, "locale/", tr_file))
else:
print("Unable to find modname in folder " + folder)
print(f"\033[31mUnable to find modname in folder {folder}.\033[0m", file=_stderr)
exit(1)
# Determines if the folder being pointed to is a mod or a mod pack
# and then runs update_mod accordingly

237
init.lua
View File

@ -1,3 +1,5 @@
personal_log = {}
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
@ -7,6 +9,8 @@ local default_modpath = minetest.get_modpath("default")
local unified_inventory_modpath = minetest.get_modpath("unified_inventory")
local sfinv_buttons_modpath = minetest.get_modpath("sfinv_buttons")
local sfinv_modpath = minetest.get_modpath("sfinv")
local mcl_books_modpath = minetest.get_modpath("mcl_books")
local mcl_formspec_modpath = minetest.get_modpath("mcl_formspec")
local modstore = minetest.get_mod_storage()
@ -14,6 +18,8 @@ local ccompass_recalibration_allowed = minetest.settings:get_bool("ccompass_reca
local ccompass_restrict_target = minetest.settings:get_bool("ccompass_restrict_target", false)
local ccompass_description_prefix = "^Compass to "
local personal_log_teleport_privilege = minetest.settings:get_bool("personal_log_teleport_privilege", false)
local S = minetest.get_translator(modname)
local categories = {
@ -30,6 +36,44 @@ local GENERAL_CATEGORY = 3
local ccompass_prefix = "ccompass:"
local ccompass_prefix_length = #ccompass_prefix
local book_unwritten
local book_written
local author_meta_field
if default_modpath then
book_unwritten = "default:book"
book_written = "default:book_written"
author_meta_field = "owner"
elseif mcl_books_modpath then
book_unwritten = "mcl_books:book"
book_written = "mcl_books:written_book"
author_meta_field = "author"
end
local mcl_formspec_itemslot
if mcl_formspec_modpath then
mcl_formspec_itemslot = mcl_formspec.get_itemslot_bg
end
if personal_log_teleport_privilege then
minetest.register_privilege("personal_log_teleport", {
description =S("Allows the player to teleport using the personal log"),
give_to_singleplayer = false,
give_to_admin = true,
})
privs = {personal_log_teleport=true}
end
local function can_teleport(player)
local player_name = player:get_player_name()
if minetest.check_player_privs(player_name, "teleport") then
return true
elseif personal_log_teleport_privilege and minetest.check_player_privs(player_name, "personal_log_teleport") then
return true
else
return false
end
end
--------------------------------------------------------
-- Data store
@ -66,7 +110,7 @@ local function swap_entry(player_name, state, direction)
if next_index < 1 or next_index > state.entry_counts[category_index] then
return
end
local current_topic = modstore:get_string(player_name .. "_category_" .. category_index .. "_entry_" .. entry_index .. "_topic")
local current_content = modstore:get_string(player_name .. "_category_" .. category_index .. "_entry_" .. entry_index .. "_content")
local next_topic = modstore:get_string(player_name .. "_category_" .. category_index .. "_entry_" .. next_index .. "_topic")
@ -145,11 +189,11 @@ local function write_book(player_name)
-- If it's a location or an event, add a little context to the title
topic = topic .. ": " .. first_line(content)
end
local new_book = ItemStack("default:book_written")
local new_book = ItemStack(book_written)
local meta = new_book:get_meta()
meta:set_string("owner", player_name)
meta:set_string(author_meta_field, player_name)
meta:set_string("title", topic:sub(1, max_title_size))
meta:set_string("description", S("\"@1\" by @2", truncate_string(topic, short_title_size), player_name))
meta:set_string("text", content:sub(1, max_text_size))
@ -185,7 +229,7 @@ local function write_ccompass(player_name, old_compass)
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
@ -206,7 +250,7 @@ end
local function write_item(player_name, itemstack)
local item_name = itemstack:get_name()
if item_name == "default:book" then
if item_name == book_unwritten then
return write_book(player_name)
end
if item_name == "compassgps:cgpsmap" then
@ -227,7 +271,7 @@ local function read_book(itemstack, player_name)
local date_string = topic:match("^%d%d%d%d%-%d%d%-%d%d")
local pos_string = topic:match("^%(%-?[0-9]+,%-?[0-9]+,%-?[0-9]+%)")
local category = GENERAL_CATEGORY
if date_string then
topic = date_string
@ -236,7 +280,7 @@ local function read_book(itemstack, player_name)
topic = pos_string
category = LOCATION_CATEGORY
end
local state = get_state(player_name)
local entry_index = state.entry_counts[category] + 1
state.entry_counts[category] = entry_index
@ -251,7 +295,7 @@ local function read_ccompass(itemstack, player_name)
local prefix_start, prefix_end = content:find(ccompass_description_prefix)
if prefix_end then
content = content:sub(prefix_end+1)
end
end
local state = get_state(player_name)
local entry_index = state.entry_counts[LOCATION_CATEGORY] + 1
state.entry_counts[LOCATION_CATEGORY] = entry_index
@ -276,7 +320,7 @@ end
local function read_item(itemstack, player_name)
local item_name = itemstack:get_name()
if item_name == "default:book_written" then
if item_name == book_written then
read_book(itemstack, player_name)
elseif item_name == "compassgps:cgpsmap_marked" then
read_cgpsmap(itemstack, player_name)
@ -295,7 +339,7 @@ local function ccompass_permitted_target(itemstack)
-- setting compasses when node type restriction is enabled.
return false
end
if not itemstack:get_name():sub(1,ccompass_prefix_length) == ccompass_prefix then
if itemstack:get_name():sub(1,ccompass_prefix_length) ~= ccompass_prefix then
return false
end
local meta = itemstack:get_meta()
@ -303,10 +347,10 @@ local function ccompass_permitted_target(itemstack)
if has_pos and not ccompass_recalibration_allowed then
return false
end
return true
return true
end
local function ccompass_permitted_source(itemstack)
if not itemstack:get_name():sub(1,ccompass_prefix_length) == ccompass_prefix then
if itemstack:get_name():sub(1,ccompass_prefix_length) ~= ccompass_prefix then
return false
end
local meta = itemstack:get_meta()
@ -321,32 +365,33 @@ local detached_callbacks = {
allow_put = function(inv, listname, index, stack, player)
local stack_name = stack:get_name()
if listname == "export_item" then
if stack_name == "default:book" then
if stack_name == book_unwritten then
return 1
end
local player_name = player:get_player_name()
local state = get_state(player_name)
local category = state.category
if category == LOCATION_CATEGORY and
if category == LOCATION_CATEGORY and
(stack_name == "compassgps:cgpsmap" or
ccompass_permitted_target(stack)) then
return 1
end
return 0
elseif listname == "import_item" then
if stack_name == "default:book_written" or
if stack_name == book_written or
stack_name == "compassgps:cgpsmap_marked" or
ccompass_permitted_source(stack) then
return 1
end
return 0
end
return 0
end,
on_put = function(inv, listname, index, stack, player)
local player_name = player:get_player_name()
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, new_item)
elseif listname == "import_item" then
read_item(stack, player_name)
@ -356,7 +401,7 @@ local detached_callbacks = {
local item_invs = {}
local function ensure_detached_inventory(player_name)
if item_invs[player_name] or not(default_modpath or ccompass_modpath or compassgps_modpath) then
if item_invs[player_name] or not(default_modpath or mcl_books_modpath or ccompass_modpath or compassgps_modpath) then
return
end
local inv = minetest.create_detached_inventory("personal_log_"..player_name, detached_callbacks)
@ -387,7 +432,7 @@ end
local import_mods = {}
local export_generic_mods = {}
local export_location_mods = {}
if default_modpath then
if default_modpath or mcl_books_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"))
@ -437,7 +482,12 @@ local function item_formspec(player_name, category, listname, topic)
.. "list[current_player;main;0,1.5;8,4;]"
.. "listring[]"
.. "button[3.5,5.5;1,1;back;"..S("Back").."]"
if mcl_formspec_itemslot then
formspec = formspec .. mcl_formspec_itemslot(3.5, 0, 1, 1)
.. mcl_formspec_itemslot(0,1.5,8,4)
end
return formspec
end
@ -449,9 +499,9 @@ local function make_personal_log_formspec(player)
local state = get_state(player_name)
local category_index = state.category
ensure_detached_inventory(player_name)
local formspec = {
"formspec_version[2]"
.."size[10,10]"
@ -461,26 +511,20 @@ local function make_personal_log_formspec(player)
.. "label[0.5,0.5;"..S("Category:").."]"
.. "label[4.5,0.5;"..S("Personal Log Entries").."]"
}
local entries = {}
for i = 1, state.entry_counts[category_index] do
table.insert(entries, modstore:get_string(player_name .. "_category_" .. category_index .. "_entry_" .. i .. "_content"))
end
local entry = ""
local entry_selected = state.entry_selected[category_index]
if entry_selected > 0 then
entry = entries[entry_selected]
end
local entry = entries[entry_selected] or ""
local topics = {}
for i = 1, state.entry_counts[category_index] do
table.insert(topics, modstore:get_string(player_name .. "_category_" .. category_index .. "_entry_" .. i .. "_topic"))
end
local topic = ""
if entry_selected > 0 then
topic = topics[entry_selected]
end
local topic = topics[entry_selected] or ""
formspec[#formspec+1] = "tablecolumns[text;text]table[0.5,1.0;9,4.75;log_table;"
for i, entry in ipairs(entries) do
formspec[#formspec+1] = minetest.formspec_escape(truncate_string(topics[i], 30)) .. ","
@ -488,7 +532,7 @@ local function make_personal_log_formspec(player)
formspec[#formspec+1] = ","
end
formspec[#formspec] = ";"..entry_selected.."]" -- don't use +1, this overwrites the last ","
if category_index == GENERAL_CATEGORY then
formspec[#formspec+1] = "textarea[0.5,6.0;9,0.5;topic_data;;" .. minetest.formspec_escape(topic) .. "]"
formspec[#formspec+1] = "textarea[0.5,6.5;9,1.75;entry_data;;".. minetest.formspec_escape(entry) .."]"
@ -502,12 +546,11 @@ local function make_personal_log_formspec(player)
.."button[4.5,0;2,0.5;move_up;"..S("Move Up").."]"
.."button[4.5,0.75;2,0.5;move_down;"..S("Move Down").."]"
.."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 can_teleport(player) then
formspec[#formspec+1] = "button[7,0.75;2,0.5;teleport;"..S("Teleport") .."]"
end
if default_modpath or ccompass_modpath or compassgps_modpath then
if default_modpath or mcl_books_modpath or ccompass_modpath or compassgps_modpath then
formspec[#formspec+1] = "button[0,0.75;2.0,0.5;copy_to;"..S("Export").."]"
.."button[2,0.75;2.0,0.5;copy_from;"..S("Import").."]"
end
@ -551,7 +594,7 @@ local function on_player_receive_fields(player, fields, update_callback)
return
end
end
if fields.save then
if category == GENERAL_CATEGORY then
save_entry(player_name, category, entry_selected, fields.entry_data, fields.topic_data)
@ -561,7 +604,7 @@ local function on_player_receive_fields(player, fields, update_callback)
update_callback(player)
return
end
if fields.create then
local content = ""
local general_topic = ""
@ -569,7 +612,7 @@ local function on_player_receive_fields(player, fields, update_callback)
content = fields.entry_data
general_topic = fields.topic_data
end
local entry_index = state.entry_counts[category] + 1
state.entry_counts[category] = entry_index
state.entry_selected[category] = entry_index
@ -586,7 +629,7 @@ local function on_player_receive_fields(player, fields, update_callback)
update_callback(player)
return
end
if fields.move_up then
swap_entry(player_name, state, -1)
update_callback(player)
@ -602,11 +645,11 @@ local function on_player_receive_fields(player, fields, update_callback)
update_callback(player)
return
end
if fields.teleport
and category == LOCATION_CATEGORY
and valid_entry_selected
and minetest.check_player_privs(player_name, "teleport") then
and (can_teleport(player)) then
local pos_string = modstore:get_string(player_name .. "_category_" .. category .. "_entry_" .. entry_selected .. "_topic")
local pos = minetest.string_to_pos(pos_string)
if pos then
@ -710,22 +753,106 @@ end
-----------------------------------------------------------------------------------------------------
-- Craftable item
local craftable_setting = minetest.settings:get_bool("personal_log_craftable_item", false)
if minetest.settings:get_bool("personal_log_craftable_item", false) then
if craftable_setting or not (unified_inventory_modpath or sfinv_modpath or sfinv_buttons_modpath) then
minetest.register_craftitem("personal_log:book", {
description = S("Personal Log"),
inventory_image = "personal_log_open_book.png",
groups = {book = 1, flammable = 3},
on_use = function(itemstack, user, pointed_thing)
local name = user:get_player_name()
local attributes = {
description = S("Personal Log"),
inventory_image = "personal_log_open_book.png",
groups = {book = 1, flammable = 3},
}
if mcl_formspec_modpath then
attributes.on_secondary_use = function(itemstack, user, pointed_thing)
local name = user:get_player_name()
minetest.show_formspec(name,"personal_log:root", make_personal_log_formspec(user))
end
attributes.on_place = function(itemstack, user, pointed_thing)
if not user:get_player_control().sneak then
local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing)
if new_stack then
return new_stack
end
end
local name = user:get_player_name()
minetest.show_formspec(name,"personal_log:root", make_personal_log_formspec(user))
end
else
attributes.on_use = function(itemstack, user, pointed_thing)
local name = user:get_player_name()
minetest.show_formspec(name,"personal_log:root", make_personal_log_formspec(user))
end
end
minetest.register_craftitem("personal_log:book", attributes)
minetest.register_craft({
output = "personal_log:book",
type = "shapeless",
recipe = {book_unwritten, book_unwritten}
})
end
--------------------------------------------------------------------------------------------------------
-- Chat command
local chat_command = minetest.settings:get_bool("personal_log_chat_command", false)
local chat_command_priv = minetest.settings:get_bool("personal_log_chat_command_privilege", false)
or minetest.settings:get_bool("personal_log_chat_command_priviledge", false) -- backwards compat
if chat_command then
local privs = nil
if chat_command_priv then
minetest.register_privilege("personal_log", {
description =S("Allows the player to access a personal log via chat command"),
give_to_singleplayer = false,
give_to_admin = true,
})
privs = {personal_log=true}
end
minetest.register_chatcommand("log", {
description = S("Open your personal log"),
privs = privs,
func = function(name, param)
local user = minetest.get_player_by_name(name)
minetest.show_formspec(name,"personal_log:root", make_personal_log_formspec(user))
end,
})
minetest.register_craft({
output = "personal_log:book",
recipe = {{"default:book", "default:book"}}
})
end
---------------------------------------------------------------------------------------------------------
-- API
local add_entry_for_player = function(player_name, category, content, topic_content)
local state = get_state(player_name)
local entry_index = state.entry_counts[category] + 1
state.entry_counts[category] = entry_index
state.entry_selected[category] = entry_index
save_entry(player_name, category, entry_index, content, topic_content)
save_state(player_name, state)
end
personal_log.add_location_entry = function(player_name, content, pos)
if pos == nil then
local player = minetest.get_player_by_name(player_name)
pos = player:get_pos()
end
add_entry_for_player(player_name, LOCATION_CATEGORY, content, minetest.pos_to_string(pos))
end
personal_log.add_event_entry = function(player_name, content, event_date)
if event_date == nil then
event_date = os.date("%Y-%m-%d")
end
add_entry_for_player(player_name, EVENT_CATEGORY, content, event_date)
end
personal_log.add_general_entry = function(player_name, content, general_topic)
add_entry_for_player(player_name, GENERAL_CATEGORY, content, general_topic)
end
end

65
locale/personal_log.es.tr Normal file
View File

@ -0,0 +1,65 @@
# textdomain: personal_log
### init.lua ###
#book title and author
"@1" by @2="@1" by @2
#A list of one item
@1=@1
#A list of two items
@1 or @2=@1 o @2
#A list of three items
@1, @2 or @3=@1, @2 or @3
#for combining a location or date (@1) with the first few words of the log entry it's associated with (@2)
@1: @2=@1: @2
Allows the player to access a personal log via chat command=Permitir al jugador acceder al diario personal por medio del chat
#button label for returning to the personal log from import/export
Back=Volver
#label on the category dropdown
Category:=Categoria:
#button label for deleting a personal log entry
Delete=Borrar
#a category of log entry
Event=Evento
#button label
Export=Exportar
#label explaining what items a log entry can be exported to
Export "@1" to @2=Exportar "@1" a @2
#a category of log entry
General=General
#button label
Import=Importar
#label explaining what items a log entry can be imported from
Import an entry from @1=Importar una entrada desde @1
#a category of log entry
Location=Ubicacion
#tab text. Note: not a piece of wood. This is a log as in a record of items
Log=Diario
#button label
Move Down=Mover Abajo
#button label
Move Up=Mover Arriba
#button label
New=Nuevo
Open personal log=Abrir Diario Personal
Open your personal log=Abrir Tu Diario Personal
#item name for a physical representation of the personal log
Personal Log=Diario Personal
#label on the main log UI
Personal Log Entries=Entradas de Diario
#button label
Save=Guardar
#button label
Teleport=Teletransportar
#tooltip explaining what the button that opens the log is for
Your personal log for keeping track of what happens where=Su registro personal para realizar un seguimiento de lo que sucede donde
# an item that log data can be imported from or exported to
a GPS compass map=Mapa de Brújula
# an item that log data can be imported from or exported to
a book=Libro
# an item that log data can be imported from or exported to
a calibrated compass=Brújula calibrada
# an item that log data can be exported to
a compass=una Brújula

View File

@ -1,6 +1,7 @@
# textdomain: personal_log
### init.lua ###
#book title and author
@ -13,6 +14,7 @@
@1, @2 or @3=
#for combining a location or date (@1) with the first few words of the log entry it's associated with (@2)
@1: @2=
Allows the player to access a personal log via chat command=
#button label for returning to the personal log from import/export
Back=
#label on the category dropdown
@ -42,6 +44,7 @@ Move Up=
#button label
New=
Open personal log=
Open your personal log=
#item name for a physical representation of the personal log
Personal Log=
#label on the main log UI

View File

@ -1,3 +1,3 @@
name = personal_log
description = A personal log where players can track events and places
optional_depends = unified_inventory, sfinv_buttons, sfinv, ccompass, default, compassgps
optional_depends = unified_inventory, sfinv_buttons, sfinv, ccompass, default, compassgps, mcl_books, mcl_formspec

View File

@ -18,4 +18,20 @@ Event logs automatically have the current date saved with them when they're crea
General logs have a free-form text field for their topic, players can use these to record any other sort of general information they desire.
There's no limit to how many logs a player can write.
There's no limit to how many logs a player can write.
# Chat command access
Chat command access is disabled by default. If ``personal_log_chat_command`` is set to ``true`` then the ``/log`` chat command can be used to open the personal log.
If you want to enable this for administrators but require players to craft an item, setting ``personal_log_chat_command_priviledge`` to ``true`` will create the ``personal_log`` privilege to control use of that chat command. Admins will have this privilege it by default.
# API
Other mods can automatically add log entries to players' personal logs using the following functions:
``personal_log.add_location_entry(player_name, content, pos)`` -- Content is a string. If pos is not provided it defaults to the player's position.
``personal_log.add_event_entry(player_name, content, event_date)`` -- Content is a string. Date should be in the format "%Y-%m-%d", if it is not provided it will default to the current date.
``personal_log.add_general_entry(player_name, content, general_topic)`` -- Both content and general_topic are strings.

View File

@ -1,2 +1,7 @@
personal_log_inventory_button (Access via a button in SFInv/Unified Inventory) bool true
personal_log_craftable_item (Access via a craftable item) bool false
personal_log_craftable_item (Access via a craftable item) bool false
personal_log_chat_command (Allow the /log chat command to open the log) bool false
personal_log_chat_command_privilege (The personal_log privilege is required to access the log via chat command) bool false
# True if the "personal_log_teleport" privilege is required to teleport, if false, the "teleport" privilege is used instead.
personal_log_teleport_privilege (Add personal_log_teleport privilege) bool false