diff --git a/dialogue.lua b/dialogue.lua index 065117c..f4e4d33 100644 --- a/dialogue.lua +++ b/dialogue.lua @@ -11,10 +11,10 @@ npc.dialogue.MIN_DIALOGUES = 2 npc.dialogue.MAX_DIALOGUES = 4 npc.dialogue.dialogue_type = { - married = 1, - casual_trade = 2, - dedicated_trade = 3, - custom_trade = 4 + married = 1, + casual_trade = 2, + dedicated_trade = 3, + custom_trade = 4 } -- This table contains the answers of dialogue boxes @@ -47,8 +47,8 @@ npc.dialogue.tags = { -- Occupation-based tags - these are one-to-one with the -- default occupation names BASIC = "basic", -- Dialogues related to the basic occupation should - -- use this. As basic occupation is generic, any occupation - -- should be able to use these dialogues. + -- use this. As basic occupation is generic, any occupation + -- should be able to use these dialogues. DEFAULT_FARMER = "default_farmer", DEFAULT_COOKER = "default_cooker" } @@ -125,25 +125,25 @@ npc.dialogue.cache = {} -- 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 + -- 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 @@ -161,7 +161,7 @@ function npc.dialogue.register_dialogue(def) set_response_ids_recursively(def, 0, dialogue_id) def.key = dialogue_id - + -- Insert dialogue into table table.insert(npc.dialogue.registered_dialogues, def) return dialogue_id @@ -212,9 +212,9 @@ function npc.dialogue.get_cached_dialogue_key(_cache_key, tags) 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 + key = npc.utils.get_map_keys(dialogues)[1] + -- Populate cache + npc.dialogue.cache[cache_key] = key -- Return key return key else @@ -230,13 +230,13 @@ 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) - local responses = dialogue.responses - local options_length = table.getn(responses) + 1 +function npc.dialogue.show_options_dialogue(self, +dialogue_key, +dialogue, +dismiss_option_label, +player_name) + local responses = dialogue.responses + local options_length = table.getn(responses) + 1 local formspec_height = (options_length * 0.7) + 0.4 local formspec = "size[7,"..tostring(formspec_height).."]" @@ -246,20 +246,20 @@ function npc.dialogue.show_options_dialogue(self, y = (0.75 * i) end formspec = formspec.."button_exit[0.5," - ..(y - 0.5)..";6,0.5;opt"..tostring(i)..";"..responses[i].text.."]" + ..(y - 0.5)..";6,0.5;opt"..tostring(i)..";"..responses[i].text.."]" end formspec = formspec.."button_exit[0.5," - ..(formspec_height - 0.7)..";6,0.5;exit;"..dismiss_option_label.."]" + ..(formspec_height - 0.7)..";6,0.5;exit;"..dismiss_option_label.."]" -- 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_custom_trade_dialogue = - (dialogue.dialogue_type == npc.dialogue.dialogue_type.custom_trade), + is_married_dialogue = + (dialogue.dialogue_type == npc.dialogue.dialogue_type.married), + is_custom_trade_dialogue = + (dialogue.dialogue_type == npc.dialogue.dialogue_type.custom_trade), casual_trade_type = dialogue.casual_trade_type, options = responses } @@ -269,23 +269,23 @@ end -- This function is used for showing a yes/no dialogue formspec function npc.dialogue.show_yes_no_dialogue(self, - prompt, - positive_answer_label, - positive_callback, - negative_answer_label, - negative_callback, - player_name) +prompt, +positive_answer_label, +positive_callback, +negative_answer_label, +negative_callback, +player_name) - npc.lock_actions(self) + npc.lock_actions(self) local formspec = "size[7,3]".. - "label[0.5,0.1;"..prompt.."]".. - "button_exit[0.5,1.15;6,0.5;yes_option;"..positive_answer_label.."]".. - "button_exit[0.5,1.95;6,0.5;no_option;"..negative_answer_label.."]" + "label[0.5,0.1;"..prompt.."]".. + "button_exit[0.5,1.15;6,0.5;yes_option;"..positive_answer_label.."]".. + "button_exit[0.5,1.95;6,0.5;no_option;"..negative_answer_label.."]" -- Create entry into responses table npc.dialogue.dialogue_results.yes_no_dialogue[player_name] = { - npc = self, + npc = self, yes_callback = positive_callback, no_callback = negative_callback } @@ -334,7 +334,7 @@ function npc.dialogue.select_random_dialogues_for_npc(self, phase) self.gift_data.favorite_items["fav"..tostring(i)], npc.dialogue.tags.GIFT_ITEM_HINT, npc.dialogue.tags.GIFT_ITEM_LIKED, - self.sex, + self.sex, phase_tag) for key, value in pairs(hints) do result.hints[i] = key @@ -359,31 +359,31 @@ end -- This function creates a multi-option dialogue from the custom trades that the -- NPC have. function npc.dialogue.create_custom_trade_options(self, player) - -- Create the action for each option - local actions = {} - for i = 1, #self.trader_data.custom_trades do - table.insert(actions, - function() - npc.trade.show_custom_trade_offer(self, player, self.trader_data.custom_trades[i]) - end) - end - -- Default text to be shown for dialogue prompt - local text = npc.trade.CUSTOM_TRADES_PROMPT_TEXT - -- Get the options from each custom trade entry - local options = {} - if #self.trader_data.custom_trades == 1 then - table.insert(options, self.trader_data.custom_trades[1].button_prompt) - text = self.trader_data.custom_trades[1].option_prompt - else - for i = 1, #self.trader_data.custom_trades do - table.insert(options, self.trader_data.custom_trades[i].button_prompt) - end - end - -- Create dialogue object - local dialogue = npc.dialogue.create_option_dialogue(text, options, actions) - dialogue.dialogue_type = npc.dialogue.dialogue_type.custom_trade + -- Create the action for each option + local actions = {} + for i = 1, #self.trader_data.custom_trades do + table.insert(actions, + function() + npc.trade.show_custom_trade_offer(self, player, self.trader_data.custom_trades[i]) + end) + end + -- Default text to be shown for dialogue prompt + local text = npc.trade.CUSTOM_TRADES_PROMPT_TEXT + -- Get the options from each custom trade entry + local options = {} + if #self.trader_data.custom_trades == 1 then + table.insert(options, self.trader_data.custom_trades[1].button_prompt) + text = self.trader_data.custom_trades[1].option_prompt + else + for i = 1, #self.trader_data.custom_trades do + table.insert(options, self.trader_data.custom_trades[i].button_prompt) + end + end + -- Create dialogue object + local dialogue = npc.dialogue.create_option_dialogue(text, options, actions) + dialogue.dialogue_type = npc.dialogue.dialogue_type.custom_trade - return dialogue + return dialogue end -- This function will choose randomly a dialogue from the NPC data @@ -394,17 +394,17 @@ function npc.dialogue.start_dialogue(self, player, show_married_dialogue) -- Construct dialogue for marriage if npc.relationships.get_relationship_phase(self, player:get_player_name()) == "phase6" - and show_married_dialogue == true then - dialogue = npc.relationships.MARRIED_NPC_DIALOGUE - npc.dialogue.process_dialogue(self, dialogue, player:get_player_name()) + and show_married_dialogue == true then + dialogue = npc.relationships.MARRIED_NPC_DIALOGUE + npc.dialogue.process_dialogue(self, dialogue, player:get_player_name()) return - end + end -- Show options dialogue for dedicated trader if self.trader_data.trader_status == npc.trade.TRADER then - 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 + 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) @@ -414,92 +414,99 @@ function npc.dialogue.start_dialogue(self, player, show_married_dialogue) -- If NPC has custom trading options, these will be -- shown as well with equal chance as the casual -- buy/sell options - if self.trader_data.trader_status == npc.trade.NONE then - -- Show custom trade options if available - if table.getn(self.trader_data.custom_trades) > 0 then - -- Show custom trade options - dialogue = npc.dialogue.create_custom_trade_options(self, player) - else - -- If not available, choose normal dialogue - dialogue = self.dialogues.normal[math.random(1, #self.dialogues.normal)] - end - elseif self.trader_data.trader_status == npc.trade.CASUAL then - local max_trade_chance = 2 - if table.getn(self.trader_data.custom_trades) > 0 then - max_trade_chance = 3 - end - -- Show buy/sell with 50% chance each - local trade_chance = math.random(1, max_trade_chance) - if trade_chance == 1 then - -- Show casual 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.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) - end - end + if self.trader_data.trader_status == npc.trade.NONE then + -- Show custom trade options if available + if table.getn(self.trader_data.custom_trades) > 0 then + -- Show custom trade options + dialogue = npc.dialogue.create_custom_trade_options(self, player) + else + -- If not available, choose normal dialogue + dialogue = self.dialogues.normal[math.random(1, #self.dialogues.normal)] + end + elseif self.trader_data.trader_status == npc.trade.CASUAL then + local max_trade_chance = 2 + if table.getn(self.trader_data.custom_trades) > 0 then + max_trade_chance = 3 + end + -- Show buy/sell with 50% chance each + local trade_chance = math.random(1, max_trade_chance) + if trade_chance == 1 then + -- Show casual 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.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) + end + end elseif chance >= 30 and chance < 90 then - -- Choose a random dialogue from the common ones + -- Choose a random dialogue from the common ones dialogue = self.dialogues.normal[math.random(1, #self.dialogues.normal)] elseif chance >= 90 then - -- Choose a random dialogue line from the favorite/disliked item hints - dialogue = self.dialogues.hints[math.random(1, 4)] + -- Check if gift items hints are enabled + minetest.log("Self gift data enable: "..dump(self.gift_data.enable_gift_items_hints)) + if self.gift_data.enable_gift_items_hints then + -- Choose a random dialogue line from the favorite/disliked item hints + dialogue = self.dialogues.hints[math.random(1, 4)] + else + -- Choose a random dialogue from the common ones + dialogue = self.dialogues.normal[math.random(1, #self.dialogues.normal)] + end end local dialogue_result = npc.dialogue.process_dialogue(self, dialogue, player:get_player_name()) - if dialogue_result == false then - -- Try to find another dialogue line - npc.dialogue.start_dialogue(self, player, show_married_dialogue) - end + if dialogue_result == false then + -- Try to find another dialogue line + npc.dialogue.start_dialogue(self, player, show_married_dialogue) + end end -- This function processes a dialogue object and performs --- actions depending on what is defined in the object +-- 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 + local dialogue_key = -1 - if type(dialogue) ~= "table" then - dialogue_key = dialogue - 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 - - 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 + -- 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 -- 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 @@ -512,22 +519,22 @@ function npc.dialogue.process_dialogue(self, dialogue, 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) - local result = {} - result.text = prompt - result.responses = {} - for i = 1, #options do - table.insert(result.responses, {text = options[i], action_type="function", action=actions[i]}) - end - return result + local result = {} + result.text = prompt + result.responses = {} + for i = 1, #options do + table.insert(result.responses, {text = options[i], action_type="function", action=actions[i]}) + end + return result end ----------------------------------------------------------------------------- --- Functions for rotating NPC to look at player +-- Functions for rotating NPC to look at player -- (taken from the mobs_redo API) ----------------------------------------------------------------------------- local atan = function(x) @@ -543,7 +550,7 @@ function npc.dialogue.rotate_npc_to_player(self) local objs = minetest.get_objects_inside_radius(s, 4) local lp = nil local yaw = 0 - + for n = 1, #objs do if objs[n]:is_player() then lp = objs[n]:getpos() @@ -571,38 +578,38 @@ end --------------------------------------------------------------------------------------- -- This function locates a response object that has function on the dialogue tree. local function get_response_object_by_id_recursive(dialogue, current_depth, response_id) - if dialogue.responses == nil - and (dialogue.action_type == "dialogue" and dialoge.action.responses == nil) then - return nil - elseif dialogue.responses ~= nil then - -- Get current depth and response ID - local d_i1, d_i2 = string.find(response_id, ":") - minetest.log("N1: "..dump(string.sub(response_id, 0, d_i1))..", N2: "..dump(string.sub(response_id, 1, d_i1-1))) - local depth = tonumber(string.sub(response_id, 0, d_i1-1)) - local id = tonumber(string.sub(response_id, d_i2 + 1)) - minetest.log("Depth: "..dump(depth)..", id: "..dump(id)) - -- Check each response - for key,value in ipairs(dialogue.responses) do - minetest.log("Key: "..dump(key)..", value: "..dump(value)..", comp1: "..dump(current_depth == depth)) - if value.action_type == "function" then - -- Check if we are on correct response and correct depth - if current_depth == depth then - if key == id then - return value - end - end - else - minetest.log("Entering again...") - -- We have a dialogue action type. Need to check if dialogue has further responses - if value.action.responses ~= nil then - local response = get_response_object_by_id_recursive(value.action, current_depth + 1, response_id) - if response ~= nil then - return response - end - end - end - end - end + if dialogue.responses == nil + and (dialogue.action_type == "dialogue" and dialoge.action.responses == nil) then + return nil + elseif dialogue.responses ~= nil then + -- Get current depth and response ID + local d_i1, d_i2 = string.find(response_id, ":") + --minetest.log("N1: "..dump(string.sub(response_id, 0, d_i1))..", N2: "..dump(string.sub(response_id, 1, d_i1-1))) + local depth = tonumber(string.sub(response_id, 0, d_i1-1)) + local id = tonumber(string.sub(response_id, d_i2 + 1)) + --minetest.log("Depth: "..dump(depth)..", id: "..dump(id)) + -- Check each response + for key,value in ipairs(dialogue.responses) do + --minetest.log("Key: "..dump(key)..", value: "..dump(value)..", comp1: "..dump(current_depth == depth)) + if value.action_type == "function" then + -- Check if we are on correct response and correct depth + if current_depth == depth then + if key == id then + return value + end + end + else + --minetest.log("Entering again...") + -- We have a dialogue action type. Need to check if dialogue has further responses + if value.action.responses ~= nil then + local response = get_response_object_by_id_recursive(value.action, current_depth + 1, response_id) + if response ~= nil then + return response + end + end + end + end + end end -- Handler for dialogue formspec @@ -615,8 +622,8 @@ minetest.register_on_player_receive_fields(function (player, formname, fields) if fields then local player_response = npc.dialogue.dialogue_results.yes_no_dialogue[player_name] - -- Unlock queue, reset action timer and unfreeze NPC. - npc.unlock_actions(player_response.npc) + -- Unlock queue, reset action timer and unfreeze NPC. + npc.unlock_actions(player_response.npc) if fields.yes_option then player_response.yes_callback() @@ -634,46 +641,46 @@ minetest.register_on_player_receive_fields(function (player, formname, fields) -- Get player response local player_response = npc.dialogue.dialogue_results.options_dialogue[player_name] - -- Check if the player hit the negative option or esc button - if fields["exit"] or fields["quit"] == "true" then - -- Unlock queue, reset action timer and unfreeze NPC. - npc.unlock_actions(player_response.npc) - end + -- Check if the player hit the negative option or esc button + if fields["exit"] or fields["quit"] == "true" then + -- Unlock queue, reset action timer and unfreeze NPC. + npc.unlock_actions(player_response.npc) + end for i = 1, #player_response.options do local button_label = "opt"..tostring(i) if fields[button_label] then if player_response.options[i].action_type == "dialogue" then -- Process dialogue object - npc.dialogue.process_dialogue(player_response.npc, - player_response.options[i].action, - player_name) + npc.dialogue.process_dialogue(player_response.npc, + player_response.options[i].action, + player_name) elseif player_response.options[i].action_type == "function" then -- Execute function - get it directly from definition -- Find NPC relationship phase with player - local phase = - npc.relationships.get_relationship_phase(player_response.npc, player_name) + local phase = + npc.relationships.get_relationship_phase(player_response.npc, player_name) -- Check if NPC is married and the married NPC dialogue should be shown if phase == "phase6" and player_response.is_married_dialogue == true then -- Get the function definitions from the married dialogue npc.relationships.MARRIED_NPC_DIALOGUE - .responses[player_response.options[i].response_id] - .action(player_response.npc, player) - elseif player_response.is_custom_trade_dialogue == true then - -- 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) + .responses[player_response.options[i].response_id] + .action(player_response.npc, player) + elseif player_response.is_custom_trade_dialogue == true then + -- 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) + local response = get_response_object_by_id_recursive(dialogue, 0, player_response.options[i].response_id) - -- 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 d9bbc65..c382dc3 100755 --- a/npc.lua +++ b/npc.lua @@ -344,6 +344,8 @@ function npc.initialize(entity, pos, is_lua_entity, npc_stats, occupation_name) favorite_items = npc.relationships.select_random_favorite_items(ent.sex, "phase1"), -- Choose disliked items. Choose phase1 per default disliked_items = npc.relationships.select_random_disliked_items(ent.sex), + -- Enable/disable gift item hints dialogue lines + enable_gift_items_hints = true } -- Flag that determines if NPC can have a relationship @@ -845,7 +847,8 @@ npc.schedule_properties = { take_item = "take_item", trader_status = "trader_status", can_receive_gifts = "can_receive_gifts", - flag = "flag" + flag = "flag", + enable_gift_items_hints = "enable_gift_items_hints" } local function get_time_in_hours() @@ -1012,6 +1015,8 @@ function npc.schedule_change_property(self, property, args) self.flags[args.flag_name] = false end end + elseif property == npc.schedule_properties.enable_gift_item_hints then + self.gift_data.enable_gift_items_hints = args.value end end diff --git a/occupations/occupations.lua b/occupations/occupations.lua index 13015ac..a5d4279 100644 --- a/occupations/occupations.lua +++ b/occupations/occupations.lua @@ -30,6 +30,9 @@ -- occupation that can be used to initialize NPCs. The format is the following: -- { -- dialogues = { +-- enable_gift_item_dialogues = true, +-- -- This flag enables/disables gift item dialogues. +-- -- If not set, it defaults to true. -- type = "", -- -- The type can be "given", "mix" or "tags" -- data = {}, @@ -374,6 +377,11 @@ function npc.occupations.initialize_occupation_values(self, occupation_name) -- Initialize dialogues if def.dialogues then + -- Check for gift item dialogues enable + if def.dialogues.disable_gift_item_dialogues then + self.dialogues.hints = {} + end + local dialogue_keys = {} -- Check which type of dialogues we have if def.dialogues.type == "given" and def.dialogues.keys then @@ -421,11 +429,20 @@ function npc.occupations.initialize_occupation_values(self, occupation_name) end end - -- Initialize trader status - if def.initial_trader_status then - self.trader_data.trader_status = def.initial_trader_status + -- Initialize properties + minetest.log("def.properties: "..dump(def.properties)) + if def.properties then + -- Initialize trader status + if def.properties.initial_trader_status then + self.trader_data.trader_status = def.properties.initial_trader_status + end + -- Enable/disable gift items hints + if def.properties.enable_gift_items_hints ~= nil then + self.gift_data.enable_gift_items_hints = def.properties.enable_gift_items_hints + end end + -- Initialize schedule entries if def.schedules_entries and table.getn(npc.utils.get_map_keys(def.schedules_entries)) > 0 then -- Create schedule in NPC