From 2b58aac1dc5bf3df7c6df4f902f677b059e5ad5f Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sat, 1 Oct 2022 22:43:35 +0200 Subject: [PATCH] trade_inv now calls extra functions so that the code can be changed at runtime with npc_talk_reload, too --- trade_simple.lua | 211 +++++++++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 91 deletions(-) diff --git a/trade_simple.lua b/trade_simple.lua index a5086b0..2f91063 100644 --- a/trade_simple.lua +++ b/trade_simple.lua @@ -862,6 +862,118 @@ yl_speak_up.get_fs_trade_simple = function(player, trade_id) end +-- functions for handling the detached trade inventory of players +-- these functions exist as extra functions so that they can be changed with /npc_talk_reload + +-- moving of items between diffrent lists is not allowed +yl_speak_up.trade_inv_allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + if(not(player)) then + return 0 + end + if(from_list ~= to_list) then + return 0 + end + return count +end + +-- these all require calling special functions, depending on context +yl_speak_up.trade_inv_allow_put = function(inv, listname, index, stack, player) + if(not(player)) then + return 0 + end + -- the "buy" slot is managed by the NPC; the player only takes from it + if(listname == "buy") then + return 0 + end + -- do not allow used items or items with metadata in the setup slots + -- (they can't really be traded later on anyway) + if(listname == "setup") then + -- check if player can edit NPC, item is undammaged and contains no metadata + return yl_speak_up.inventory_allow_item(player, stack, + "yl_speak_up:add_trade_simple") + end + -- allow putting something in in edit mode - but not otherwise + if(listname == "npc_gives") then + local pname = player:get_player_name() + local n_id = yl_speak_up.speak_to[pname].n_id + -- only in edit mode! else the NPC manages this slot + if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then + return 0 + end + end + return stack:get_count() +end + +yl_speak_up.trade_inv_allow_take = function(inv, listname, index, stack, player) + if(not(player)) then + return 0 + end + -- can the trade be made? + if(listname == "buy") then + return yl_speak_up.can_trade_simple(player, stack:get_count()) + end + return stack:get_count() +end + +yl_speak_up.trade_inv_on_move = function(inv, from_list, from_index, to_list, to_index, count, player) +end + +yl_speak_up.trade_inv_on_put = function(inv, listname, index, stack, player) + if(listname == "pay") then + local pname = player:get_player_name() + -- show formspec with updated information (perhaps sale is now possible) + yl_speak_up.show_fs(player, "trade_simple") + elseif(listname == "npc_gives" + or listname == "npc_wants") then + -- monitor changes in order to adjust the formspec + yl_speak_up.action_inv_changed(inv, listname, index, stack, player, "put") + end +end + +yl_speak_up.trade_inv_on_take = function(inv, listname, index, stack, player) + -- the player may have put something wrong in the payment slot + -- -> show updated formspec + if(listname == "pay") then + local pname = player:get_player_name() + -- show formspec with updated information (perhaps sale is now possible) + yl_speak_up.show_fs(player, "trade_simple") + elseif(listname == "buy") then + -- do the exchange + yl_speak_up.do_trade_simple(player, stack:get_count()) + local pname = player:get_player_name() + -- which trade are we talking about? + local trade = yl_speak_up.trade[pname] + -- when the player traded once inside an action: that action was a success; + -- execute next action + -- but only if not in edit mode + if(trade and trade.trade_done > 0 + and not(trade.trade_is_trade_list) + and yl_speak_up.edit_mode[pname] ~= trade.n_id) then + local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) + -- return surplus items from the pay slot + local pay = trade_inv:get_stack("pay", 1) + local player_inv = player:get_inventory() + if( pay and player_inv:room_for_item("main", pay)) then + player_inv:add_item("main", pay) + trade_inv:set_stack("pay", 1, "") + end + -- done trading + yl_speak_up.speak_to[pname].target_d_id = nil + yl_speak_up.speak_to[pname].trade_id = nil + -- execute the next action + yl_speak_up.execute_next_action(player, trade.a_id, true) + return + end + -- information may require an update (NPC might now be out of stock), or + -- the player can do the trade a second time + yl_speak_up.show_fs(player, "trade_simple") + elseif(listname == "npc_gives" + or listname == "npc_wants") then + -- monitor changes in order to adjust the formspec + yl_speak_up.action_inv_changed(inv, listname, index, stack, player, "take") + end +end + -- create a detached inventory for the *player* for trading with the npcs -- (called in minetest.register_on_joinplayer) yl_speak_up.player_joined_add_trade_inv = function(player, last_login) @@ -871,109 +983,26 @@ yl_speak_up.player_joined_add_trade_inv = function(player, last_login) -- the functions for monitoring changes will be important later on -- only the the player owning this detached inventory may access it local trade_inv = minetest.create_detached_inventory("yl_speak_up_player_"..tostring(pname), { - -- moving of items between diffrent lists is not allowed allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - if(not(player) or player:get_player_name() ~= pname) then - return 0 - end - if(from_list ~= to_list) then - return 0 - end - return count + return yl_speak_up.trade_inv_allow_move(inv, from_list, from_index, to_list, + to_index, count, player) end, - -- these all require calling special functions, depending on context allow_put = function(inv, listname, index, stack, player) - if(not(player) or player:get_player_name() ~= pname) then - return 0 - end - -- the "buy" slot is managed by the NPC; the player only takes from it - if(listname == "buy") then - return 0 - end - -- do not allow used items or items with metadata in the setup slots - -- (they can't really be traded later on anyway) - if(listname == "setup") then - -- check if player can edit NPC, item is undammaged and contains no metadata - return yl_speak_up.inventory_allow_item(player, stack, - "yl_speak_up:add_trade_simple") - end - -- allow putting something in in edit mode - but not otherwise - if(listname == "npc_gives") then - local pname = player:get_player_name() - local n_id = yl_speak_up.speak_to[pname].n_id - -- only in edit mode! else the NPC manages this slot - if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then - return 0 - end - end - return stack:get_count() + return yl_speak_up.trade_inv_allow_put(inv, listname, index, stack, player) end, allow_take = function(inv, listname, index, stack, player) - if(not(player) or player:get_player_name() ~= pname) then - return 0 - end - -- can the trade be made? - if(listname == "buy") then - return yl_speak_up.can_trade_simple(player, stack:get_count()) - end - return stack:get_count() + return yl_speak_up.trade_inv_allow_take(inv, listname, index, stack, player) end, on_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return yl_speak_up.trade_inv_on_move(inv, from_list, from_index, to_list, + to_index, count, player) end, on_put = function(inv, listname, index, stack, player) - if(listname == "pay") then - local pname = player:get_player_name() - -- show formspec with updated information (perhaps sale is now possible) - yl_speak_up.show_fs(player, "trade_simple") - elseif(listname == "npc_gives" - or listname == "npc_wants") then - -- monitor changes in order to adjust the formspec - yl_speak_up.action_inv_changed(inv, listname, index, stack, player, "put") - end + return yl_speak_up.trade_inv_on_put(inv, listname, index, stack, player) end, on_take = function(inv, listname, index, stack, player) - -- the player may have put something wrong in the payment slot - -- -> show updated formspec - if(listname == "pay") then - local pname = player:get_player_name() - -- show formspec with updated information (perhaps sale is now possible) - yl_speak_up.show_fs(player, "trade_simple") - elseif(listname == "buy") then - -- do the exchange - yl_speak_up.do_trade_simple(player, stack:get_count()) - local pname = player:get_player_name() - -- which trade are we talking about? - local trade = yl_speak_up.trade[pname] - -- when the player traded once inside an action: that action was a success; - -- execute next action - -- but only if not in edit mode - if(trade and trade.trade_done > 0 - and not(trade.trade_is_trade_list) - and yl_speak_up.edit_mode[pname] ~= trade.n_id) then - local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) - -- return surplus items from the pay slot - local pay = trade_inv:get_stack("pay", 1) - local player_inv = player:get_inventory() - if( pay and player_inv:room_for_item("main", pay)) then - player_inv:add_item("main", pay) - trade_inv:set_stack("pay", 1, "") - end - -- done trading - yl_speak_up.speak_to[pname].target_d_id = nil - yl_speak_up.speak_to[pname].trade_id = nil - -- execute the next action - yl_speak_up.execute_next_action(player, trade.a_id, true) - return - end - -- information may require an update (NPC might now be out of stock), or - -- the player can do the trade a second time - yl_speak_up.show_fs(player, "trade_simple") - elseif(listname == "npc_gives" - or listname == "npc_wants") then - -- monitor changes in order to adjust the formspec - yl_speak_up.action_inv_changed(inv, listname, index, stack, player, "take") - end + return yl_speak_up.trade_inv_on_take(inv, listname, index, stack, player) end, }) -- prepare the actual inventories