actually handle partial taking of items

This commit is contained in:
Sokomine 2022-01-18 21:56:01 +01:00
parent 75cc01904e
commit d0e7b23127

View File

@ -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