diff --git a/fs_edit_effects.lua b/fs_edit_effects.lua index 9f33bfb..ecfba92 100644 --- a/fs_edit_effects.lua +++ b/fs_edit_effects.lua @@ -406,13 +406,14 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r) elseif(r.r_operator and r.r_operator == "set_to_current_time") then -- we store the time in seconds - because microseconds would just -- confuse the users and be too fine grained anyway - new_value = minetest.get_us_time()/1000000 + new_value = math.floor(minetest.get_us_time()/1000000) else yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." ".. "state: Unsupported type: "..tostring(r.r_value)..".") return false end - local ret = yl_speak_up.set_quest_variable_value(owner, pname, r.r_variable, new_value) + -- the owner is already encoded in the variable name + local ret = yl_speak_up.set_quest_variable_value(pname, r.r_variable, new_value) yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." ".. "state: Success: "..tostring(ret).." for setting "..tostring(r.r_variable).." to ".. tostring(new_value)..".") diff --git a/fs_edit_general.lua b/fs_edit_general.lua index 5d0c333..e4b5052 100644 --- a/fs_edit_general.lua +++ b/fs_edit_general.lua @@ -703,6 +703,14 @@ yl_speak_up.input_fs_edit_option_related = function(player, formname, fields, yl_speak_up.speak_to[pname][ tmp_data_cache ].action_failure_dialog = nr end + -- new variables have to be added (and deleted) somewhere after all + if(fields.manage_variables) then + -- remember which formspec we are comming from + yl_speak_up.speak_to[pname][ "working_at" ] = formspec_input_to + yl_speak_up.show_fs(player, "manage_variables") + return + end + -- the player wants to change/edit a precondition or effect if(not(fields.back) and (fields.change_element or fields.select_what or fields.select_trade @@ -966,7 +974,8 @@ yl_speak_up.get_fs_edit_option_related = function(player, table_click_result, tostring(data.operator)..";]".. "label[11.2,4.3;"..text_select_value.."]".. field_for_value.. - "hypertext[1.2,6.0;16.0,2.5;some_text;".. + "button[0.2,6.0;4.0,0.6;manage_variables;Manage variables]".. + "hypertext[1.2,7.0;16.0,2.5;some_text;".. "Note: Each variable is player-specific and will be set and ".. "checked for the player that currently talks to your NPC.\n".. "Note: You can set a variable to the current time in an effect. ".. diff --git a/fs_edit_preconditions.lua b/fs_edit_preconditions.lua index 60b6b98..d5a145e 100644 --- a/fs_edit_preconditions.lua +++ b/fs_edit_preconditions.lua @@ -265,7 +265,8 @@ yl_speak_up.eval_precondition = function(player, n_id, p) local pname = player:get_player_name() local owner = yl_speak_up.npc_owner[ n_id ] -- get the value of the variable - var_val = yl_speak_up.get_quest_variable_value(owner, pname, p.p_variable) + -- the owner is alrady encoded in the variable name + var_val = yl_speak_up.get_quest_variable_value(pname, p.p_variable) end if(p.p_operator == "not") then @@ -311,7 +312,7 @@ yl_speak_up.eval_precondition = function(player, n_id, p) return true end return (tonumber(var_val) + tonumber(p.p_var_cmp_value)) < - minetest.get_us_time()/1000000 + math.floor(minetest.get_us_time()/1000000) elseif(p.p_operator == "less_than_x_seconds_ago") then if(not(tonumber(var_val)) or not(tonumber(p.p_var_cmp_value))) then return false diff --git a/quest_api.lua b/quest_api.lua index 4f5b4e1..f8d5a2c 100644 --- a/quest_api.lua +++ b/quest_api.lua @@ -1,30 +1,150 @@ -- just some handling of variables +-- TODO: handle read (and write?) access for other players +-- TODO: add a function to check if the player has read/write access +-- TODO: mark some vars as "need to be saved" while others are less important (i.e. timestamps) +-- TODO: save state whenever a new variable is added - or else if the last change was more than x minutes ago? + +-- the keys are of the form: +-- (makes it easier to grant read access) +-- the values are of the form: +-- : yl_speak_up.player_vars = {} --- set the value of a variable used by a player in an NPC -yl_speak_up.set_quest_variable_value = function(owner_name, current_player_name, variable_name, new_value) - -- TODO: actually implement - minetest.chat_send_player(current_player_name, "[Info] Trying to set variable ".. - tostring(variable_name).." to "..tostring(new_value)..".") - return false + +-- new variables have to be added somehow +yl_speak_up.add_quest_variable = function(owner_name, variable_name) + local k = tostring(owner_name).." "..tostring(variable_name) + if(not(owner_name) or not(variable_name)) then + return false + end + -- create a new empty table; + -- keys will be the names of players for which values are set + yl_speak_up.player_vars[ k ] = {} + return true end --- get the value of a variable used by a player in an NPC -yl_speak_up.get_quest_variable_value = function(owner_name, current_player_name, variable_name) - -- TODO: actually implement - return tostring(owner_name).." "..tostring(current_player_name).." "..tostring(variable_name) + +-- accidentally created or no longer needed variables need to be deleted somehow +yl_speak_up.del_quest_variable = function(owner_name, variable_name) + local k = tostring(owner_name).." "..tostring(variable_name) + if(not(owner_name) or not(variable_name)) then + return false + end + yl_speak_up.player_vars[ k ] = nil end + +-- set the value of a variable used by a player in an NPC; +-- returns false if the variable cannot be set (i.e. does not exist) +yl_speak_up.set_quest_variable_value = function(player_name, variable_name, new_value) + -- 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 + return false + end + yl_speak_up.player_vars[ k ][ player_name ] = new_value + return true +end + + +-- get the value of a variable used by a player in an NPC; +-- returns nil if the variable does not exist +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 + return nil + end + return yl_speak_up.player_vars[ k ][ player_name ] +end + + -- which variables can player pname read and use in preconditions? +-- returns a sorted list yl_speak_up.get_quest_variables_with_read_access = function(pname) - -- TODO: actually implement - return {"var_1","var_2","var_3", "var_4"} + if(not(pname)) then + return {} + end + local liste = {} + for k, v in pairs(yl_speak_up.player_vars) do + local parts = string.split(k, " ") + if(parts and parts[1] and parts[1] == pname) then + table.insert(liste, k) + end + end + -- TODO: insert those vars owned by other players where this one has read access to + table.sort(liste) + return liste end + -- which variables can player pname write and use in effects/results? yl_speak_up.get_quest_variables_with_write_access = function(pname) - -- TODO: actually implement - return {"var_1","var_2","var_3"} + if(not(pname)) then + return {} + end + local liste = {} + for k, v in pairs(yl_speak_up.player_vars) do + local parts = string.split(k, " ") + if(parts and parts[1] and parts[1] == pname) then + table.insert(liste, k) + end + end + -- TODO: insert those vars owned by other players where this one has write access to + table.sort(liste) + return liste +end + + +yl_speak_up.input_fs_manage_variables = function(player, formname, fields) + local pname = player:get_player_name() + if(fields and fields.back_from_msg) then + yl_speak_up.show_fs(player, "manage_variables") + return + end + -- add a new variable? + if(fields and fields.add_variable) then + if(not(fields.add_variable_name) or fields.add_variable_name == "") then + yl_speak_up.show_fs(player, "msg", { + input_to = "yl_speak_up:manage_variables", + formspec = "size[6,2]".. + "label[0.2,0.5;Please enter the name of your variable!]".. + "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) + return + end + local res = yl_speak_up.add_quest_variable(pname, fields.add_variable_name) + local text = "A new variable named\n \""..tostring(fields.add_variable_name).. + "\"\nhas been created." + if(not(res)) then + text = "Failed to create variable named\n \"".. + tostring(fields.add_variable_name).."\"." + end + yl_speak_up.show_fs(player, "msg", { + input_to = "yl_speak_up:manage_variables", + formspec = "size[6,2]".. + "label[0.2,0.0;"..minetest.formspec_escape(text).."]".. + "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) + return + + end + -- try to go back to the last formspec shown before this one + if(not(yl_speak_up.speak_to[pname])) then + return + end + local last_fs = yl_speak_up.speak_to[pname][ "working_at" ] + yl_speak_up.show_fs(player, last_fs) +end + + +yl_speak_up.get_fs_manage_variables = function(player, param) + return "size[12,4]".. + "label[2.0,-0.2;* Manage your variables *]".. + "label[0.2,1.0;Create this new variable:]".. + "field[3.7,1.3;6.0,0.6;add_variable_name;;]".. + "button[9.4,1.0;2.5,0.6;add_variable;Create variable]".. + "tooltip[add_variable;Enter the name of your new variable.]".. + -- TODO: delete variable + "button[2.0,3.5;1.0,0.6;back;Back]" end diff --git a/show_fs.lua b/show_fs.lua index 04bef1a..16c041f 100644 --- a/show_fs.lua +++ b/show_fs.lua @@ -66,6 +66,10 @@ minetest.register_on_player_receive_fields( function(player, formname, fields) elseif formname == "yl_speak_up:edit_effects" then yl_speak_up.input_fs_edit_effects(player, formname, fields) return true + -- handled in quest_api.lua + elseif formname == "yl_speak_up:manage_variables" then + yl_speak_up.input_fs_manage_variables(player, formname, fields) + return true end end) @@ -184,6 +188,10 @@ yl_speak_up.show_fs = function(player, fs_name, param) minetest.show_formspec(pname, "yl_speak_up:action_custom", yl_speak_up.get_fs_action_custom(player, param)) + elseif(fs_name == "manage_variables") then + minetest.show_formspec(pname, "yl_speak_up:manage_variables", + yl_speak_up.get_fs_manage_variables(player, param)) + -- fallback in case of wrong call else minetest.chat_send_player(pname, "Error: Trying to show wrong "..