yl_speak_up/fs_add_quest_steps.lua
2023-09-19 04:16:38 +02:00

306 lines
12 KiB
Lua

-- 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