From 3edc959d3a4404358d7fc3ef1e7693e3d789499a Mon Sep 17 00:00:00 2001 From: Hector Franqui Date: Wed, 19 Jul 2017 14:00:29 -0400 Subject: [PATCH] Dialogues: Finish implementation of registered dialogues. Ported all trade dialogues to use new dialogue system. --- dialogue.lua | 266 ++++++++++++++++----------------- npc.lua | 4 +- random_data.lua | 31 ---- random_data/dialogues_data.lua | 127 ++++++++++++++++ relationships.lua | 2 +- trade/trade.lua | 101 +++++++++++-- 6 files changed, 346 insertions(+), 185 deletions(-) diff --git a/dialogue.lua b/dialogue.lua index 0288eff..41e623c 100644 --- a/dialogue.lua +++ b/dialogue.lua @@ -29,6 +29,7 @@ npc.dialogue.tags = { FEMALE = "female", -- Relationship based tags - these are one-to-one with the -- phase names. + DEFAULT_MARRIED_DIALOGUE = "default_married_dialogue", PHASE_1 = "phase1", PHASE_2 = "phase2", PHASE_3 = "phase3", @@ -38,6 +39,11 @@ npc.dialogue.tags = { GIFT_ITEM_RESPONSE = "gift_item_response", GIFT_ITEM_LIKED = "gift_item_liked", GIFT_ITEM_UNLIKED = "gift_item_unliked", + -- Trade-related tags + DEFAULT_CASUAL_TRADE = "default_casual_trade_dialogue", + DEFAULT_DEDICATED_TRADE = "default_dedicated_trade_dialogue", + DEFAULT_BUY_OFFER = "buy_offer", + DEFAULT_SELL_OFFER = "sell_offer", -- Occupation-based tags - these are one-to-one with the -- default occupation names BASIC = "basic", -- Dialogues related to the basic occupation should @@ -50,6 +56,15 @@ npc.dialogue.tags = { -- This table will contain all the registered dialogues for NPCs npc.dialogue.registered_dialogues = {} +npc.dialogue.cache_keys = { + CASUAL_BUY_DIALOGUE = {key="CASUAL_BUY_DIALOGUE", tags={npc.dialogue.tags.DEFAULT_CASUAL_TRADE, npc.dialogue.tags.DEFAULT_BUY_OFFER}}, + CASUAL_SELL_DIALOGUE = {key="CASUAL_SELL_DIALOGUE", tags={npc.dialogue.tags.DEFAULT_CASUAL_TRADE, npc.dialogue.tags.DEFAULT_SELL_OFFER}}, + DEDICATED_TRADER_DIALOGUE = {key="DEDICATED_TRADER_DIALOGUE", tags={npc.dialogue.tags.DEFAULT_DEDICATED_TRADE}}, + MARRIED_DIALOGUE = {key="MARRIED_DIALOGUE", tags={npc.dialogue.tags.DEFAULT_MARRIED_DIALOGUE}}, +} + +npc.dialogue.cache = {} + -------------------------------------------------------------------------------------- -- Dialogue registration functions -- All dialogues will be registered by providing a definition. @@ -106,6 +121,31 @@ npc.dialogue.registered_dialogues = {} -- } -- } -------------------------------------------------------------------------------------- +-- This function sets a unique response ID (made of :) to +-- each response that features a function. This is to be able to locate the +-- function easily later +local function set_response_ids_recursively(dialogue, depth, dialogue_id) + -- Base case: dialogue object with no responses and no responses below it + if dialogue.responses == nil + and (dialogue.action_type == "dialogue" and dialogue.action.responses == nil) then + return + elseif dialogue.responses ~= nil then + -- Assign a response ID to each response + local response_id_prefix = tostring(depth)..":" + for key,value in ipairs(dialogue.responses) do + if value.action_type == "function" then + value.response_id = response_id_prefix..key + value.dialogue_id = dialogue_id + else + -- We have a dialogue action type. Need to check if dialogue has further responses + if value.action.responses ~= nil then + set_response_ids_recursively(value.action, depth + 1, dialogue_id) + end + end + end + end +end + -- The register dialogue function will just receive the definition as -- explained above. The unique key will be the index it gets into the -- array when inserted. @@ -114,9 +154,17 @@ function npc.dialogue.register_dialogue(def) if not def.tags then def.tags = {npc.dialogue.tags.UNISEX, npc.dialogue.tags.PHASE_1} end + + local dialogue_id = table.getn(npc.dialogue.registered_dialogues) + 1 + -- Set the response IDs - required for dialogue objects that + -- form trees of dialogues + set_response_ids_recursively(def, 0, dialogue_id) + + def.key = dialogue_id + -- Insert dialogue into table table.insert(npc.dialogue.registered_dialogues, def) - --minetest.log("Dialogues: "..dump(npc.dialogue.registered_dialogues)) + return dialogue_id end -- This function returns a table of dialogues that meet the given @@ -148,14 +196,33 @@ function npc.dialogue.search_dialogue_by_tags(tags, find_all) result[key] = def end end - -- if (find_all == true and tags_found == #tags) - -- or (not find_all and tags_found == #def.tags) then - - -- end end return result end +function npc.dialogue.get_cached_dialogue_key(_cache_key, tags) + local cache_key = _cache_key + if type(_cache_key) == "table" then + cache_key = _cache_key.key + tags = _cache_key.tags + end + + local key = npc.dialogue.cache[cache_key] + -- Check if key isn't cached + if not key then + -- Search for the dialogue + local dialogues = npc.dialogue.search_dialogue_by_tags(tags, true) + key = npc.utils.get_map_keys(dialogues)[1] + -- Populate cache + npc.dialogue.cache[cache_key] = key + -- Return key + return key + else + -- Return the cached key + return key + end +end + -------------------------------------------------------------------------------------- -- Dialogue box definitions -- The dialogue boxes are used for the player to interact with the @@ -164,6 +231,7 @@ end -- Creates and shows a multi-option dialogue based on the number of responses -- that the dialogue object contains function npc.dialogue.show_options_dialogue(self, + dialogue_key, dialogue, dismiss_option_label, player_name) @@ -186,12 +254,10 @@ function npc.dialogue.show_options_dialogue(self, -- Create entry on options_dialogue table npc.dialogue.dialogue_results.options_dialogue[player_name] = { npc = self, + dialogue = dialogue, + dialogue_key = dialogue_key, is_married_dialogue = (dialogue.dialogue_type == npc.dialogue.dialogue_type.married), - is_casual_trade_dialogue = - (dialogue.dialogue_type == npc.dialogue.dialogue_type.casual_trade), - is_dedicated_trade_dialogue = - (dialogue.dialogue_type == npc.dialogue.dialogue_type.dedicated_trade), is_custom_trade_dialogue = (dialogue.dialogue_type == npc.dialogue.dialogue_type.custom_trade), casual_trade_type = dialogue.casual_trade_type, @@ -230,32 +296,6 @@ end -------------------------------------------------------------------------------------- -- Dialogue methods -------------------------------------------------------------------------------------- --- This function sets a unique response ID (made of :) to --- each response that features a function. This is to be able to locate the --- function easily later -local function set_response_ids_recursively(dialogue, depth, dialogue_id) - -- Base case: dialogue object with no responses and no r,esponses below it - if dialogue.responses == nil - and (dialogue.action_type == "dialogue" and dialogue.action.responses == nil) then - return - elseif dialogue.responses ~= nil then - -- Assign a response ID to each response - local response_id_prefix = tostring(depth)..":" - for key,value in ipairs(dialogue.responses) do - if value.action_type == "function" then - value.response_id = response_id_prefix..key - value.dialogue_id = dialogue_id - else - -- We have a dialogue action type. Need to check if dialogue has further responses - if value.action.responses ~= nil then - set_response_ids_recursively(value.action, depth + 1, dialogue_id) - end - end - end - end -end - - -- Select random dialogue objects for an NPC based on sex -- and the relationship phase with player function npc.dialogue.select_random_dialogues_for_npc(self, phase) @@ -277,16 +317,15 @@ function npc.dialogue.select_random_dialogues_for_npc(self, phase) } local dialogues = npc.dialogue.search_dialogue_by_tags(search_tags) - minetest.log("dialogues found by tag search: "..dump(dialogues)) + local keys = npc.utils.get_map_keys(dialogues) -- Determine how many dialogue lines the NPC will have local number_of_dialogues = math.random(npc.dialogue.MIN_DIALOGUES, npc.dialogue.MAX_DIALOGUES) - for i = 1,number_of_dialogues do - local dialogue_id = math.random(1, #dialogues) - result.normal[i] = dialogue_id - - --set_response_ids_recursively(result.normal[i], 0, dialogue_id) + for i = 1, number_of_dialogues do + local key_id = math.random(1, #keys) + result.normal[i] = keys[key_id] + minetest.log("Adding dialogue: "..dump(dialogues[keys[key_id]])) end -- Add item hints. @@ -313,24 +352,7 @@ function npc.dialogue.select_random_dialogues_for_npc(self, phase) end end - - -- Favorite items - -- for i = 1, 2 do - -- result.hints[i] = {} - -- result.hints[i].text = - -- npc.relationships.get_hint_for_favorite_item( - -- self.gift_data.favorite_items["fav"..tostring(i)], self.sex, phase_tag) - -- end - - -- -- Disliked items - -- for i = 3, 4 do - -- result.hints[i] = {} - -- result.hints[i].text = - -- npc.relationships.get_hint_for_disliked_item( - -- self.gift_data.disliked_items["dis"..tostring(i-2)], self.sex, phase_tag) - -- end - - minetest.log("Dialogue results:"..dump(result)) + npc.log("DEBUG", "Dialogue results:"..dump(result)) return result end @@ -380,12 +402,13 @@ function npc.dialogue.start_dialogue(self, player, show_married_dialogue) -- Show options dialogue for dedicated trader if self.trader_data.trader_status == npc.trade.TRADER then - dialogue = npc.trade.DEDICATED_TRADER_PROMPT + dialogue = npc.dialogue.get_cached_dialogue_key(npc.dialogue.cache_keys.DEDICATED_TRADER_DIALOGUE) npc.dialogue.process_dialogue(self, dialogue, player:get_player_name()) return end local chance = math.random(1, 100) + --minetest.log("Chance: "..dump(chance)) if chance < 30 then -- Show trading options for casual traders -- If NPC has custom trading options, these will be @@ -406,10 +429,10 @@ function npc.dialogue.start_dialogue(self, player, show_married_dialogue) local trade_chance = math.random(1, max_trade_chance) if trade_chance == 1 then -- Show casual buy dialogue - dialogue = npc.trade.CASUAL_TRADE_BUY_DIALOGUE + dialogue = npc.dialogue.get_cached_dialogue_key(npc.dialogue.cache_keys.CASUAL_BUY_DIALOGUE) elseif trade_chance == 2 then -- Show casual sell dialogue - dialogue = npc.trade.CASUAL_TRADE_SELL_DIALOGUE + dialogue = npc.dialogue.get_cached_dialogue_key(npc.dialogue.cache_keys.CASUAL_SELL_DIALOGUE) elseif trade_chance == 3 then -- Show custom trade options dialogue = npc.dialogue.create_custom_trade_options(self, player) @@ -433,58 +456,61 @@ end -- This function processes a dialogue object and performs -- actions depending on what is defined in the object function npc.dialogue.process_dialogue(self, dialogue, player_name) + -- Freeze NPC actions + npc.lock_actions(self) - -- Freeze NPC actions - npc.lock_actions(self) + local dialogue_key = -1 - if type(dialogue) ~= "table" then - dialogue = npc.dialogue.registered_dialogues[dialogue] - minetest.log("Found dialogue: "..dump(dialogue)) - end + if type(dialogue) ~= "table" then + dialogue_key = dialogue + dialogue = npc.dialogue.registered_dialogues[dialogue] + --minetest.log("Found dialogue: "..dump(dialogue)) + end - -- Check if this dialogue has a flag definition - if dialogue.flag then - -- Check if the NPC has this flag - local flag_value = npc.get_flag(self, dialogue.flag.name) - if flag_value ~= nil then - -- Check if value of the flag is equal to the expected value - if flag_value ~= dialogue.flag.value then - -- Do not process this dialogue - return false - end - else + -- Check if this dialogue has a flag definition + if dialogue.flag then + -- Check if the NPC has this flag + local flag_value = npc.get_flag(self, dialogue.flag.name) + if flag_value ~= nil then + -- Check if value of the flag is equal to the expected value + if flag_value ~= dialogue.flag.value then + -- Do not process this dialogue + return false + end + else - if (type(dialogue.flag.value) == "boolean" and dialogue.flag.value ~= false) - or (type(dialogue.flag.value) == "number" and dialogue.flag.value > 0) then - -- Do not process this dialogue - return false - end - end - end + if (type(dialogue.flag.value) == "boolean" and dialogue.flag.value ~= false) + or (type(dialogue.flag.value) == "number" and dialogue.flag.value > 0) then + -- Do not process this dialogue + return false + end + end + end -- Send dialogue line if dialogue.text then npc.chat(self.npc_name, player_name, dialogue.text) end - -- Check if dialogue has responses. If it doesn't, unlock the actions - -- queue and reset actions timer.' - if not dialogue.responses then - npc.unlock_actions(self) - end + -- Check if dialogue has responses. If it doesn't, unlock the actions + -- queue and reset actions timer.' + if not dialogue.responses then + npc.unlock_actions(self) + end -- Check if there are responses, then show multi-option dialogue if there are if dialogue.responses then npc.dialogue.show_options_dialogue( self, + dialogue_key, dialogue, npc.dialogue.NEGATIVE_ANSWER_LABEL, player_name ) end - -- Dialogue object processed successfully - return true + -- Dialogue object processed successfully + return true end function npc.dialogue.create_option_dialogue(prompt, options, actions) @@ -630,51 +656,21 @@ minetest.register_on_player_receive_fields(function (player, formname, fields) npc.relationships.MARRIED_NPC_DIALOGUE .responses[player_response.options[i].response_id] .action(player_response.npc, player) - - elseif player_response.is_casual_trade_dialogue == true then - -- Check if trade is casual buy or sell - if player_response.casual_trade_type == npc.trade.OFFER_BUY then - -- Get functions from casual buy dialogue - npc.trade.CASUAL_TRADE_BUY_DIALOGUE - .responses[player_response.options[i].response_id] - .action(player_response.npc, player) - elseif player_response.casual_trade_type == npc.trade.OFFER_SELL == true then - -- Get functions from casual sell dialogue - npc.trade.CASUAL_TRADE_SELL_DIALOGUE - .responses[player_response.options[i].response_id] - .action(player_response.npc, player) - end - return - elseif player_response.is_dedicated_trade_dialogue == true then - -- Get the functions for a dedicated trader prompt - npc.trade.DEDICATED_TRADER_PROMPT - .responses[player_response.options[i].response_id] - .action(player_response.npc, player) - return elseif player_response.is_custom_trade_dialogue == true then - -- Functions for a custom trade should be available from the same dialogue - -- object as it is created in memory - minetest.log("Player response: "..dump(player_response.options[i])) - player_response.options[i].action(player_response.npc, player) - else - -- Get dialogues for sex and phase - local dialogues = npc.data.DIALOGUES[player_response.npc.sex][phase] - - minetest.log("Object: "..dump(dialogues[player_response.options[i].dialogue_id])) - local response = get_response_object_by_id_recursive(dialogues[player_response.options[i].dialogue_id], 0, player_response.options[i].response_id) - minetest.log("Found: "..dump(response)) + -- Functions for a custom trade should be available from the same dialogue + -- object as they are created on demand + minetest.log("Player response: "..dump(player_response.options[i])) + player_response.options[i].action(player_response.npc, player) + else + -- Get dialogue from registered dialogues + local dialogue = npc.dialogue.registered_dialogues[player_response.options[i].dialogue_id] + local response = get_response_object_by_id_recursive(dialogue, 0, player_response.options[i].response_id) - -- Execute function - response.action(player_response.npc, player) - - -- Execute function - -- dialogues[player_response.options[i].dialogue_id] - -- .responses[player_response.options[i].response_id] - -- .action(player_response.npc, player) - - -- Unlock queue, reset action timer and unfreeze NPC. - npc.unlock_actions(player_response.npc) + -- Execute function + response.action(player_response.npc, player) + -- Unlock queue, reset action timer and unfreeze NPC. + npc.unlock_actions(player_response.npc) end end return diff --git a/npc.lua b/npc.lua index 3cedeb2..7cc42a3 100755 --- a/npc.lua +++ b/npc.lua @@ -482,8 +482,8 @@ function npc.initialize(entity, pos, is_lua_entity, npc_stats) -- Add a custom trade offer local offer1 = npc.trade.create_custom_sell_trade_offer("Do you want me to fix your steel sword?", "Fix steel sword", "Fix steel sword", "default:sword_steel", {"default:sword_steel", "default:iron_lump 5"}) table.insert(ent.trader_data.custom_trades, offer1) - local offer2 = npc.trade.create_custom_sell_trade_offer("Do you want me to fix your mese sword?", "Fix mese sword", "Fix mese sword", "default:sword_mese", {"default:sword_mese", "default:copper_lump 10"}) - table.insert(ent.trader_data.custom_trades, offer2) + --local offer2 = npc.trade.create_custom_sell_trade_offer("Do you want me to fix your mese sword?", "Fix mese sword", "Fix mese sword", "default:sword_mese", {"default:sword_mese", "default:copper_lump 10"}) + --table.insert(ent.trader_data.custom_trades, offer2) ent.initialized = true --minetest.log(dump(ent)) diff --git a/random_data.lua b/random_data.lua index 96dd33b..5b2d403 100644 --- a/random_data.lua +++ b/random_data.lua @@ -8,37 +8,6 @@ npc.data.DIALOGUES = { male = {} } - -npc.dialogue.register_dialogue({ - text = "Hello there!", - tags = {"unisex", "phase1"} -}) - -npc.dialogue.register_dialogue({ - text = "How are you doing?", - tags = {"unisex", "phase1"} -}) - -npc.dialogue.register_dialogue({ - text = "Just living another day...", - tags = {"unisex", "phase1"} -}) - -npc.dialogue.register_dialogue({ - text = "Is there any woman in this area more beautiful than I am?", - tags = {"female", "phase1"} -}) - -npc.dialogue.register_dialogue({ - text = "Hunting is the best pasttime!", - tags = {"male", "phase1"} -}) - -npc.dialogue.register_dialogue({ - text = "I hope my wheat grows well this harvest.", - tags = {"male", "default_farmer"} -}) - -- Female dialogue options defined by phase -- Phase 1 npc.data.DIALOGUES.female["phase1"] = { diff --git a/random_data/dialogues_data.lua b/random_data/dialogues_data.lua index e69de29..bbc6fd8 100644 --- a/random_data/dialogues_data.lua +++ b/random_data/dialogues_data.lua @@ -0,0 +1,127 @@ + + + +-- Phase 1 dialogues, unisex + +npc.dialogue.register_dialogue({ + text = "Hello there!", + tags = {"unisex", "phase1"} +}) + +npc.dialogue.register_dialogue({ + text = "How are you doing?", + tags = {"unisex", "phase1"} +}) + +npc.dialogue.register_dialogue({ + text = "Just living another day...", + tags = {"unisex", "phase1"} +}) + +-- Phase 1 dialogues, female + +npc.dialogue.register_dialogue({ + text = "Is there any woman in this area more beautiful than I am?", + tags = {"female", "phase1"} +}) + +npc.dialogue.register_dialogue({ + text = "Hello! Have you been to the sea?", + tags = {"female", "phase1"}, + responses = { + [1] = { + text = "No, never before", + action_type = "function", + action = function(self, player) + minetest.chat_send_player(player:get_player_name(), "Oh, never? How come! You should.".. + "\nHere, take this. It will guide you to the sea...") + end + }, + [2] = { + text = "Yes, sure", + action_type = "dialogue", + action = { + text = "It's so beautiful, and big, and large, and infinite, and..." + } + }, + [3] = { + text = "Of course! And to all the seas in the world!", + action_type = "dialogue", + action = { + text = "Awww you are no fun then! Go on then know-it-all!" + } + } + } +}) + +npc.dialogue.register_dialogue({ + text = "Hello there, could you help me?", + tags = {"phase1", "female"}, + flag = {name="received_money_help", value=false}, + responses = { + [1] = { + text = "Yes, how can I help?", + action_type = "dialogue", + action = { + text = "Could you please give me 3 "..npc.trade.prices.currency.tier3.name.."?", + responses = { + [1] = { + text = "Yes, ok, here", + action_type = "function", + action = function(self, player) + -- Take item + if npc.actions.execute(self, npc.actions.cmd.TAKE_ITEM, { + player=player:get_player_name(), + pos=nil, + inv_list="main", + item_name=npc.trade.prices.currency.tier3.string, + count=3 + }) then + -- Send message + npc.chat(self.npc_name, player:get_player_name(), "Thank you, thank you so much!") + -- Set flag + npc.add_flag(self, "received_money_help", true) + -- Add chat line + --table.insert(self.dialogues.normal, npc.data.DIALOGUES.female["phase1"][8]) + else + npc.chat(self.npc_name, player:get_player_name(), "Looks like you don't have that amount of money...") + end + end + }, + [2] = { + text = "No, I'm sorry", + action_type = "dialogue", + action = { + text = "Oh..." + } + } + } + } + }, + [2] = { + text = "No, I'm sorry, can't now", + action_type = "function", + action = function(self, player) + npc.chat(self.npc_name, player:get_player_name(), "Oh, ok...") + end + } + } +}) + +npc.dialogue.register_dialogue({ + text = "Thank you so much for your help, thank you!", + flag = {name="received_money_help", value=true}, + tags = {"phase1", "female"} +}) + +-- Phase 1 dialogues, male + +npc.dialogue.register_dialogue({ + text = "Hunting is the best pasttime!", + tags = {"male", "phase1"} +}) + +npc.dialogue.register_dialogue({ + text = "I hope my wheat grows well this harvest.", + tags = {"male", "default_farmer"} +}) \ No newline at end of file diff --git a/relationships.lua b/relationships.lua index 3c8cf5d..08a24e3 100644 --- a/relationships.lua +++ b/relationships.lua @@ -96,7 +96,7 @@ npc.relationships.MARRIED_NPC_DIALOGUE = { end }, [3] = { - text = "Come with me, please!", + text = "Please, come with me!", action_type = "function", response_id = 3, action = function(self, player) diff --git a/trade/trade.lua b/trade/trade.lua index c4d7f75..777a38e 100644 --- a/trade/trade.lua +++ b/trade/trade.lua @@ -26,10 +26,11 @@ npc.trade.CUSTOM_TRADES_PROMPT_TEXT = "Hi there, how can I help you today?" -- Casual trader NPC dialogues definition -- Casual buyer -npc.trade.CASUAL_TRADE_BUY_DIALOGUE = { +npc.dialogue.register_dialogue({ text = "I'm looking to buy some items, are you interested?", - casual_trade_type = npc.trade.OFFER_BUY, - dialogue_type = npc.dialogue.dialogue_type.casual_trade, + --casual_trade_type = npc.trade.OFFER_BUY, + tags = {"default_casual_trade_dialogue", "buy_offer"}, + --dialogue_type = npc.dialogue.dialogue_type.casual_trade, responses = { [1] = { text = "Sell", @@ -40,13 +41,30 @@ npc.trade.CASUAL_TRADE_BUY_DIALOGUE = { end } } -} +}) + +-- npc.trade.CASUAL_TRADE_BUY_DIALOGUE = { +-- text = "I'm looking to buy some items, are you interested?", +-- casual_trade_type = npc.trade.OFFER_BUY, +-- dialogue_type = npc.dialogue.dialogue_type.casual_trade, +-- responses = { +-- [1] = { +-- text = "Sell", +-- action_type = "function", +-- response_id = 1, +-- action = function(self, player) +-- npc.trade.show_trade_offer_formspec(self, player, npc.trade.OFFER_BUY) +-- end +-- } +-- } +-- } -- Casual seller -npc.trade.CASUAL_TRADE_SELL_DIALOGUE = { +npc.dialogue.register_dialogue({ text = "I have some items to sell, are you interested?", - dialogue_type = npc.dialogue.dialogue_type.casual_trade, - casual_trade_type = npc.trade.OFFER_SELL, + --dialogue_type = npc.dialogue.dialogue_type.casual_trade, + tags = {"default_casual_trade_dialogue", "sell_offer"}, + --casual_trade_type = npc.trade.OFFER_SELL, responses = { [1] = { text = "Buy", @@ -57,11 +75,28 @@ npc.trade.CASUAL_TRADE_SELL_DIALOGUE = { end } } -} +}) + +-- npc.trade.CASUAL_TRADE_SELL_DIALOGUE = { +-- text = "I have some items to sell, are you interested?", +-- dialogue_type = npc.dialogue.dialogue_type.casual_trade, +-- casual_trade_type = npc.trade.OFFER_SELL, +-- responses = { +-- [1] = { +-- text = "Buy", +-- action_type = "function", +-- response_id = 1, +-- action = function(self, player) +-- npc.trade.show_trade_offer_formspec(self, player, npc.trade.OFFER_SELL) +-- end +-- } +-- } +-- } -- Dedicated trade dialogue prompt -npc.trade.DEDICATED_TRADER_PROMPT = { +npc.dialogue.register_dialogue({ text = "Hello there, would you like to trade?", + tags = {npc.dialogue.tags.DEFAULT_DEDICATED_TRADE}, dialogue_type = npc.dialogue.dialogue_type.dedicated_trade, responses = { [1] = { @@ -90,7 +125,38 @@ npc.trade.DEDICATED_TRADER_PROMPT = { end } } -} +}) +-- npc.trade.DEDICATED_TRADER_PROMPT = { +-- text = "Hello there, would you like to trade?", +-- dialogue_type = npc.dialogue.dialogue_type.dedicated_trade, +-- responses = { +-- [1] = { +-- text = "Buy", +-- action_type = "function", +-- response_id = 1, +-- action = function(self, player) +-- npc.trade.show_dedicated_trade_formspec(self, player, npc.trade.OFFER_SELL) +-- end +-- }, +-- [2] = { +-- text = "Sell", +-- action_type = "function", +-- response_id = 2, +-- action = function(self, player) +-- npc.trade.show_dedicated_trade_formspec(self, player, npc.trade.OFFER_BUY) +-- end +-- }, +-- [3] = { +-- text = "Other", +-- action_type = "function", +-- response_id = 3, +-- action = function(self, player) +-- local dialogue = npc.dialogue.create_custom_trade_options(self, player) +-- npc.dialogue.process_dialogue(self, dialogue, player:get_player_name()) +-- end +-- } +-- } +-- } function npc.trade.show_trade_offer_formspec(self, player, offer_type) @@ -348,12 +414,15 @@ function npc.trade.get_casual_trade_offer(self, offer_type) end end end - -- Choose a random item from the sellable items - local item = sellable_items[math.random(#sellable_items)] - -- Choose how many of this item will be sold to player - local count = math.random(npc.get_item_count(item)) - -- Create trade offer - result = npc.trade.create_offer(npc.trade.OFFER_SELL, npc.get_item_name(item), nil, nil, count) + -- Check if there are no sellable items to avoid crash + if #sellable_items > 0 then + -- Choose a random item from the sellable items + local item = sellable_items[math.random(#sellable_items)] + -- Choose how many of this item will be sold to player + local count = math.random(npc.get_item_count(item)) + -- Create trade offer + result = npc.trade.create_offer(npc.trade.OFFER_SELL, npc.get_item_name(item), nil, nil, count) + end end return result