-- helper function to make unintresting zeros in tables less visible local grey_if_zero = function(fs, n) if(n and n == 0) then table.insert(fs, "#444444") else table.insert(fs, "#FFFFFF") end table.insert(fs, minetest.formspec_escape(n)) end -- small helper function local show_error_fs = function(player, text) yl_speak_up.show_fs(player, "msg", { input_to = "yl_speak_up:add_quest_steps", formspec = yl_speak_up.get_fs_quest_edit_error(text, "back_from_error_msg")}) end -- find out in how many quest steps this NPC or location is used; -- ID can either be n_ or a location p_(x,y,z) yl_speak_up.count_used_in_quest_steps = function(id, step_data) local used = 0 for s, d in pairs(step_data or {}) do for loc_id, loc in pairs(d.where or {}) do if(loc and loc.n_id and loc.n_id == id) then used = used + 1 end end end return used end -- This order imposed here on the quest steps is the one in which the -- quest steps have to be solved - as far as we can tell (the quest -- may be in the process of beeing created and not logicly complete yet). yl_speak_up.get_sorted_quest_step_list_by_prev_step = function(pname, q_id) if(not(q_id) or not(yl_speak_up.quests[q_id]) or not(yl_speak_up.quests[q_id].step_data)) then return {} end -- for now: sort alphabeticly local step_data = yl_speak_up.quests[q_id].step_data local liste = {} for k, v in pairs(step_data) do table.insert(liste, k) end table.sort(liste) return liste end --[[ still belongs to the above function -- add back links (or rather: forward links to quest steps that get enabled) local connected = table.copy(step_data) for k, v in pairs(connected) do -- will store the inverse data connected[k].inv_one_step_required = {} connected[k].inv_all_steps_require = {} end for k, v in pairs(connected) do if(k and v and v.one_step_required) then for i, s in ipairs(v.one_step_required) do table.insert(connected[s].inv_one_step_required, k) end end if(k and v and v.all_steps_required) then for i, s in ipairs(v.all_steps_required) do table.insert(connected[s].inv_all_steps_required, k) end end end -- get those quest steps that are not connected and not used yet local liste = {} for k, v in pairs(connected) do if(k and v and #v.one_step_required == 0 and #v.all_steps_required == 0 and #v.inv_one_step_required == 0 and #v.inv_all_steps_required == 0) then table.insert(liste, k) end end -- sort alphabeticly table.sort(liste) -- remove those entries from our connection table (they're not connected anyway); -- we have already added them to the beginning of the list for i, v in ipairs(liste) do connected[v] = nil end return liste end --]] -- helper function: find out if a quest step is required by other quest steps yl_speak_up.quest_step_get_required_for_steps = function(step_data) local required_for_steps = {} for s, d in pairs(step_data) do required_for_steps[s] = {} end for s, d in pairs(step_data) do if(s and d and d.one_step_required and type(d.one_step_required) == "table") then for i, s2 in ipairs(d.one_step_required) do table.insert(required_for_steps[s2], s) end end if(s and d and d.all_steps_required and type(d.all_steps_required) == "table") then for i, s2 in ipairs(d.all_steps_required) do table.insert(required_for_steps[s2], s) end end end return required_for_steps end yl_speak_up.input_fs_add_quest_steps = function(player, formname, fields) if(not(fields) or not(player)) then return end local res = yl_speak_up.player_is_working_on_quest(player) if(res.error_msg) then return show_error_fs(player, res.error_msg) end local pname = res.pname local q_id = res.q_id local current_step = res.current_step local step_data = res.step_data local quest = res.quest if(fields.back_from_error_msg) then yl_speak_up.show_fs(player, "add_quest_steps") return end local mode = yl_speak_up.speak_to[pname].quest_step_mode if(fields.back) then -- go back to quest overview if(mode and (mode == "manage_quest_npcs" or mode == "manage_quest_locations")) then return yl_speak_up.show_fs(player, "manage_quests") end return yl_speak_up.show_fs(player, "manage_quest_steps", current_step) end -- has a quest step be selected? local work_step = nil if(fields.add_element and fields.add_element_name) then if( mode and mode == "manage_quest_npcs") then -- manually entered an NPC ID local npc_id = fields.add_element_name or "" -- just check if it is *potentially* an NPC ID; that way NPC the quest -- creator has no write access to can be added if(string.sub(npc_id, 1, 2) ~= "n_" or not(tonumber(string.sub(npc_id, 3)))) then return show_error_fs(player, "This is not an NPC ID. They have the form n_.") end -- only npcs that are not yet added (and we store IDs without n_ prefix) local id = tonumber(string.sub(npc_id, 3)) if(id and table.indexof(res.quest.npcs or {}, id) == -1) then table.insert(yl_speak_up.quests[q_id].npcs, id) yl_speak_up.save_quest(q_id) end return yl_speak_up.show_fs(player, "add_quest_steps") elseif(mode and mode == "manage_quest_locations") then -- manually entered a quest location local location_id = fields.add_element_name or "" local d = yl_speak_up.player_vars["$NPC_META_DATA$"][location_id] local error_msg = "" -- the owner is not checked; that way, locations can be added where the -- quest onwer does not (yet) have write access if(string.sub(location_id, 1, 1) ~= "p") then error_msg = "This is not a location ID." elseif(not(d)) then error_msg = "Location not found." end if(error_msg ~= "") then return show_error_fs(player, error_msg) end -- only locations that are not yet added if(table.indexof(res.quest.locations or {}, location_id) == -1) then table.insert(yl_speak_up.quests[q_id].locations, location_id) yl_speak_up.save_quest(q_id) end return yl_speak_up.show_fs(player, "add_quest_steps") end -- create a new quest step local new_step = fields.add_element_name:trim() -- a new one shall be created local msg = yl_speak_up.quest_step_add_quest_step(pname, q_id, new_step) if(msg ~= "OK") then return show_error_fs(player, msg) end -- this will also be set if the quest step exists already; this is fine so far work_step = new_step elseif(fields.add_from_available and yl_speak_up.speak_to[pname].list_available) then -- selected a quest step from the list of available steps offered local liste = yl_speak_up.speak_to[pname].list_available local selected = minetest.explode_table_event(fields.add_from_available) if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then work_step = liste[selected.row - 1] end elseif(fields.add_to_npc_list and yl_speak_up.speak_to[pname].list_available) then -- selected an NPC from the list of available NPC offered local liste = yl_speak_up.speak_to[pname].list_available local selected = minetest.explode_table_event(fields.add_to_npc_list) if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then local npc_id = liste[selected.row - 1] if(table.indexof(res.quest.npcs or {}, npc_id) == -1) then table.insert(yl_speak_up.quests[q_id].npcs, npc_id) yl_speak_up.save_quest(q_id) end end return yl_speak_up.show_fs(player, "add_quest_steps") elseif(fields.add_to_location_list and yl_speak_up.speak_to[pname].list_available) then -- selected a location from the list of available locations offered local liste = yl_speak_up.speak_to[pname].list_available local selected = minetest.explode_table_event(fields.add_to_location_list) if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then local location_id = liste[selected.row - 1] if(table.indexof(res.quest.locations or {}, location_id) == -1) then table.insert(yl_speak_up.quests[q_id].locations, location_id) yl_speak_up.save_quest(q_id) end end return yl_speak_up.show_fs(player, "add_quest_steps") elseif(fields.delete_from_one_step_required and current_step and step_data[current_step]) then -- remove a quest step from the list (from one step required) local selected = minetest.explode_table_event(fields.delete_from_one_step_required) local liste = (step_data[current_step].one_step_required or {}) if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then table.remove(yl_speak_up.quests[q_id].step_data[current_step].one_step_required, selected.row-1) end yl_speak_up.save_quest(q_id) return yl_speak_up.show_fs(player, "add_quest_steps") elseif(fields.delete_from_all_steps_required and current_step and step_data[current_step]) then -- remove a quest step from the lists (from all steps required) local selected = minetest.explode_table_event(fields.delete_from_all_steps_required) local liste = (step_data[current_step].all_steps_required or {}) if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then table.remove(yl_speak_up.quests[q_id].step_data[current_step].all_steps_required, selected.row-1) end yl_speak_up.save_quest(q_id) return yl_speak_up.show_fs(player, "add_quest_steps") elseif(fields.delete_from_npc_list) then -- remove an NPC from the list of contributors local selected = minetest.explode_table_event(fields.delete_from_npc_list) local liste = (res.quest.npcs or {}) if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then -- *can* it be removed, or is it needed somewhere? local full_id = "n_"..tostring(liste[selected.row - 1]) if(yl_speak_up.count_used_in_quest_steps(full_id, step_data) > 0) then return show_error_fs(player, "This NPC is needed for setting a quest step.") end table.remove(yl_speak_up.quests[q_id].npcs, selected.row - 1) end yl_speak_up.save_quest(q_id) return yl_speak_up.show_fs(player, "add_quest_steps") elseif(fields.delete_from_location_list) then -- remove a location from the list of contributors local selected = minetest.explode_table_event(fields.delete_from_location_list) local liste = (res.quest.locations or {}) if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then -- *can* it be removed, or is it needed somewhere? local full_id = liste[selected.row - 1] if(yl_speak_up.count_used_in_quest_steps(full_id, step_data) > 0) then return show_error_fs(player, "This location is needed for setting a quest step.") end table.remove(yl_speak_up.quests[q_id].locations, selected.row - 1) end yl_speak_up.save_quest(q_id) return yl_speak_up.show_fs(player, "add_quest_steps") end if(not(work_step)) then return -- TODO elseif(mode == "embedded_select") then yl_speak_up.speak_to[t.pname].quest_step = work_step return yl_speak_up.show_fs(player, "manage_quest_steps", work_step) elseif(mode == "assign_quest_step") then -- TODO: what if there's already a step assigned? -- actually add the step local n_id = yl_speak_up.speak_to[pname].n_id local d_id = yl_speak_up.speak_to[pname].d_id local o_id = yl_speak_up.speak_to[pname].o_id -- this saves the quest data as well if needed local msg = yl_speak_up.quest_step_add_where(pname, q_id, work_step, {n_id = n_id, d_id = d_id, o_id = o_id}) if(msg ~= "OK") then return show_error_fs(player, msg) end -- TODO: the NPC needs to be saved as well -- show the newly created or selected step yl_speak_up.speak_to[pname].quest_step = work_step return yl_speak_up.show_fs(player, "manage_quest_steps", work_step) elseif(not(current_step) or not(step_data[current_step])) then return yl_speak_up.show_fs(player, "manage_quests") end local required_for_steps = yl_speak_up.quest_step_get_required_for_steps(step_data) -- make sure we have a sane data structure for i, s in ipairs({current_step, work_step}) do if(s and yl_speak_up.quests[q_id].step_data[s]) then if(not(yl_speak_up.quests[q_id].step_data[s].one_step_required)) then yl_speak_up.quests[q_id].step_data[s].one_step_required = {} end if(not(yl_speak_up.quests[q_id].step_data[s].all_steps_required)) then yl_speak_up.quests[q_id].step_data[s].all_steps_required = {} end end end -- actually do the work if(mode == "add_to_one_needed") then table.insert(yl_speak_up.quests[q_id].step_data[current_step].one_step_required, work_step) elseif(mode == "add_to_all_needed") then table.insert(yl_speak_up.quests[q_id].step_data[current_step].all_steps_required, work_step) elseif(mode == "insert_after_prev_step") then -- the work_step requires what the current step used to require if(#step_data[current_step].one_step_required == 1) then -- a clear insert is possible yl_speak_up.quests[q_id].step_data[work_step].one_step_required = { step_data[current_step].one_step_required[1]} yl_speak_up.quests[q_id].step_data[current_step].one_step_required[1] = work_step else -- no useful information on what the new work_step ought to depend on; -- we just insert the new step at the first place table.insert(yl_speak_up.quests[q_id].step_data[current_step].one_step_required, 1, work_step) end return yl_speak_up.show_fs(player, "manage_quest_steps", work_step) elseif(mode == "insert_before_next_step") then -- the work_step requires the current_step table.insert(yl_speak_up.quests[q_id].step_data[work_step].one_step_required, 1, current_step) -- the current step has exactly one successor? then we adjust that one if(#required_for_steps[current_step] == 1) then local next_step = required_for_steps[current_step][1] local i = table.indexof(step_data[next_step].one_step_required, current_step) local a = table.indexof(step_data[next_step].all_steps_required, current_step) if(i > -1) then -- is it in one_step_required? -> replace current_step with work_step yl_speak_up.quests[q_id].step_data[next_step].one_step_required[i] = work_step elseif(a > -1) then -- or in all_steps_required? -> replace current_step with work_step yl_speak_up.quests[q_id].step_data[next_step].all_steps_required[i] =work_step end end return yl_speak_up.show_fs(player, "manage_quest_steps", work_step) end yl_speak_up.save_quest(q_id) return yl_speak_up.show_fs(player, "add_quest_steps") end -- small helper function for yl_speak_up.get_fs_add_quest_steps; -- lists all the quest steps found in liste in the order they occour there yl_speak_up.quest_step_list_show_table = function(formspec, table_specs, liste, data, required_for_steps) table.insert(formspec, "tablecolumns[".. "color;text,align=right;".. -- #d.one_step_required "color;text,align=right;".. -- #d.all_steps_required "color;text,align=right;".. -- #required_for_steps (quest steps that need this one) "color;text,align=right;".. -- #where (locations/NPC that *set* this quest step) "color;text,align=left".. -- name of quest step "]table[") table.insert(formspec, table_specs) table.insert(formspec,"#FFFFFF,(O),#FFFFFF,(A),#FFFFFF,(U),#FFFFFF,(L),#FFFFFF,Name of step:,") local tmp = {} for i, s in ipairs(liste or {}) do local d = data[s] if(not(d.one_step_required) or type(d.one_step_required) ~= "table") then d.one_step_required = {} end grey_if_zero(tmp, #d.one_step_required) if(not(d.all_steps_required) or type(d.all_steps_required) ~= "table") then d.all_steps_required = {} end grey_if_zero(tmp, #d.all_steps_required) if(not(required_for_steps[s])) then required_for_steps[s] = {} end grey_if_zero(tmp, #required_for_steps[s]) if(not(d.where) or type(d.where) ~= "table") then d.where = {} end local anz_where = 0 for k, v in pairs(d.where) do anz_where = anz_where + 1 end grey_if_zero(tmp, anz_where) table.insert(tmp, "#AAFFAA") table.insert(tmp, minetest.formspec_escape(s)) end table.insert(formspec, table.concat(tmp, ",")) table.insert(formspec, ";]") end -- returns list of NPCs that pname can edit and that are not yet part of quest_npc_list yl_speak_up.quest_get_npc_candidate_list = function(pname, quest_npc_liste) -- build a list of candidates local npc_list = {} for k, v in pairs(yl_speak_up.npc_list) do -- only NPC that are not already added if(table.indexof(quest_npc_liste or {}, k) == -1 -- and only those that the player can edit and (v.owner == pname or (v.may_edit and v.may_edit[pname]))) then table.insert(npc_list, k) end end table.sort(npc_list) return npc_list end -- lists npc that are either already added or could be added -- can also handle locations yl_speak_up.quest_npc_show_table = function(formspec, table_specs, liste, step_data, is_location_list) table.insert(formspec, "tablecolumns[".. "color;text,align=right;".. -- used in this many quest steps "color;text,align=left;".. -- n_id (number, for NPC) or p_(-185,3,-146) (for locations) "color;text,align=left;".. -- owner "color;text,align=left".. -- name of NPC "]table[") table.insert(formspec, table_specs) if(is_location_list) then table.insert(formspec,"#FFFFFF,Used:,#FFFFFF,PositionID:,#FFFFFF,Name") else table.insert(formspec,"#FFFFFF,Used:,#FFFFFF,n_id:,#FFFFFF,Name") end table.insert(formspec, minetest.formspec_escape(",")) table.insert(formspec, " description:,#FFFFFF,Owner:,") local tmp = {} for i, n_id in ipairs(liste or {}) do local full_id = n_id if(not(is_location_list)) then full_id = "n_"..tostring(n_id) end grey_if_zero(tmp, yl_speak_up.count_used_in_quest_steps(full_id, step_data)) -- the n_id of the NPC table.insert(tmp, "#AAFFAA") if(is_location_list) then -- this already encodes the position but contains , and () table.insert(tmp, minetest.formspec_escape(n_id)) else table.insert(tmp, "n_"..minetest.formspec_escape(n_id)) end -- get information from the NPC list (see fs_npc_list.lua) local owner = "- ? -" local name = "- ? -" if(yl_speak_up.npc_list[n_id]) then local npc = yl_speak_up.npc_list[n_id] owner = npc.owner name = (npc.name or name) if(npc.desc and npc.desc ~= "") then name = name..', '..(npc.desc or "") end end -- name and description of the NPC table.insert(tmp, "#AAFFAA") table.insert(tmp, minetest.formspec_escape(name)) -- owner of the NPC table.insert(tmp, "#AAFFAA") table.insert(tmp, minetest.formspec_escape(owner)) end table.insert(formspec, table.concat(tmp, ",")) table.insert(formspec, ";]") end -- returns list of locations that pname can edit and that are not yet part of quest_location_list yl_speak_up.quest_get_location_candidate_list = function(pname, quest_location_liste) -- build a list of candidates of locations local location_list = {} for n_id, v in pairs(yl_speak_up.player_vars["$NPC_META_DATA$"] or {}) do -- TODO: better detection would be helpful if(string.sub(n_id, 1, 1) == "p" -- only locations that are not yet added and table.indexof(quest_location_liste or {}, n_id) == -1 -- and only those that the player can edit and (v.owner == pname or (v.may_edit and v.may_edit[pname]))) then table.insert(location_list, n_id) end end table.sort(location_list) return location_list end -- param is unused yl_speak_up.get_fs_add_quest_steps = function(player, param) local res = yl_speak_up.player_is_working_on_quest(player) if(res.error_msg) then return yl_speak_up.get_fs_quest_edit_error(res.error_msg, "back") end local pname = res.pname local step_data = res.step_data or {} -- find out if a quest step is required by other quest steps local required_for_steps = yl_speak_up.quest_step_get_required_for_steps(step_data) local current_step = nil local this_step_data = nil if(pname and yl_speak_up.speak_to[pname] and yl_speak_up.speak_to[pname].quest_step) then current_step = yl_speak_up.speak_to[pname].quest_step this_step_data = step_data[current_step] end local mode = "" if(param) then mode = param yl_speak_up.speak_to[pname].quest_step_mode = param elseif(pname and yl_speak_up.speak_to[pname] and yl_speak_up.speak_to[pname].quest_step_mode) then mode = yl_speak_up.speak_to[pname].quest_step_mode end local add_what = "Add a new quest step named:" if(mode == "manage_quest_npcs") then add_what = "Add the NPC with n_:" elseif(mode == "manage_quest_locations") then add_what = "Add a location by entering its ID directly:" end local formspec = {} if(mode and mode == "embedded_select") then table.insert(formspec, "size[30,12]container[6,0;18.5,12]") current_step = nil else table.insert(formspec, "size[18.5,17.3]") end -- add back button table.insert(formspec, "button[8,0;2,0.7;back;Back]") -- show which quest we're working at table.insert(formspec, "label[0.2,1.0;Quest ID:]") table.insert(formspec, "label[3.0,1.0;") table.insert(formspec, minetest.formspec_escape(res.q_id)) table.insert(formspec, "]") table.insert(formspec, "label[0.2,1.5;Quest name:]") table.insert(formspec, "label[3.0,1.5;") table.insert(formspec, minetest.formspec_escape(res.quest.name or "- unknown -")) table.insert(formspec, "]") -- add new quest step table.insert(formspec, "label[0.2,2.2;") table.insert(formspec, add_what) table.insert(formspec, "]") table.insert(formspec, "button[16.1,2.4;1.2,0.7;add_element;Add]") table.insert(formspec, "field[1.0,2.4;15,0.7;add_element_name;;]") local y_pos = 3.3 if(current_step and mode == "insert_after_prev_step") then local prev_step = "-" if(this_step_data and this_step_data.one_step_required and #this_step_data.one_step_required > 0) then prev_step = this_step_data.one_step_required[1] end table.insert(formspec, "label[0.2,3.3;between the previous step:]") table.insert(formspec, "label[1.0,3.7;") table.insert(formspec, minetest.colorize("#AAFFAA", minetest.formspec_escape(prev_step))) table.insert(formspec, "]") table.insert(formspec, "label[0.2,4.1;and the currently selected step:]") table.insert(formspec, "label[1.0,4.5;") table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(current_step))) table.insert(formspec, "]") y_pos = 5.3 elseif(current_step and mode == "insert_before_next_step") then local next_step = "-" if(current_step and required_for_steps[current_step] and #required_for_steps[current_step] > 0) then next_step = required_for_steps[current_step][1] end table.insert(formspec, "label[0.2,3.3;between the currently selected step:]") table.insert(formspec, "label[1.0,3.7;") table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(current_step))) table.insert(formspec, "]") table.insert(formspec, "label[0.2,4.1;and the next step:]") table.insert(formspec, "label[1.0,4.5;") table.insert(formspec, minetest.colorize("#AAFFAA", minetest.formspec_escape(next_step))) table.insert(formspec, "]") y_pos = 5.3 elseif(current_step and mode == "add_to_one_needed") then table.insert(formspec, "label[0.2,3.3;as a requirement to the currently selected step:]") table.insert(formspec, "label[1.0,3.7;") table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(current_step))) table.insert(formspec, "]") table.insert(formspec, "label[0.2,4.1;so that ".. minetest.colorize("#9999FF", "at least one").. " of these requirements is fulfilled:]") yl_speak_up.quest_step_list_show_table(formspec, "0.2,4.3;17.0,3.0;delete_from_one_step_required;", step_data[current_step].one_step_required, step_data, required_for_steps) table.insert(formspec, "label[0.2,7.5;(Click on an entry to delete it from the list above.)]") y_pos = 8.3 elseif(current_step and mode == "add_to_all_needed") then table.insert(formspec, "label[0.2,3.3;as a requirement to the currently selected step:]") table.insert(formspec, "label[1.0,3.7;") table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(current_step))) table.insert(formspec, "]") table.insert(formspec, "label[0.2,4.1;so that ".. minetest.colorize("#9999FF", "all").. " of these requirements are fulfilled:]") yl_speak_up.quest_step_list_show_table(formspec, "0.2,4.3;17.0,3.0;delete_from_all_steps_required;", step_data[current_step].all_steps_required, step_data, required_for_steps) table.insert(formspec, "label[0.2,7.5;(Click on an entry to delete it from the list above.)]") y_pos = 8.3 -- add a quest step to an NPC or location elseif(mode == "assign_quest_step") then -- what are we talking about? local n_id = yl_speak_up.speak_to[pname].n_id local d_id = yl_speak_up.speak_to[pname].d_id local o_id = yl_speak_up.speak_to[pname].o_id local dialog = yl_speak_up.speak_to[pname].dialog local name_txt = "- ? -" local dialog_txt = "- ? -" local option_txt = "- ? -" if(dialog and dialog.n_dialogs and d_id and o_id and dialog.n_dialogs[d_id] and dialog.n_dialogs[d_id].d_options and dialog.n_dialogs[d_id].d_options[o_id]) then dialog_txt = dialog.n_dialogs[d_id].d_text or "- ? -" option_txt = dialog.n_dialogs[d_id].d_options[o_id].o_text_when_prerequisites_met or "- ? -" name_txt = (dialog.n_npc or "- ? -") if(dialog.n_description and dialog.n_description ~= "") then name_txt = name_txt..", "..tostring(dialog.n_description) end end -- are we dealing with an NPC? local id_label = "the block at position " if(n_id and string.sub(n_id, 1, 2) == "n_") then id_label = "NPC " end table.insert(formspec, "label[0.2,3.3;which will be set by ") table.insert(formspec, id_label) table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(n_id))) table.insert(formspec, ":]") table.insert(formspec, "label[1.0,3.7;") table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(name_txt))) table.insert(formspec, "]") table.insert(formspec, "label[0.2,4.2;when answering to dialog ") table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(d_id))) table.insert(formspec, ":]") table.insert(formspec, "textarea[1.0,4.4;16,1.8;;;") table.insert(formspec, minetest.formspec_escape(dialog_txt)) table.insert(formspec, "]") table.insert(formspec, "label[0.2,6.5;with the following answer/option ") table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(o_id))) table.insert(formspec, ":]") table.insert(formspec, "label[1.0,6.9;") table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(option_txt))) table.insert(formspec, "]") y_pos = 7.8 -- which NPC may contribute to the quest? elseif(mode == "manage_quest_npcs") then table.insert(formspec, "container[0,3.3;18,6]") table.insert(formspec, "label[0.2,0;so that the NPC ".. minetest.colorize("#9999FF", "may contribute").. " to the quest like these NPC:]") yl_speak_up.quest_npc_show_table(formspec, "0.2,0.2;17.0,3.0;delete_from_npc_list;", res.quest.npcs or {}, step_data, false) table.insert(formspec, "label[0.2,3.4;(Click on an entry to delete it from the list above.)]") local available_npcs = yl_speak_up.quest_get_npc_candidate_list(pname, res.quest.npcs or {}) yl_speak_up.speak_to[pname].list_available = available_npcs table.insert(formspec, "label[0.2,4.4;or select an NPC from the list below:]") yl_speak_up.quest_npc_show_table(formspec, "0.2,4.6;17.0,6.0;add_to_npc_list;", available_npcs or {}, step_data, false) table.insert(formspec, "label[0.2,10.8;Used: Shows in how many quest steps this NPC is used.]") table.insert(formspec, "container_end[]") return table.concat(formspec, "") -- which locations may contribute to the quest? elseif(mode == "manage_quest_locations") then table.insert(formspec, "container[0,3.3;18,6]") table.insert(formspec, "label[0.2,0;so that the location ".. minetest.colorize("#9999FF", "may contribute").. " to the quest like these locations:]") yl_speak_up.quest_npc_show_table(formspec, "0.2,0.2;17.0,3.0;delete_from_location_list;", res.quest.locations or {}, step_data, true) table.insert(formspec, "label[0.2,3.4;(Click on an entry to delete it from the list above.)]") local available_locations = yl_speak_up.quest_get_location_candidate_list(pname, res.quest.locations or {}) yl_speak_up.speak_to[pname].list_available = available_locations table.insert(formspec, "label[0.2,4.4;or select a location from the list below:]") yl_speak_up.quest_npc_show_table(formspec, "0.2,4.6;17.0,6.0;add_to_location_list;", available_locations or {}, step_data, true) table.insert(formspec, "label[0.2,10.8;Used: Shows in how many quest steps this location is used.]") table.insert(formspec, "container_end[]") return table.concat(formspec, "") end -- some quest steps may not be available/may not make sense local not_available = {} if(current_step and step_data[current_step]) then -- steps that are already required for i, s in ipairs(step_data[current_step].one_step_required or {}) do not_available[s] = true end for i, s in ipairs(step_data[current_step].all_steps_required or {}) do not_available[s] = true end -- steps that directly require this quest step here for i, s in ipairs(required_for_steps[current_step] or {}) do not_available[s] = true end end if(current_step) then not_available[current_step] = true end -- build a list of candidates local available_steps = {} for k, v in pairs(step_data) do if(not(not_available[k])) then table.insert(available_steps, k) end end table.sort(available_steps) yl_speak_up.speak_to[pname].list_available = available_steps table.insert(formspec, "container[0,") table.insert(formspec, tostring(y_pos)) table.insert(formspec, ";30,20]") table.insert(formspec, "label[0.2,0;or select an existing quest step from the list below") if(mode and mode == "embedded_select") then table.insert(formspec, minetest.colorize("#9999FF", " to display the step")..":]") else table.insert(formspec, ":]") end yl_speak_up.quest_step_list_show_table(formspec, "0.2,0.2;17,6.0;add_from_available;", available_steps, step_data, required_for_steps) table.insert(formspec, "label[0.2,6.5;Legend: The numbers show the amount of quest steps...\n".. "\t(O) from which (o)ne needs to be achieved for this quest step\n".. "\t(A) that (a)ll need to be achieved for this quest step\n".. "\t(U) that require/(u)se this quest step in some form\n".. "\t(L) Number of locations (npc/places) that ".. minetest.colorize("#9999FF", "set").." this quest step]") table.insert(formspec, "container_end[]") return table.concat(formspec, "") end