forked from your-land-mirror/yl_speak_up
344 lines
14 KiB
Lua
344 lines
14 KiB
Lua
-- assign a quest step to a dialog option/answe
|
|
-- This is the formspec where this is handled.
|
|
|
|
-- small helper function
|
|
local show_error_fs = function(player, text)
|
|
yl_speak_up.show_fs(player, "msg", {
|
|
input_to = "yl_speak_up:assign_quest_step",
|
|
formspec = yl_speak_up.build_fs_quest_edit_error(text, "back_from_error_msg")})
|
|
end
|
|
|
|
|
|
-- small helper function
|
|
yl_speak_up.get_choose_until_step_list = function(pname, q_id, quest_step)
|
|
local choose_until_step = {
|
|
" - the player restarts the quest -",
|
|
" - this quest step -",
|
|
" - the quest step immediately following this one -"
|
|
}
|
|
local cdata = yl_speak_up.quests[q_id].step_data[quest_step]
|
|
for step_name, d in pairs(yl_speak_up.quests[q_id].step_data or {}) do
|
|
if(step_name ~= quest_step
|
|
and cdata
|
|
-- exclude steps that quest_step depends on
|
|
and table.indexof(cdata.one_step_required or {}, step_name) == -1
|
|
and table.indexof(cdata.all_steps_required or {}, step_name) == -1) then
|
|
table.insert(choose_until_step, minetest.formspec_escape(step_name))
|
|
end
|
|
end
|
|
return choose_until_step
|
|
end
|
|
|
|
|
|
yl_speak_up.input_fs_assign_quest_step = function(player, formname, fields)
|
|
if(not(player)) then
|
|
return ""
|
|
end
|
|
local pname = player:get_player_name()
|
|
-- 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
|
|
|
|
if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then
|
|
return
|
|
end
|
|
local dialog = yl_speak_up.speak_to[pname].dialog
|
|
if(not(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id))) then
|
|
return
|
|
end
|
|
|
|
-- go back to edit options field
|
|
if((fields and fields.quit)
|
|
or (fields and fields.back and fields.back ~= "")) then
|
|
yl_speak_up.show_fs(player, "edit_option_dialog",
|
|
{n_id = n_id, d_id = d_id, o_id = o_id})
|
|
return
|
|
elseif(fields and fields.back_from_error_msg) then
|
|
yl_speak_up.show_fs(player, "assign_quest_step", nil)
|
|
return
|
|
-- show manage quests formspec
|
|
elseif(fields and fields.manage_quests) then
|
|
-- store information so that the back button can work
|
|
yl_speak_up.speak_to[pname][ "working_at" ] = "assign_quest_step"
|
|
yl_speak_up.show_fs(player, "manage_quests", nil)
|
|
return
|
|
elseif(fields and fields.show_quest) then
|
|
local q_id = yl_speak_up.speak_to[pname].q_id
|
|
local quest_var_name = nil
|
|
if(q_id and yl_speak_up.quests[q_id]) then
|
|
quest_var_name = yl_speak_up.strip_pname_from_var(yl_speak_up.quests[q_id].var_name, pname)
|
|
end
|
|
yl_speak_up.show_fs(player, "manage_quests", quest_var_name)
|
|
return
|
|
elseif(fields and fields.select_quest_id and fields.select_quest_id ~= "") then
|
|
local parts = string.split(fields.select_quest_id, " ")
|
|
if(parts and parts[1] and yl_speak_up.quests[parts[1]]) then
|
|
-- TODO: check if the player has access rights to that quest
|
|
-- TODO: check if the NPC has been added to that quest
|
|
yl_speak_up.speak_to[pname].q_id = parts[1]
|
|
yl_speak_up.show_fs(player, "add_quest_steps", "assign_quest_step")
|
|
return
|
|
end
|
|
elseif(fields and fields.show_step) then
|
|
yl_speak_up.show_fs(player, "manage_quest_steps", yl_speak_up.speak_to[pname].quest_step)
|
|
return
|
|
elseif(fields and fields.change_show_until) then
|
|
yl_speak_up.show_fs(player, "assign_quest_step", "change_show_until")
|
|
return
|
|
elseif(fields and fields.store_show_until and fields.select_show_until) then
|
|
local res = yl_speak_up.player_is_working_on_quest(player)
|
|
if(res.error_msg) then
|
|
return yl_speak_up.build_fs_quest_edit_error(res.error_msg, "back")
|
|
end
|
|
local choose_until_step = yl_speak_up.get_choose_until_step_list(
|
|
res.pname, res.q_id, yl_speak_up.speak_to[pname].quest_step)
|
|
local index = table.indexof(choose_until_step, fields.select_show_until or "")
|
|
if(index ~= -1) then
|
|
local dialog = yl_speak_up.speak_to[pname].dialog
|
|
if(not(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id))) then
|
|
return
|
|
end
|
|
table.insert(yl_speak_up.npc_was_changed[ n_id ],
|
|
tostring(d_id).." "..tostring(o_id)..
|
|
" quest step will be offered until player reached step \""..
|
|
tostring(fields.select_show_until).."\".")
|
|
if(fields.select_show_until == " - the player restarts the quest -") then
|
|
fields.select_show_until = nil
|
|
elseif(fields.select_show_until == " - this quest step -") then
|
|
fields.select_show_until = yl_speak_up.speak_to[pname].quest_step
|
|
elseif(fields.select_show_until == " - the quest step immediately following this one -") then
|
|
fields.select_show_until = " next_step"
|
|
end
|
|
dialog.n_dialogs[d_id].d_options[o_id].quest_show_until = fields.select_show_until
|
|
end
|
|
yl_speak_up.show_fs(player, "assign_quest_step")
|
|
return
|
|
elseif(fields.delete_assignment and fields.delete_assignment ~= "") then
|
|
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
|
|
-- load the dialog (which may be diffrent from what the player is working on)
|
|
local stored_dialog = yl_speak_up.load_dialog(n_id, false)
|
|
-- check if the dialog exists
|
|
if(not(yl_speak_up.check_if_dialog_has_option(stored_dialog, d_id, o_id))) then
|
|
return show_error_fs(player, "Dialog or option not found.")
|
|
end
|
|
local quest_step_name = dialog.n_dialogs[d_id].d_options[o_id].quest_step
|
|
local var_name = dialog.n_dialogs[d_id].d_options[o_id].quest_id
|
|
local q_id = yl_speak_up.get_quest_id_by_var_name(var_name, pname)
|
|
-- we will ignore the return value so that this connection can be deleted even if
|
|
-- something went wrong (quest deleted, no write access to quest etc.)
|
|
local msg = yl_speak_up.quest_step_del_where(pname, q_id, quest_step_name,
|
|
{n_id = n_id, d_id = d_id, o_id = o_id})
|
|
if(not(n_id)) then
|
|
return show_error_fs(player, "NPC or location not found.")
|
|
end
|
|
-- log the change
|
|
yl_speak_up.log_change(pname, n_id,
|
|
"Dialog "..tostring(d_id)..": Option "..tostring(o_id)..
|
|
" no longer sets quest step \""..
|
|
tostring(dialog.n_dialogs[d_id].d_options[o_id].quest_step)..
|
|
"\" of quest \""..
|
|
tostring(dialog.n_dialogs[d_id].d_options[o_id].quest_id).."\".")
|
|
-- we have updated the quest step data - we need to update the NPC as well
|
|
local dialog = yl_speak_up.load_dialog(n_id, false)
|
|
if(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id)) then
|
|
-- ok - the tables exist, so we can delete the connection
|
|
-- (if it doesn't exist there's no need to change the stored NPC)
|
|
dialog.n_dialogs[d_id].d_options[o_id].quest_id = nil
|
|
dialog.n_dialogs[d_id].d_options[o_id].quest_step = nil
|
|
-- write it back to disc
|
|
yl_speak_up.save_dialog(n_id, dialog)
|
|
end
|
|
-- the player is working on the NPC - thus, the NPC may be in a modified stage
|
|
-- that hasn't been written to disc yet, and we need to adjust this stage as well
|
|
dialog = yl_speak_up.speak_to[pname].dialog
|
|
-- delete the connection
|
|
dialog.n_dialogs[d_id].d_options[o_id].quest_id = nil
|
|
dialog.n_dialogs[d_id].d_options[o_id].quest_step = nil
|
|
yl_speak_up.show_fs(player, "edit_option_dialog",
|
|
{n_id = n_id, d_id = d_id, o_id = o_id})
|
|
return
|
|
elseif(not(fields) or not(fields.save)) then
|
|
return
|
|
end
|
|
-- actually store the data
|
|
local error_msg = ""
|
|
-- check if the quest exists
|
|
local quest_list = yl_speak_up.get_sorted_quest_list(pname)
|
|
local idx = table.indexof(quest_list, fields.quest_id or "")
|
|
if(not(fields.quest_id) or fields.quest_id == "" or idx < 1) then
|
|
error_msg = "Quest not found."
|
|
elseif(not(fields.quest_step)
|
|
or string.len(fields.quest_step) < 1
|
|
or string.len(fields.quest_step) > 80) then
|
|
error_msg = "The name of the quest step has to be between\n"..
|
|
"1 and 80 characters long."
|
|
end
|
|
if(error_msg ~= "") then
|
|
yl_speak_up.show_fs(player, "msg", {
|
|
input_to = "yl_speak_up:assign_quest_step",
|
|
formspec = "size[9,2]"..
|
|
"label[0.2,0.5;Error: "..minetest.formspec_escape(error_msg).."]"..
|
|
"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
|
|
return
|
|
end
|
|
-- we identify quests by their var_name - not by their q_id
|
|
-- (makes it easier to transfer quests from one server to another later)
|
|
dialog.n_dialogs[d_id].d_options[o_id].quest_id = yl_speak_up.add_pname_to_var(fields.quest_id, pname)
|
|
dialog.n_dialogs[d_id].d_options[o_id].quest_step = fields.quest_step
|
|
if(not(yl_speak_up.npc_was_changed[ n_id ])) then
|
|
yl_speak_up.npc_was_changed[ n_id ] = {}
|
|
end
|
|
table.insert(yl_speak_up.npc_was_changed[ n_id ],
|
|
"Dialog "..d_id..": Option "..tostring(o_id)..
|
|
" has been set as quest step \""..
|
|
tostring(fields.quest_step).."\" for quest \""..tostring(fields.quest_id).."\".")
|
|
yl_speak_up.show_fs(player, "edit_option_dialog",
|
|
{n_id = n_id, d_id = d_id, o_id = o_id})
|
|
end
|
|
|
|
|
|
yl_speak_up.get_fs_assign_quest_step = function(player, param)
|
|
if(not(player)) then
|
|
return ""
|
|
end
|
|
local pname = player:get_player_name()
|
|
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 only works in edit mode
|
|
if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then
|
|
return "size[1,1]label[0,0;You cannot edit this NPC.]"
|
|
end
|
|
local dialog = yl_speak_up.speak_to[pname].dialog
|
|
if(not(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id))) then
|
|
return "size[4,1]label[0,0;Dialog option does not exist.]"
|
|
end
|
|
local d_option = dialog.n_dialogs[d_id].d_options[o_id]
|
|
local quest_id = d_option.quest_id or ""
|
|
local quest_step = d_option.quest_step or ""
|
|
local quest_show_until = d_option.quest_show_until or " - the player restarts the quest -"
|
|
if(quest_show_until == quest_step) then
|
|
quest_show_until = " - this quest step -"
|
|
-- players cannot create quest steps with leading blanks
|
|
elseif(quest_show_until == " next_step") then
|
|
quest_show_until = " - the quest step immediately following this one -"
|
|
end
|
|
|
|
-- has a quest been selected?
|
|
local q_id = yl_speak_up.get_quest_id_by_var_name(quest_id, pname)
|
|
if(not(q_id)) then
|
|
local npc_id = tonumber(string.sub(n_id, 3))
|
|
local quest_list = {}
|
|
for id, d in pairs(yl_speak_up.quests) do
|
|
if(table.indexof(d.npcs or {}, npc_id) ~= -1) then
|
|
table.insert(quest_list, minetest.formspec_escape(
|
|
tostring(id).." "..tostring(d.name)))
|
|
end
|
|
end
|
|
if(#quest_list < 1) then
|
|
return "size[14,4]"..
|
|
"label[4.0,0.5;Using this option/answer shall be a quest step.]"..
|
|
"label[0.2,1.4;"..
|
|
"This NPC "..tostring(n_id).." has not been added to a quest yet.\n"..
|
|
"Please add him to the NPC list of one of your quests first!\n"..
|
|
"Search the \"Edit\" button for \"NPC that (may) participate:\" "..
|
|
"while viewing the desired quest.]"..
|
|
"button[0.2,3.0;3.6,0.8;manage_quests;Manage Quests]"..
|
|
"button[9.5,3.0;4.0,0.8;back;Back to edit option "..tostring(o_id).."]"
|
|
end
|
|
local selected = 1
|
|
|
|
-- local quest_list = yl_speak_up.get_sorted_quest_list(pname)
|
|
-- for i, v in ipairs(quest_list) do
|
|
-- quest_list[i] = minetest.formspec_escape(v)
|
|
-- if(quest_id and v == quest_id) then
|
|
-- selected = i
|
|
-- end
|
|
-- end
|
|
return "size[14,4]"..
|
|
"label[4.0,0.5;Using this option/answer shall be a quest step.]"..
|
|
"label[0.2,1.4;Select a quest:]"..
|
|
"dropdown[4.0,1.0;9.5,0.8;select_quest_id;"..
|
|
table.concat(quest_list, ',')..";"..
|
|
tostring(selected)..",]"..
|
|
"label[0.2,2.1;If you want to use a quest not mentionned here or a new one, "..
|
|
"click on \"Manage Quests\"\n"..
|
|
"and search the \"Edit\" button for \"NPC that (may) participate:\".]"..
|
|
"button[0.2,3.0;3.6,0.8;manage_quests;Manage Quests]"..
|
|
"button[9.5,3.0;4.0,0.8;back;Back to edit option "..tostring(o_id).."]"
|
|
end
|
|
|
|
-- this is the currently relevant quest
|
|
yl_speak_up.speak_to[pname].q_id = q_id
|
|
yl_speak_up.speak_to[pname].quest_step = quest_step
|
|
local choose_until_step = {}
|
|
local show_until = ""
|
|
if(param and param == "change_show_until") then
|
|
local choose_until_step = yl_speak_up.get_choose_until_step_list(pname, q_id, quest_step)
|
|
local index = table.indexof(choose_until_step, quest_show_until or "")
|
|
if(index == -1) then
|
|
index = 1
|
|
end
|
|
show_until = "dropdown[3.0,5.1;10,0.5;select_show_until;"..
|
|
table.concat(choose_until_step, ",")..";"..tostring(index)..";]"..
|
|
"button[13.5,4.8;4.3,0.8;store_show_until;Store]"
|
|
else
|
|
show_until = "label[3.0,5.4;"..minetest.colorize("#AAFFAA",
|
|
minetest.formspec_escape(quest_show_until)).."]"..
|
|
"button[13.5,4.8;4.3,0.8;change_show_until;Edit]"
|
|
end
|
|
local formspec = {
|
|
"size[18,7]"..
|
|
"label[3.0,0.5;Using this option/answer shall be a quest step.]"..
|
|
"label[0.2,1.4;Quest ID:]"..
|
|
"label[0.2,1.9;Quest name:]"..
|
|
"label[0.2,3.4;quest step:]"..
|
|
"button[13.5,3.1;4.3,0.8;show_step;Show this quest step]"..
|
|
"label[0.2,3.9;"..
|
|
"This quest step will be set for the player after the effects of "..
|
|
"the dialog option are executed.]"..
|
|
|
|
"label[0.2,4.9;"..
|
|
"This dialog option will be shown until the player has reached the "..
|
|
"following quest step:]"..
|
|
"button[0.2,0.2;2.0,0.8;delete_assignment;Delete]"..
|
|
"tooltip[delete_assignment;"..
|
|
"Delete the assignment of this quest step to this dialog option.\n"..
|
|
"Neither the quest step nor the dialog option will be deleted.\n"..
|
|
"Just their connection. Afterwards, you can assign a new or\n"..
|
|
"diffrent quest step to the dialog option.]"..
|
|
"button[13.5,6.0;4.3,0.8;manage_quests;Manage quests]"
|
|
}
|
|
table.insert(formspec, "label[3.0,1.4;")
|
|
table.insert(formspec, minetest.formspec_escape(q_id))
|
|
table.insert(formspec, "]")
|
|
table.insert(formspec, "label[3.0,1.9;")
|
|
table.insert(formspec, minetest.formspec_escape(yl_speak_up.quests[q_id].name or "- ? -"))
|
|
table.insert(formspec, "]")
|
|
table.insert(formspec, "button[13.5,1.0;4.3,0.8;show_quest;Show this quest ")
|
|
table.insert(formspec, tostring(q_id))
|
|
table.insert(formspec, "]")
|
|
table.insert(formspec, "label[0.2,2.9;This option here (")
|
|
table.insert(formspec, tostring(o_id))
|
|
table.insert(formspec, ") will be available once the player has reached all required ".. "quest steps for the following]")
|
|
table.insert(formspec, "label[3.0,3.4;")
|
|
table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(quest_step)))
|
|
table.insert(formspec, "]")
|
|
table.insert(formspec, "button[6.0,6.0;6.0,0.8;back;Back to edit option ")
|
|
table.insert(formspec, tostring(o_id))
|
|
table.insert(formspec, "]")
|
|
table.insert(formspec, show_until)
|
|
return table.concat(formspec, " ")
|
|
end
|
|
|
|
|
|
yl_speak_up.register_fs("assign_quest_step",
|
|
yl_speak_up.input_fs_assign_quest_step,
|
|
yl_speak_up.get_fs_assign_quest_step,
|
|
-- no special formspec required:
|
|
nil
|
|
)
|