added yl_speak_up.get_npc_users_of_variable and modified saving of npc data so that the necessary data is stored

This commit is contained in:
Sokomine 2021-07-05 19:31:29 +02:00
parent 8ea4123e01
commit c3c7b7e2da
2 changed files with 140 additions and 0 deletions

View File

@ -152,6 +152,8 @@ yl_speak_up.save_dialog = function(n_id, dialog)
return false
end
local p = save_path(n_id)
-- save some data (in particular usage of quest variables)
yl_speak_up.update_stored_npc_data(n_id, dialog)
local content = minetest.write_json(dialog)
return minetest.safe_file_write(p, content)
end

View File

@ -49,6 +49,9 @@ yl_speak_up.load_quest_variables = function()
end
end
yl_speak_up.player_vars = data
if(not(yl_speak_up.player_vars.meta)) then
yl_speak_up.player_vars["meta"] = {}
end
end
-- do so when this file is parsed
yl_speak_up.load_quest_variables()
@ -237,3 +240,138 @@ yl_speak_up.strip_pname_from_varlist = function(var_list, pname)
end
return var_list_text
end
-- helper function for saving NPC data;
-- this only works if *someone* is currently talking to that NPC
yl_speak_up.get_pname_for_n_id = function(n_id)
for k, v in pairs(yl_speak_up.speak_to) do
if(v and v.n_id and v.n_id == n_id) then
return k
end
end
end
-- the dialog data of an NPC is saved - use this to save some statistical data
-- plus store which variables are used by this NPC
yl_speak_up.update_stored_npc_data = function(n_id, dialog)
-- in order to determine the position of the NPC, we need its object
local pname = yl_speak_up.get_pname_for_n_id(n_id)
local npc_pos = ""
if(pname) then
local obj = yl_speak_up.speak_to[pname].obj
if(obj and obj:get_pos()) then
npc_pos = minetest.pos_to_string(obj:get_pos())
end
end
-- gather statistical data about the NPC and find out which variables it uses
local anz_dialogs = 0
local anz_options = 0
local anz_preconditions = 0
local anz_actions = 0
local anz_effects = 0
local anz_trades = 0
local variables_p = {}
local variables_e = {}
if(dialog and dialog.n_dialogs) then
for d_id, d in pairs(dialog.n_dialogs) do
anz_dialogs = anz_dialogs + 1
if(d and d.d_options) then
for o_id, o in pairs(d.d_options) do
anz_options = anz_options + 1
if(o and o.o_prerequisites) then
for p_id, p in pairs(o.o_prerequisites) do
anz_preconditions = anz_preconditions + 1
if(p and p.p_type and p.p_type == "state"
and p.p_variable and p.p_variable ~= "") then
variables_p[ p.p_variable ] = true
end
end
end
if(o and o.actions) then
for a_id, a_data in pairs(o.actions) do
anz_actions = anz_actions + 1
end
end
if(o and o.o_results) then
for r_id, r in pairs(o.o_results) do
anz_effects = anz_effects + 1
if(r and r.r_type and r.r_type == "state"
and r.r_variable and r.r_variable ~= "") then
variables_e[ r.r_variable ] = true
end
end
end
end
end
end
end
if(dialog and dialog.trades) then
for trade_id, t_data in pairs(dialog.trades) do
-- not a trade that is the action of a dialog option; only trade list trades count
if(not(t_data.d_id)) then
anz_trades = anz_trades + 1
end
end
end
-- add a special variable (if needed) for saving the NPC meta data
if(not(yl_speak_up.player_vars[ "$NPC_META_DATA$" ])) then
yl_speak_up.player_vars[ "$NPC_META_DATA$" ] = {}
end
yl_speak_up.player_vars[ "$NPC_META_DATA$" ][ n_id ] = {
n_id = n_id,
name = tostring(dialog.n_npc),
owner = tostring(yl_speak_up.npc_owner[ n_id ]),
pos = tostring(npc_pos),
anz_dialogs = anz_dialogs,
anz_options = anz_options,
anz_preconditions = anz_preconditions,
anz_actions = anz_actions,
anz_effects = anz_effects,
anz_trades = anz_trades,
last_modified = os.date(),
}
-- save in the variables' metadata which NPC uses it
-- (this is what we're mostly after - know which variable is used in which NPC)
for k, v in pairs(variables_p) do
-- if the variable does not exist: create it
if(not(yl_speak_up.player_vars[ k ])) then
yl_speak_up.player_vars[ k ] = {}
end
if(not(yl_speak_up.player_vars[ k ][ "$META$" ])) then
yl_speak_up.player_vars[ k ][ "$META$"] = { used_by_npc = {} }
end
yl_speak_up.player_vars[ k ][ "$META$"][ "used_by_npc" ][ n_id ] = true
end
for k, v in pairs(variables_e) do
-- if the variable does not exist: create it
if(not(yl_speak_up.player_vars[ k ])) then
yl_speak_up.player_vars[ k ] = {}
end
if(not(yl_speak_up.player_vars[ k ][ "$META$" ])) then
yl_speak_up.player_vars[ k ][ "$META$"] = { used_by_npc = {} }
end
yl_speak_up.player_vars[ k ][ "$META$"][ "used_by_npc" ][ n_id ] = true
end
-- force writing the data
yl_speak_up.save_quest_variables(true)
end
yl_speak_up.get_npc_users_of_variable = function(var_name)
-- no variable, or nothing stored? then it's not used by any NPC either
if(not(var_name)
or not(yl_speak_up.player_vars[ var_name ])
or not(yl_speak_up.player_vars[ var_name ][ "$META$"])
or not(yl_speak_up.player_vars[ var_name ][ "$META$"][ "used_by_npc" ])) then
return {}
end
local npc_list = {}
for n_id, v in pairs(yl_speak_up.player_vars[ var_name ][ "$META$"][ "used_by_npc" ]) do
table.insert(npc_list, n_id)
end
table.sort(npc_list)
return npc_list
end