diff --git a/exec_apply_effects.lua b/exec_apply_effects.lua index b3d0cb1..0fa2d02 100644 --- a/exec_apply_effects.lua +++ b/exec_apply_effects.lua @@ -68,6 +68,7 @@ yl_speak_up.execute_all_relevant_effects = function(player, effects, o_id, actio local alternate_text = nil local last_result = action_was_successful local res = true + local refuse_items = true for i, k in ipairs(sorted_key_list) do local r = effects[ k ] yl_speak_up.debug_msg(player, n_id, o_id, "..executing ".. @@ -82,6 +83,12 @@ yl_speak_up.execute_all_relevant_effects = function(player, effects, o_id, actio " -> Effect failed to execute.") alternate_text = r.alternate_text end + if(r and r.r_type and r.r_type == "deal_with_offered_item") then + refuse_items = true + if(not(r.r_value) or r.r_value == "do_nothing") then + refuse_items = false + end + end else -- in edit mode: assume that the effect was successful res = true @@ -102,6 +109,14 @@ yl_speak_up.execute_all_relevant_effects = function(player, effects, o_id, actio end -- all preconditions are true yl_speak_up.debug_msg(player, n_id, o_id, "Finished executing effects.") + -- make sure to give unwanted items back if needed + if(refuse_items) then + -- check if there is actually something that needs to be given back + local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) + if(not(trade_inv:is_empty("npc_wants"))) then + target_dialog = "d_got_item" + end + end return {next_dialog = target_dialog, alternate_text = alternate_text} end @@ -242,6 +257,50 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r) return true end return false + elseif(r.r_type == "deal_with_offered_item") then + -- possible r_value: "do_nothing", "take_as_wanted", "take_all", "refuse_all"} + if(not(r.r_value) or r.r_value == "do_nothing") then + return true -- we're good at doing nothing + end + local pname = player:get_player_name() + local inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) + local stack_got = inv:get_stack("npc_wants",1) + if(stack_got:is_empty()) then + yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." ".. + r.r_type..": The offered stack is empty.") + return false -- the player gave nothing + end + -- get the inventory of the npc + local npc_inv = minetest.get_inventory({type="detached", + name="yl_speak_up_npc_"..tostring(n_id)}) + -- shall we take all or just as much as the NPC wants? + local stack_wanted = ItemStack(p.p_value) + local amount = 0 + if(r.r_value == "take_all") then + amount = stack_got:get_count() + elseif(r.r_value == "takeas_wanted") then + amount = stack_wanted:get_count() + -- the NPC didn't get enough + if(amount > stack_got:get_count()) then + yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." ".. + r.r_type..": The offered stack \""..tostring(stack_got).. + "is smaller than what the NPC wanted: \"".. + tostring(stack_wanted).."\".") + return false + end + end + local take_stack = stack_got:get_name().." "..tostring(amount) + if(not(npc_inv:room_for_item("npc_main", take_stack))) then + yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." ".. + r.r_type..": The NPC has not enough room for \""..tostring(take_stack).."\".") + return false + end + -- actually transfer the item from the player to the NPC's inventory + npc_inv:add_item("npc_main", take_stack) + inv:remove_item("npc_wants", take_stack) + -- returning of any leftover items needs to happen after *all* effects + -- are executed; we don't need to take any special preparations here + elseif(r.r_type == "dialog" or r.r_type == "on_failure") then -- this needs to be handled in the calling function