only load detached npc inventories when they are really needed - either by the npc dialog or in edit_mode

This commit is contained in:
Sokomine 2024-02-15 22:19:08 +01:00
parent 6f51ddd10d
commit d58789e703
4 changed files with 62 additions and 6 deletions

View File

@ -98,10 +98,54 @@ yl_speak_up.inventory_allow_item = function(player, stack, input_to)
end
-- checks dialog and tries to find out if this dialog needs a detached inventory for the NPC;
-- returns true if the NPC needs one; else false
yl_speak_up.dialog_requires_inventory = function(dialog)
if(not(dialog)) then
return false
end
for t, t_data in pairs(dialog.trades or {}) do
if(t and t ~= "limits") then
return true
end
end
for d_id, d_data in pairs(dialog.n_dialogs or {}) do
for o_id, o_data in pairs(d_data.d_options or {}) do
-- check preconditions:
for p_id, p_data in pairs(o_data.o_prerequisites or {}) do
local t = p_data.p_type or "?"
if(t == "trade" or t == "npc_inv" or t == "player_offered_item") then
return true
end
end
-- check actions:
for a_id, a_data in pairs(o_data.actions or {}) do
local t = a_data.a_type or "?"
if(t == "trade" or t == "npc_gives" or t == "npc_wants") then
return true
end
end
-- check effects:
for r_id, r_data in pairs(o_data.o_results or {}) do
local t = r_data.r_type or "?"
if(t == "block" or t == "craft" or t == "put_into_block_inv"
or t == "take_from_block_inv" or t == "deal_with_offered_item") then
return true
end
end
end
end
-- nothing found that actually uses the NPC's inventory - so don't load it
return false
end
-- create and load the detached inventory in yl_speak_up.after_activate;
-- direct access to this inventory is only possible for players with the right privs
-- (this is an inventory for the *NPC*, which is stored to disk sometimes)
yl_speak_up.load_npc_inventory = function(n_id)
-- if force_load is true, the inventory will be loaded even if the NPC doesn't usually
-- need one (i.e. in edit_mode, or with "show me your inventory").
yl_speak_up.load_npc_inventory = function(n_id, force_load, dialog)
if(not(n_id)) then
return
end
@ -125,9 +169,16 @@ yl_speak_up.load_npc_inventory = function(n_id)
yl_speak_up.npc_inventory_last_used[ n_id ] = os.time()
-- the inventory is already loaded
if( yl_speak_up.npc_inventory[ n_id ]) then
if(yl_speak_up.npc_inventory[ n_id ]) then
return
end
-- check if the NPC actually needs an inventory - else don't load it
if(not(force_load) and dialog
and not(yl_speak_up.dialog_requires_inventory(dialog))) then
return
end
-- create the detached inventory (it is empty for now)
local npc_inv = minetest.create_detached_inventory("yl_speak_up_npc_"..tostring(n_id), {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)

View File

@ -49,6 +49,8 @@ yl_speak_up.input_talk = function(player, formname, fields)
-- result
return
end
-- make sure the inventory of the NPC is loaded
yl_speak_up.load_npc_inventory(n_id, true, nil)
-- for older formspec versions: reset scroll counter
yl_speak_up.speak_to[pname].counter = 1
yl_speak_up.speak_to[pname].option_index = 1

View File

@ -45,6 +45,9 @@ yl_speak_up.get_fs_inventory = function(player)
"button_exit[2,1.5;1,0.9;exit;Exit]"
end
-- make sure the inventory of the NPC is loaded
yl_speak_up.load_npc_inventory(n_id, true, nil)
return table.concat({"size[12,11]",
"label[2,-0.2;Inventory of ",
minetest.formspec_escape(dialog.n_npc),

View File

@ -589,10 +589,6 @@ function yl_speak_up.talk(self, clicker)
self = yl_speak_up.initialize_npc(self)
end
-- TODO: load inventory only when the npc actually uses one?
-- create a detached inventory for the npc and load its inventory
yl_speak_up.load_npc_inventory(id_prefix.."_"..tostring(self.yl_speak_up.id))
local npc_id = self.yl_speak_up.id
local n_id = id_prefix.."_" .. npc_id
@ -646,6 +642,10 @@ function yl_speak_up.talk(self, clicker)
dialog.trades = {}
end
-- create a detached inventory for the npc and load its inventory
yl_speak_up.load_npc_inventory(id_prefix.."_"..tostring(self.yl_speak_up.id), false, dialog)
-- some NPC may have reset the animation; at least set it to the desired
-- value whenever we talk to the NPC
if self.yl_speak_up and self.yl_speak_up.animation then