From 6cb44d54e0b04f22cad292bd98c075b01b2bf634 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Fri, 6 May 2022 19:14:49 +0200 Subject: [PATCH] added npc_talk_generic chatcommand --- README.md | 33 +++++++++++++++ add_generic_dialogs.lua | 90 +++++++++++++++++++++++++++++++++++------ 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 9af66da..573a0e8 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,13 @@ Chat commands NPC, the priv will be considered granted if the executing NPC or the the generic NPC has the priv. +/npc_talk_generic Add or remove NPC from the list of generic dialog providers. + /npc_talk_generic list Lists all generic NPC + /npc_talk_generic add n_3 Adds the dialog from NPC as a + generic dialog. + /npc_talk_generic add n_3 Removes the dialog from NPC as a + generic dialog. + Terminology =========== dialog A text said by the NPC, with diffrent replys the player can @@ -74,6 +81,10 @@ npc_master allows players to edit *any* NPC supported by this mod. code without restrictions. Only grant this to staff members you really trust. +privs Necessary for the commands + npc_talk_privs - grant NPC privs like e.g. execute lua + npc_talk_generic - add or remove an NPC from the list of + generic dialog providers NPC can have privs as well. The NPC... @@ -295,6 +306,25 @@ interaction. You may i.e. set the put and take tables for blocks that do extensive checks on the player object which the NPC simply can't provide. +Data saved in modstorage +======================== +status Set this to 2 to globally deactivate all NPC. +amount Number of NPCs generated in this world. This is + needed to create a uniqe ID for each NPC. +generic_npc_list List of NPC ids whose dialogs shall be used as + generic dialogs. + +Files generated in world folder +=============================== +yl_speak_up.path/ Folder containing the JSON files containing the + stored dialogs of the NPC. +yl_speak_up.inventory_path/ Folder containing the detatched inventories of + the NPC. +yl_speak_up_npc_privs.data File containing the privs of the NPC. +yl_speak_up.player_vars_save_file JSON file containing information about + quest progress and quest data for individual + players. + Generic behaviour ================= Sometimes you may have a group of NPC that ought to show a common behaviour @@ -341,3 +371,6 @@ imported dialogs from that NPC. The options found there will be added into the target NPC and the dialog text will be appended to its dialog text. +The chat command /npc_talk_generic (requires privs priv) is used to list, +add or remove NPC from the list of generic dialog/behaviour providers. + diff --git a/add_generic_dialogs.lua b/add_generic_dialogs.lua index 2e27fbb..08902d3 100644 --- a/add_generic_dialogs.lua +++ b/add_generic_dialogs.lua @@ -96,7 +96,8 @@ yl_speak_up.check_and_add_as_generic_dialog = function(dialog, n_id) local prereq = option.o_prerequisites if(prereq) then for p_id, p in pairs(prereq) do - if(p.p_type ~= "state" and p.p_type ~= "player_inv" and p.p_type ~= "custom") then + if(p.p_type ~= "state" and p.p_type ~= "player_inv" and p.p_type ~= "custom" + and p.p_type ~= "true" and p.p_type ~= "false") then return "Precondition "..tostring(p_id).. " of option "..tostring(one_option).. " of dialog "..tostring(d_id).. @@ -127,7 +128,9 @@ yl_speak_up.check_and_add_as_generic_dialog = function(dialog, n_id) and p.p_type ~= "function" and p.p_type ~= "custom" -- depends on the preconditions of another option - and p.p_type ~= "other") then + and p.p_type ~= "other" + and p.p_type ~= "true" + and p.p_type ~= "false") then return "Precondition "..tostring(p_id).. " of option "..tostring(o_id).. " of dialog "..tostring(d_id).. @@ -367,22 +370,83 @@ yl_speak_up.add_generic_dialogs = function(dialog, current_n_id, player) -- minetest.chat_send_player("singleplayer","injecting option "..tostring(o_id).." into "..tostring(start_dialog_current)..": "..minetest.serialize(o)) end end + -- TODO: add necessary texts end -- TODO: deal with d_got_item return dialog end + +-- a chat command to grant or deny or disallow npc these privs; +-- it is not checked if the NPC exists +minetest.register_chatcommand( 'npc_talk_generic', { + description = "Lists, add or removes the dialogs of NPC as generic dialogs.\n".. + "Call: [list|add|remove|reload] []", + privs = {privs = true}, + func = function(pname, param) + if(not(param) or param == "") then + minetest.chat_send_player(pname, "Usage: [list|add|remove|reload] ") + return + end + local parts = string.split(param, " ") + local do_reload = false + local s = yl_speak_up.modstorage:get_string("generic_npc_list") or "" + local generic_npc_list = string.split(s, " ") + if((parts[1] == "add" or parts[1] == "remove") and #parts == 2) then + local i = table.indexof(generic_npc_list, parts[2]) + if(parts[1] == "add" and i == -1) then + local n_id = parts[2] + table.insert(generic_npc_list, n_id) + local dialog = yl_speak_up.load_dialog(n_id, false) + local res = yl_speak_up.check_and_add_as_generic_dialog(dialog, n_id) + minetest.chat_send_player(pname, "Adding NPC "..tostring(n_id).."..: "..tostring(res)) + do_reload = true + elseif(parts[1] == "remove" and i ~= -1) then + table.remove(generic_npc_list, i) + minetest.chat_send_player(pname, "Removing NPC "..tostring(parts[2]).."..") + do_reload = true + elseif(parts[1] == "reload") then + do_reload = true + end + elseif(parts[1] ~= "list" and parts[1] ~= "reload") then + minetest.chat_send_player(pname, "Usage: [list|add|remove|reload] ") + return + end + + -- actually reload the NPC list + if(do_reload) then + yl_speak_up.load_generic_dialogs() + end + local liste = {} + for n_id, v in pairs(yl_speak_up.generic_dialogs) do + table.insert(liste, n_id) + end + if(#liste < 1) then + minetest.chat_send_player(pname, "No NPC provides generic dialogs.") + else + minetest.chat_send_player(pname, "These NPC provide generic dialogs: ".. + table.concat(liste, ", ")..".") + end + -- store the updated version + yl_speak_up.modstorage:set_string("generic_npc_list", table.concat(generic_npc_list, " ")) + return + end +}) + + yl_speak_up.load_generic_dialogs = function() - -- TODO: keep list of added npc dialogs - local n_id = "n_31" - local dialog = yl_speak_up.load_dialog(n_id, false) - -- TODO: do this check when the generic dialog is added - local res = yl_speak_up.check_and_add_as_generic_dialog(dialog, n_id) - if(res == "OK") then - minetest.log("action", "[MOD] yl_speak_up: ".. - "Generic dialog from NPC "..tostring(n_id).." loaded successfully.") - else - minetest.log("action", "[MOD] yl_speak_up: ".. - "Generic dialog from NPC "..tostring(n_id).." failed to load: "..tostring(res)..".") + -- read list of generic NPC from mod storage + local s = yl_speak_up.modstorage:get_string("generic_npc_list") or "" + for i, n_id in ipairs(string.split(s, " ")) do + local dialog = yl_speak_up.load_dialog(n_id, false) + local res = yl_speak_up.check_and_add_as_generic_dialog(dialog, n_id) + if(res == "OK") then + minetest.log("action", "[MOD] yl_speak_up: ".. + "Generic dialog from NPC "..tostring(n_id).." loaded successfully.") + else + minetest.log("action", "[MOD] yl_speak_up: ".. + "Generic dialog from NPC "..tostring(n_id).." failed to load: ".. + tostring(res)..".") + end end end