From e00be2fc4370ef43e5c9c4eacf67c084b57fd542 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sat, 5 Apr 2025 20:42:13 +0200 Subject: [PATCH 01/12] added effect to play a sound --- api/custom_functions_you_can_override.lua | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/api/custom_functions_you_can_override.lua b/api/custom_functions_you_can_override.lua index e2764f0..fdafdef 100644 --- a/api/custom_functions_you_can_override.lua +++ b/api/custom_functions_you_can_override.lua @@ -530,6 +530,7 @@ yl_speak_up.custom_functions_r_[ "set_variable_to_random_number" ] = { end } + yl_speak_up.custom_functions_r_[ "set_variable_to_random_value_from_list" ] = { description = "Set a variable to a random value from a list.", param1_text = "Name of the variable:", @@ -560,6 +561,66 @@ yl_speak_up.custom_functions_r_[ "set_variable_to_random_value_from_list" ] = { end } + +yl_speak_up.custom_functions_r_[ "play_sound" ] = { + description = "Plays a sound.", + param1_text = "Name of the sound(file):", + param1_desc = "How is the sound(file) called?\n".. + "It has to be provided by another mod.\n".. + "Example: default_dirt_footstep", + param2_text = "Gain:", + param2_desc = "Number between 1 and 10. Default: 10.", + param3_text = "Pitch:", + param3_desc = "Applies a pitch-shift to the sound.\n".. + "Each factor of 20 results in a pitch-shift of +12 semitones.\n".. + "Default is 10.", + param4_text = "Max hear distance:", + param4_desc = "Default: 32 m. Can be set to a value between 3 and 64.", + code = function(player, n_id, r) + if(not(r) or not(r.r_param1) or r.r_param1 == "") then + return false + end + if(not(player)) then + return false + end + local pname = player:get_player_name() + + sound_param = {} + if(r.r_param2 and r.r_param2 ~= "") then + sound_param.gain = math.floor(tonumber(r.r_param2) or 0) + if(sound_param.gain < 1 or sound_param.gain > 10) then + sound_param.gain = 10 + end + sound_param.gain = sound_param.gain / 10 + end + if(r.r_param3 and r.r_param3 ~= "") then + sound_param.pitch = math.floor(tonumber(r.r_pitch) or 0) + if(sound_param.pitch < 1) then + sound_param.pitch = 10 + end + sound_param.pitch = sound_param.pitch / 10 + end + if(r.r_param4 and r.r_param4 ~= "") then + sound_param.max_hear_distance = math.min(tonumber(r.r_pitch) or 1, 32) + if(sound_param.max_hear_distance < 3) then + sound_param.max_hear_distance = 3 + end + if(sound_param.max_hear_distance > 64) then + sound_param.max_hear_distance = 64 + end + end + sound_param.loop = false + -- located at the NPC + sound_param.object = yl_speak_up.speak_to[pname].obj + if(not(sound_param.object)) then + return false + end + -- actually play the sound + core.sound_play(r.r_param1, sound_param, true) + return true + end +} + ----------------------------------------------------------------------------- -- Custom handling of special properties ----------------------------------------------------------------------------- -- 2.47.2 From de001c35396a9965812907acae32394f4bb57268 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sun, 20 Apr 2025 21:38:15 +0200 Subject: [PATCH 02/12] save quest vars only if something actually changed --- quest_api.lua | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/quest_api.lua b/quest_api.lua index 934d3a6..3a94874 100644 --- a/quest_api.lua +++ b/quest_api.lua @@ -26,13 +26,26 @@ yl_speak_up.player_vars = {} -- store when player_vars was last saved to disc yl_speak_up.player_vars_last_save_time = 0 +-- do not save this data every time it's changed - reduce disk writes +yl_speak_up.quest_var_saving_pending = 0 + -- save the data to disc; either if force_save is set or enough time has passed yl_speak_up.save_quest_variables = function(force_save) - if(not(force_save) - and (yl_speak_up.player_vars_last_save_time + yl_speak_up.player_vars_min_save_time > - math.floor(minetest.get_us_time()/1000000))) then + if(not(force_save)) then + if(yl_speak_up.quest_var_saving_pending > minetest.get_us_time()) then + -- we are waiting a bit, hoping to catch more changes before next write + return + end + if(yl_speak_up.player_vars_min_save_time < 10) then + yl_speak_up.player_vars_min_save_time = 10 + end + -- save in yl_speak_up.player_vars_min_save_time seconds + yl_speak_up.quest_var_saving_pending = minetest.get_us_time() + + yl_speak_up.player_vars_min_save_time * 1000000 + core.after(yl_speak_up.player_vars_min_save_time, yl_speak_up.save_quest_variables, true) return end + yl_speak_up.quest_var_saving_pending = 0 local json = minetest.write_json( yl_speak_up.player_vars ) -- actually store it on disk minetest.safe_file_write(yl_speak_up.worldpath..yl_speak_up.player_vars_save_file..".json", json) @@ -185,6 +198,10 @@ yl_speak_up.set_quest_variable_value = function(player_name, variable_name, new_ if(new_value ~= nil) then new_value = tostring(new_value) end + -- no need to change anything if the value is unchanged + if(yl_speak_up.player_vars[ k ][ player_name ] == new_value) then + return true + end yl_speak_up.player_vars[ k ][ player_name ] = new_value -- a quest variable was changed - save that to disc (but no need to force it) yl_speak_up.save_quest_variables(false) @@ -363,28 +380,42 @@ yl_speak_up.set_variable_metadata = function(k, pname, meta_name, entry_name, ne if(not(yl_speak_up.player_vars[ k ])) then return false end + changed = nil -- make sure all the necessary tables exist if( not(yl_speak_up.player_vars[ k ][ "$META$" ])) then yl_speak_up.player_vars[ k ][ "$META$" ] = { meta_name = {} } + changed = true end -- var_type (the type of the variable) is a single string if(meta_name == "var_type") then - yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ] = new_value + if(yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ] ~= new_value) then + yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ] = new_value + changed = true + end elseif(meta_name == "default_value") then -- reset default value to nil with empty string: if(new_value == "") then new_value = nil end - yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ] = new_value + if(yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ] ~= new_value) then + yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ] = new_value + changed = true + end else if( not(yl_speak_up.player_vars[ k ][ "$META$" ][ meta_name ]) or type(yl_speak_up.player_vars[ k ][ "$META$" ][ meta_name ]) ~= "table") then yl_speak_up.player_vars[ k ][ "$META$" ][ meta_name ] = {} + changed = true + end + if(yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ][ entry_name ] ~= new_values) then + yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ][ entry_name ] = new_value + changed = true end - yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ][ entry_name ] = new_value end - yl_speak_up.save_quest_variables(true) + if(changed) then + yl_speak_up.save_quest_variables(true) + end return true end -- 2.47.2 From 208cafc7257e288e12b4cfb87ba0dbd891b96f92 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sat, 31 May 2025 19:28:16 +0200 Subject: [PATCH 03/12] fixed local variables --- quest_api.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quest_api.lua b/quest_api.lua index 3a94874..f2a86dd 100644 --- a/quest_api.lua +++ b/quest_api.lua @@ -380,7 +380,7 @@ yl_speak_up.set_variable_metadata = function(k, pname, meta_name, entry_name, ne if(not(yl_speak_up.player_vars[ k ])) then return false end - changed = nil + local changed = nil -- make sure all the necessary tables exist if( not(yl_speak_up.player_vars[ k ][ "$META$" ])) then yl_speak_up.player_vars[ k ][ "$META$" ] = { meta_name = {} } @@ -408,7 +408,7 @@ yl_speak_up.set_variable_metadata = function(k, pname, meta_name, entry_name, ne yl_speak_up.player_vars[ k ][ "$META$" ][ meta_name ] = {} changed = true end - if(yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ][ entry_name ] ~= new_values) then + if(yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ][ entry_name ] ~= new_value) then yl_speak_up.player_vars[ k ][ "$META$"][ meta_name ][ entry_name ] = new_value changed = true end -- 2.47.2 From 2b7db390c5912482696abe68232adf18978b929f Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sun, 1 Jun 2025 05:22:17 +0200 Subject: [PATCH 04/12] made action trade work again --- fs/fs_do_trade_simple.lua | 3 ++- show_fs.lua | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/fs_do_trade_simple.lua b/fs/fs_do_trade_simple.lua index 35e314e..071f51d 100644 --- a/fs/fs_do_trade_simple.lua +++ b/fs/fs_do_trade_simple.lua @@ -265,7 +265,8 @@ yl_speak_up.get_fs_do_trade_simple = function(player, trade_id) "button[0.2,1.0;2.0,0.9;show_trade_list_dialog_options;Back to list]".. "tooltip[show_trade_list_dialog_options;".. "Click here to get back to the list of all trades\n".. - "associated with dialog options (like this one).]" + "associated with dialog options (like this one).\n".. + "This button is only shown if you can edit this NPC.]" local dialog = yl_speak_up.speak_to[pname].dialog local tr = dialog.trades[ trade_id ] if( tr and tr.d_id and tr.o_id) then diff --git a/show_fs.lua b/show_fs.lua index b986b5a..cddb496 100644 --- a/show_fs.lua +++ b/show_fs.lua @@ -74,6 +74,10 @@ yl_speak_up.show_fs = function(player, fs_name, param) return end + -- this formspec was renamed; make it usable again + if(fs_name == "trade_simple") then + fs_name = "do_trade_simple" + end local fun = yl_speak_up.registered_forms_get_fs[fs_name] if(fun) then yl_speak_up.show_fs_ver(pname, "yl_speak_up:"..fs_name, -- 2.47.2 From 9d2fb157d0beece1970fd0dfd011977f0efd3046 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sun, 8 Jun 2025 14:00:03 +0200 Subject: [PATCH 05/12] fixed two bugs in replacing vars in text --- api/custom_functions_you_can_override.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/custom_functions_you_can_override.lua b/api/custom_functions_you_can_override.lua index fdafdef..0ad3cc7 100644 --- a/api/custom_functions_you_can_override.lua +++ b/api/custom_functions_you_can_override.lua @@ -24,6 +24,9 @@ yl_speak_up.replace_vars_in_text = function(text, dialog, pname) PLAYER_NAME = pname, } + if(not(text) or text == "") then + return "" + end -- only try to replace variables if there are variables inside the text if(string.find(text, "$VAR ")) then local varlist = yl_speak_up.get_quest_variables(dialog.npc_owner, true) @@ -32,7 +35,7 @@ yl_speak_up.replace_vars_in_text = function(text, dialog, pname) -- only allow to replace unproblematic variable names if(not(string.find(v_name, "[^%w^%s^_^%-^%.]"))) then -- remove leading $ from $ var_owner_name var_name - subs["VAR "..v_name] = yl_speak_up.get_quest_variable_value(dialog.npc_owner, v) or "- not set -" + subs["VAR "..v_name] = yl_speak_up.get_quest_variable_value(pname, v) or "- not set -" end end end -- 2.47.2 From 3855a9b393bb0eceabd756d9997edc252060611a Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sun, 8 Jun 2025 16:32:57 +0200 Subject: [PATCH 06/12] allow to take parts of a stack in d_got_item if take_as_wanted is set --- exec_apply_effects.lua | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/exec_apply_effects.lua b/exec_apply_effects.lua index 5ba64ca..fc94c13 100644 --- a/exec_apply_effects.lua +++ b/exec_apply_effects.lua @@ -197,7 +197,7 @@ yl_speak_up.execute_all_relevant_effects = function(player, effects, o_id, actio 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 + if(not(r.r_value) or r.r_value == "do_nothing" or r.r_value == "take_as_wanted") then refuse_items = false end end @@ -456,7 +456,7 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r) local amount = 0 if(r.r_value == "take_all") then amount = stack_got:get_count() - elseif(r.r_value == "takeas_wanted") then + elseif(r.r_value == "take_as_wanted") then amount = stack_wanted:get_count() -- the NPC didn't get enough if(amount > stack_got:get_count()) then @@ -465,6 +465,16 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r) "is smaller than what the NPC wanted: \"".. tostring(stack_wanted).."\".") return false + elseif(amount < stack_got:get_count()) then + local rest = stack_got:get_count() - amount + player_inv = player:get_inventory() + if(player_inv) then + rest_stack = ItemStack(stack_got:to_table()) + rest_stack:set_count(rest) + player_inv:add_item("main", rest_stack) + stack_got:set_count(amount) + inv:set_stack("npc_wants", 1, stack_got) + end end end local take_stack = stack_got:get_name().." "..tostring(amount) -- 2.47.2 From b371f158013f4c4c69158cd6b45bf6efbb83ecea Mon Sep 17 00:00:00 2001 From: Sokomine Date: Sun, 8 Jun 2025 16:33:44 +0200 Subject: [PATCH 07/12] supported "at least" for accepting items --- exec_eval_preconditions.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/exec_eval_preconditions.lua b/exec_eval_preconditions.lua index 385dd14..25ef3fb 100644 --- a/exec_eval_preconditions.lua +++ b/exec_eval_preconditions.lua @@ -382,8 +382,11 @@ yl_speak_up.eval_precondition = function(player, n_id, p, other_options_true_or_ if(p.p_match_stack_size and p.p_match_stack_size ~= "") then local c_got = stack_got:get_count() local c_wanted = stack_wanted:get_count() + if( p.p_match_stack_size == "exactly" and c_got ~= c_wanted) then return false -- not exactly the same amount as the wanted one + elseif(p.p_match_stack_size == "at_least" and c_got < c_wanted) then + return false -- didn't get at least the wanted amount elseif(p.p_match_stack_size == "less" and c_got >= c_wanted) then return false -- didn't get less than the given number elseif(p.p_match_stack_size == "more" and c_got <= c_wanted) then -- 2.47.2 From 6b6c31e4aa2cde8edad52917847977e917f6ae8b Mon Sep 17 00:00:00 2001 From: Sokomine Date: Mon, 9 Jun 2025 01:53:18 +0200 Subject: [PATCH 08/12] adjust real_owner when changing owner as well --- fs/fs_initial_config.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/fs_initial_config.lua b/fs/fs_initial_config.lua index b176803..8af2440 100644 --- a/fs/fs_initial_config.lua +++ b/fs/fs_initial_config.lua @@ -151,6 +151,7 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields) ent.yl_speak_up.npc_name = dialog.n_npc ent.yl_speak_up.npc_description = dialog.n_description ent.owner = yl_speak_up.npc_owner[ n_id ] or dialog.npc_owner + ent.yl_speak_up.real_owner = ent.owner local i_text = dialog.n_npc .. "\n" .. dialog.n_description .. "\n" .. yl_speak_up.infotext -- 2.47.2 From 7896d53dd6c6725dded313ee1c841a74ff250665 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Mon, 9 Jun 2025 02:19:58 +0200 Subject: [PATCH 09/12] check parameters in set_variable_to_random_number better --- api/custom_functions_you_can_override.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/custom_functions_you_can_override.lua b/api/custom_functions_you_can_override.lua index 0ad3cc7..d815b1e 100644 --- a/api/custom_functions_you_can_override.lua +++ b/api/custom_functions_you_can_override.lua @@ -514,6 +514,9 @@ yl_speak_up.custom_functions_r_[ "set_variable_to_random_number" ] = { -- set the value of the variable local n1 = tonumber(r.r_param2) local n2 = tonumber(r.r_param3) + if(n1 == nil or n2 == nil) then + return false + end if(n2 < n1) then local tmp = n1 n1 = n2 -- 2.47.2 From 94906c221bf994ae4005d52ed843e93c79f331e9 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Mon, 9 Jun 2025 02:52:39 +0200 Subject: [PATCH 10/12] allow to combine values of variables via operator --- api/custom_functions_you_can_override.lua | 70 +++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/api/custom_functions_you_can_override.lua b/api/custom_functions_you_can_override.lua index d815b1e..bfb02dc 100644 --- a/api/custom_functions_you_can_override.lua +++ b/api/custom_functions_you_can_override.lua @@ -568,6 +568,76 @@ yl_speak_up.custom_functions_r_[ "set_variable_to_random_value_from_list" ] = { } +yl_speak_up.custom_functions_r_[ "var0_eq_var1_op_var2" ] = { + description = "Set a to the value of .", + param1_text = "Name of the variable0 to set:", + param1_desc = "Which variable do you want to set to the new value?", + param2_text = "Name of variable1:", + param2_desc = "Which variable holds the value of the first operand?", + param3_text = "Operand (+ - * / % ^ and or):", + param3_desc = "Choose operand: Add, subtract, multiply, divide, modulo, exponent, and, or.", + param4_text = "Name of variable2:", + param4_desc = "Which variable holds the value of the second operand?", + code = function(player, n_id, r) + if(not(r) or not(r.r_param1) or r.r_param1 == "" + or not(r.r_param2) or r.r_param2 == "" + or not(r.r_param3) or r.r_param3 == "" + or not(r.r_param4) or r.r_param4 == "") then + return false + end + -- the owner is already encoded in the variable name + local pname = player:get_player_name() + local owner = yl_speak_up.npc_owner[ n_id ] + local prefix = "$ "..tostring(owner).." " + local v_1 = yl_speak_up.get_quest_variable_value(pname, prefix..r.r_param2) + local v_2 = yl_speak_up.get_quest_variable_value(pname, prefix..r.r_param3) + local new_value = nil + local op = r.r_param3 + if(op == 'and') then + new_value = v_1 and v_2 + elseif(op == 'or') then + new_value = v_1 or v_2 + else + v_1 = tonumber(v_1) + v_2 = tonumber(v_2) + if(v_1 == nil or v_2 == nil) then + new_value = nil + elseif(op == '+') then + new_value = v_1 + v_2 + elseif(op == '-') then + new_value = v_1 - v_2 + elseif(op == '*') then + new_value = v_1 * v_2 + elseif(op == '/') then + if(v_2 ~= 0) then + new_value = v_1 / v_2 + else + new_value = nil + end + elseif(op == '%') then + if(v_2 ~= 0) then + new_value = v_1 % v_2 + else + new_value = nil + end + elseif(op == '^') then + new_value = v_1 ^ v_2 + end + end + if(new_value == nil) then + return false + end + local ret = yl_speak_up.set_quest_variable_value(pname, prefix..r.r_param1, new_value) + + local o_id = yl_speak_up.speak_to[pname].o_id or "?" + yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." ".. + "state: Success: "..tostring(ret).." for setting "..tostring(r.r_param1).." to ".. + tostring(new_value)..".") + return ret + end +} + + yl_speak_up.custom_functions_r_[ "play_sound" ] = { description = "Plays a sound.", param1_text = "Name of the sound(file):", -- 2.47.2 From cce17c7c232c991ca5e1f47051a12704607919db Mon Sep 17 00:00:00 2001 From: Sokomine Date: Mon, 9 Jun 2025 03:41:34 +0200 Subject: [PATCH 11/12] fixed undeclared globals --- exec_apply_effects.lua | 4 ++-- fs/fs_talkdialog.lua | 3 ++- quest_api.lua | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/exec_apply_effects.lua b/exec_apply_effects.lua index fc94c13..c90755e 100644 --- a/exec_apply_effects.lua +++ b/exec_apply_effects.lua @@ -467,9 +467,9 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r) return false elseif(amount < stack_got:get_count()) then local rest = stack_got:get_count() - amount - player_inv = player:get_inventory() + local player_inv = player:get_inventory() if(player_inv) then - rest_stack = ItemStack(stack_got:to_table()) + local rest_stack = ItemStack(stack_got:to_table()) rest_stack:set_count(rest) player_inv:add_item("main", rest_stack) stack_got:set_count(amount) diff --git a/fs/fs_talkdialog.lua b/fs/fs_talkdialog.lua index 7a30ee3..9fc03ec 100644 --- a/fs/fs_talkdialog.lua +++ b/fs/fs_talkdialog.lua @@ -374,7 +374,8 @@ yl_speak_up.apply_autoanswer_and_random_and_d_got_item = function(player, pname, -- show the new target dialog and exit -- the recursion_depth will be increased by one (we did autoselect here and need to -- avoid infinite loops) - return yl_speak_up.get_fs_talkdialog(player, n_id, target_dialog, res.alternate_text, + return yl_speak_up.get_fs_talkdialog(player, + yl_speak_up.speak_to[pname].n_id, target_dialog, res.alternate_text, recursion_depth + 1) end diff --git a/quest_api.lua b/quest_api.lua index f2a86dd..96f77d9 100644 --- a/quest_api.lua +++ b/quest_api.lua @@ -215,6 +215,7 @@ yl_speak_up.get_quest_variable_value = function(player_name, variable_name) -- the owner name is alrady encoded in the variable name local k = tostring(variable_name) if(not(variable_name) or not(player_name) or not(yl_speak_up.player_vars[ k ])) then + local k_long = yl_speak_up.add_pname_to_var(k, player_name or "") yl_speak_up.get_variable_metadata(k_long, "default_value", true) return nil end -- 2.47.2 From 38081f8f17ef6bf2a43526338845781350f527a1 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Mon, 9 Jun 2025 04:04:46 +0200 Subject: [PATCH 12/12] fixed operation with two variables --- api/custom_functions_you_can_override.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/custom_functions_you_can_override.lua b/api/custom_functions_you_can_override.lua index bfb02dc..52d7191 100644 --- a/api/custom_functions_you_can_override.lua +++ b/api/custom_functions_you_can_override.lua @@ -590,7 +590,7 @@ yl_speak_up.custom_functions_r_[ "var0_eq_var1_op_var2" ] = { local owner = yl_speak_up.npc_owner[ n_id ] local prefix = "$ "..tostring(owner).." " local v_1 = yl_speak_up.get_quest_variable_value(pname, prefix..r.r_param2) - local v_2 = yl_speak_up.get_quest_variable_value(pname, prefix..r.r_param3) + local v_2 = yl_speak_up.get_quest_variable_value(pname, prefix..r.r_param4) local new_value = nil local op = r.r_param3 if(op == 'and') then -- 2.47.2