-- 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 --]] yl_speak_up.input_fs_add_quest_steps = function(player, formname, fields) local pname = player:get_player_name() if(not(pname) or not(yl_speak_up.speak_to[pname])) then return end if(fields and fields.back_from_error_msg) then yl_speak_up.show_fs(player, "add_quest_steps") return end if(fields and fields.back) then if(yl_speak_up.speak_to[pname].quest_step) then yl_speak_up.show_fs(player, "manage_quest_steps", yl_speak_up.speak_to[pname].quest_step) return end end -- has a quest step be selected? local work_step = nil if(fields and fields.add_step and fields.add_quest_step) then local q_id = yl_speak_up.speak_to[pname].q_id local new_step = fields.add_quest_step:trim() -- a new one shall be created local res = yl_speak_up.quest_step_add_quest_step(pname, q_id, new_step) if(res ~= "OK") then yl_speak_up.show_fs(player, "msg", { input_to = "yl_speak_up:add_quest_steps", formspec = "size[9,2]".. "label[0.2,0.0;Error:\n".. minetest.formspec_escape(minetest.wrap_text(res,80)).."]".. "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) return res 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 pname and yl_speak_up.speak_to[pname] and yl_speak_up.speak_to[pname].available_quest_steps) then local liste = yl_speak_up.speak_to[pname].available_quest_steps 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 end if(work_step) then -- minetest.chat_send_player("singleplayer","SELECTED: "..tostring(work_step)) -- TODO return end -- minetest.chat_send_player("singleplayer","FIELDS: "..minetest.serialize(fields)) -- TODO: implement 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) 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 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=left".. -- name of quest step "]table[") table.insert(formspec, table_specs) table.insert(formspec,"#FFFFFF,(O),#FFFFFF,(A),#FFFFFF,(U),#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]) table.insert(tmp, "#AAFFAA") table.insert(tmp, minetest.formspec_escape(s)) end table.insert(formspec, table.concat(tmp, ",")) table.insert(formspec, ";]") end yl_speak_up.get_fs_add_quest_steps = function(player, param) local pname = player:get_player_name() if(not(pname) or not(yl_speak_up.speak_to[pname])) then return yl_speak_up.show_fs(player, "manage_quests") end local q_id = yl_speak_up.speak_to[pname].q_id -- TODO: check if the player can access that quest if(not(q_id)) then return yl_speak_up.show_fs(player, "manage_quests") end local quest = yl_speak_up.quests[q_id] if(not(quest)) then return yl_speak_up.show_fs(player, "manage_quests") end local step_data = quest.step_data -- find out if a quest step is required by other quest steps 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 local formspec = {} table.insert(formspec, "size[12.5,17.3]") -- 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(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(quest.name or "- unknown -")) table.insert(formspec, "]") -- add new quest step table.insert(formspec, "label[0.2,2.2;Add a new quest step named:]") table.insert(formspec, "button[11.1,2.4;1.2,0.7;add_step;Add]") table.insert(formspec, "field[1.0,2.4;10,0.7;add_quest_step;;]") 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(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 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;12.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;12.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 end -- TODO: temporary! local available_steps = {} for k, v in pairs(step_data) do table.insert(available_steps, k) end table.sort(available_steps) yl_speak_up.speak_to[pname].available_quest_steps = available_steps table.insert(formspec, "label[0.2,") table.insert(formspec, tostring(y_pos)) table.insert(formspec, ";or select an existing quest step from the list below:]") yl_speak_up.quest_step_list_show_table(formspec, "0.2,"..tostring(y_pos + 0.2)..";12.0,6.0;add_from_available;", available_steps, step_data, required_for_steps) table.insert(formspec, "label[0.2,") table.insert(formspec, tostring(y_pos + 6.5)) table.insert(formspec, ";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]") -- TODO: write before which quest step we want to insert (if that is what is selected) return table.concat(formspec, "") end