forked from your-land-mirror/yl_speak_up
added basic quest management formspec
This commit is contained in:
parent
3f458bf448
commit
8b24e9b52f
79
fs_manage_quests.lua
Normal file
79
fs_manage_quests.lua
Normal file
@ -0,0 +1,79 @@
|
||||
-- helper functions for yl_speak_up.input_fs_manage_quests(..)
|
||||
-- returns the index of the new quest
|
||||
yl_speak_up.input_fs_manage_quests_add_new_entry = function(pname, entry_name)
|
||||
local res = yl_speak_up.add_quest(pname, entry_name,
|
||||
"Name of your quest",
|
||||
"Enter a longer description here for describing the quest "..
|
||||
"to players who search for one.",
|
||||
"Enter a short description here describing what the quest is about.",
|
||||
"Room for comments/notes")
|
||||
-- TODO: might make sense to show the error message somewhere
|
||||
if(res ~= "OK") then
|
||||
return -1
|
||||
end
|
||||
local quest_list = yl_speak_up.get_sorted_quest_list(pname)
|
||||
return table.indexof(quest_list, entry_name)
|
||||
end
|
||||
|
||||
-- helper functions for yl_speak_up.input_fs_manage_quests(..)
|
||||
-- returns a text describing if deleting the quest worked
|
||||
yl_speak_up.input_fs_manage_quests_del_old_entry = function(pname, entry_name)
|
||||
return "NOT IMPLEMENTED YET"
|
||||
-- delete (empty) variable
|
||||
-- return yl_speak_up.del_quest_variable(pname, entry_name, nil)
|
||||
end
|
||||
|
||||
-- helper functions for yl_speak_up.input_fs_manage_quests(..)
|
||||
-- implements all the functions that are specific to managing quests and not part of
|
||||
-- general item management
|
||||
yl_speak_up.input_fs_manage_quests_check_fields = function(player, formname, fields, quest_name, list_of_entries)
|
||||
local pname = player:get_player_name()
|
||||
if(not(quest_name)) then
|
||||
quest_name = ""
|
||||
end
|
||||
-- this function didn't have anything to do
|
||||
return "NOTHING FOUND"
|
||||
end
|
||||
|
||||
|
||||
-- makes use of yl_speak_up.input_fs_manage_general and is thus pretty short
|
||||
yl_speak_up.input_fs_manage_quests = function(player, formname, fields)
|
||||
local pname = player:get_player_name()
|
||||
local quest_list = yl_speak_up.get_sorted_quest_list(pname)
|
||||
local res = yl_speak_up.input_fs_manage_general(player, formname, fields,
|
||||
-- what_is_the_list_about, min_length, max_length, function_add_new_entry,
|
||||
"quest", 2, 80,
|
||||
yl_speak_up.input_fs_manage_quests_add_new_entry,
|
||||
quest_list,
|
||||
yl_speak_up.input_fs_manage_quests_del_old_entry,
|
||||
yl_speak_up.input_fs_manage_quests_check_fields)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
yl_speak_up.get_fs_manage_quests = function(player, param)
|
||||
local pname = player:get_player_name()
|
||||
local quest_list = yl_speak_up.get_sorted_quest_list(pname)
|
||||
local formspec = {}
|
||||
table.insert(formspec, "size[18,12]"..
|
||||
"label[0.2,1.2;A quest is a linear sequence of quest steps. Quests can "..
|
||||
"depend on and influence other quests.\n"..
|
||||
"Progress for each player is stored in a variable. The name of "..
|
||||
"that variable cannot be changed after creation.]")
|
||||
local selected = yl_speak_up.get_fs_manage_general(player, param,
|
||||
formspec, quest_list,
|
||||
"Create quest",
|
||||
"Create a new varialbe with the name\n"..
|
||||
"you entered in the field to the left.",
|
||||
"quest",
|
||||
"Enter the name of the new quest you want to create.\n"..
|
||||
"You can't change this name afterwards. But you *can*\n"..
|
||||
"add and change a human readable description later on.",
|
||||
"If you click here, the selected quest will be deleted.\n"..
|
||||
"This will only be possible if it's not used anywhere.")
|
||||
if(selected and selected ~= "") then
|
||||
local k = selected
|
||||
-- index 1 is "Add variable:"
|
||||
end
|
||||
return table.concat(formspec, "")
|
||||
end
|
@ -14,6 +14,10 @@ yl_speak_up.input_quest_gui = function(player, formname, fields)
|
||||
yl_speak_up.speak_to[pname][ "working_at" ] = "quest_gui"
|
||||
yl_speak_up.show_fs(player, "manage_variables")
|
||||
return ret
|
||||
elseif(fields.manage_quests) then
|
||||
yl_speak_up.speak_to[pname][ "working_at" ] = "quest_gui"
|
||||
yl_speak_up.show_fs(player, "manage_quests")
|
||||
return ret
|
||||
end
|
||||
-- the calling NPC shall no longer do anything
|
||||
return ret
|
||||
@ -22,8 +26,8 @@ end
|
||||
|
||||
yl_speak_up.get_fs_quest_gui = function(player, param)
|
||||
local pname = player:get_player_name()
|
||||
|
||||
return "size[10,2]"..
|
||||
return "size[24,20]"..
|
||||
"label[0,0.5;Hi. This is a quest admin gui.]"..
|
||||
"button[0.2,1.0;4.0,0.6;manage_variables;Manage variables]"
|
||||
"button[0.2,1.0;4.0,0.6;manage_variables;Manage variables]"..
|
||||
"button[6.2,1.0;4.0,0.6;manage_quests;Manage quests]"
|
||||
end
|
||||
|
2
init.lua
2
init.lua
@ -118,6 +118,8 @@ yl_speak_up.reload = function(modpath, log_entry)
|
||||
dofile(modpath .. "fs_manage_variables.lua")
|
||||
-- handle variables for quests for player-owned NPC
|
||||
dofile(modpath .. "quest_api.lua")
|
||||
-- GUI for adding/editing quests
|
||||
dofile(modpath .. "fs_manage_quests.lua")
|
||||
-- setting skin, wielded item etc.
|
||||
dofile(modpath .. "fs_fashion.lua")
|
||||
-- properties for NPC without specific dialogs that want to make use of
|
||||
|
188
quest_api.lua
188
quest_api.lua
@ -524,3 +524,191 @@ end
|
||||
yl_speak_up.get_time_in_seconds = function()
|
||||
return math.floor(minetest.get_us_time()/1000000)
|
||||
end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Quests as such (up until here we mostly dealt with variables)
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-- uses yl_speak_up.quest_path
|
||||
-- uses yl_speak_up.number_of_quests = yl_speak_up.modstorage:get_int("max_quest_id") or 0
|
||||
|
||||
-- table containing the quest data with q_id as index
|
||||
yl_speak_up.quests = {}
|
||||
|
||||
|
||||
-- store quest q_id to disc
|
||||
yl_speak_up.save_quest = function(q_id)
|
||||
local json = minetest.write_json(yl_speak_up.quests[q_id])
|
||||
-- actually store it on disk
|
||||
local file_name = yl_speak_up.worldpath..yl_speak_up.quest_path..DIR_DELIM..q_id..".json"
|
||||
minetest.safe_file_write(file_name, json)
|
||||
end
|
||||
|
||||
|
||||
-- read quest q_id from disc
|
||||
yl_speak_up.load_quest = function(q_id)
|
||||
-- load the data from the file
|
||||
local file_name = yl_speak_up.worldpath..yl_speak_up.quest_path..DIR_DELIM..q_id..".json"
|
||||
local file, err = io.open(file_name, "r")
|
||||
if err then
|
||||
return
|
||||
end
|
||||
io.input(file)
|
||||
local text = io.read()
|
||||
-- all values saved in the tables as such are strings
|
||||
local data = minetest.parse_json(text, "$NIL_VALUE$")
|
||||
io.close(file)
|
||||
|
||||
if(type(data) ~= "table") then
|
||||
return
|
||||
end
|
||||
for k,v in pairs(data) do
|
||||
if(v == "$NIL_VALUE$") then
|
||||
data[ k ] = {}
|
||||
end
|
||||
end
|
||||
yl_speak_up.quests[q_id] = data
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- get data of quest q_id
|
||||
yl_speak_up.get_quest = function(q_id)
|
||||
if(not(yl_speak_up.quests[q_id])) then
|
||||
load_quest(q_id)
|
||||
end
|
||||
return yl_speak_up.quests[q_id]
|
||||
end
|
||||
|
||||
|
||||
-- add/create a new quest
|
||||
-- a quest is based on a variable; the variable is needed to store quest progress;
|
||||
-- as this variable is of type integer, quests can only be linear;
|
||||
-- in order to offer alternatives, players can add as many quests as they want and
|
||||
-- make them depend on each other
|
||||
yl_speak_up.add_quest = function(owner_name, variable_name, quest_name, descr_long, descr_short, comment)
|
||||
-- add a special variable (if needed) for saving quest meta data
|
||||
if(not(yl_speak_up.player_vars[ "$QUEST_META_DATA$" ])) then
|
||||
yl_speak_up.player_vars[ "$QUEST_META_DATA$" ] = {}
|
||||
yl_speak_up.save_quest_variables(true)
|
||||
end
|
||||
|
||||
if(not(variable_name) or variable_name == "") then
|
||||
return "Missing name of variable."
|
||||
end
|
||||
-- determine the full name of the variable used to store quest progress
|
||||
local var_name = yl_speak_up.add_pname_to_var(variable_name, owner_name)
|
||||
-- if it is a new variable: make sure it gets created
|
||||
if(not(yl_speak_up.player_vars[var_name])) then
|
||||
-- create the new varialbe
|
||||
yl_speak_up.add_quest_variable(owner_name, variable_name)
|
||||
else
|
||||
-- if it exists already: make sure it is of a type that can be used
|
||||
local var_type = yl_speak_up.get_variable_metadata(var_name, "var_type")
|
||||
if("var_type" == "time_based") then
|
||||
return "Variable already used as a timer."
|
||||
elseif("var_type" == "quest") then
|
||||
return "Variable already used by another quest."
|
||||
end
|
||||
end
|
||||
-- set the variable for the quest creator to 0 - so that it's possible to check for
|
||||
-- var_name is set (to a value) in a precondition and thus only allow the quest creator
|
||||
-- to test the quest in the beginning
|
||||
yl_speak_up.set_quest_variable_value(owner_name, var_name, 0)
|
||||
-- set the variable type to quest
|
||||
yl_speak_up.set_variable_metadata(var_name, owner_name, "var_type", nil, "quest")
|
||||
-- get a uniq ID for storing this quest (mostly needed for creating a safe file name)
|
||||
local quest_nr = yl_speak_up.number_of_quests + 1
|
||||
yl_speak_up.number_of_quests = quest_nr
|
||||
yl_speak_up.modstorage:set_int("max_quest_nr", yl_speak_up.number_of_quests)
|
||||
-- store this number in the variable $META$ data
|
||||
yl_speak_up.set_variable_metadata(var_name, owner_name, "quest_data", "quest_nr", quest_nr)
|
||||
-- the list of quest steps is stored in the variables' metadata for quicker access
|
||||
-- (this way we won't have to load the quest file if we want to check a precondition
|
||||
-- or update the variable value to the next quest step)
|
||||
yl_speak_up.set_variable_metadata(var_name, owner_name, "quest_data", "steps", {"start","finish"})
|
||||
|
||||
-- create the quest data structure
|
||||
local quest = {}
|
||||
quest.nr = quest_nr
|
||||
quest.id = "q_"..quest_nr -- quest ID
|
||||
quest.name = quest_name -- human-readable name of the quest
|
||||
quest.description = (descr_long or "")
|
||||
-- long description of what the quest is about
|
||||
quest.short_desc = (descr_short or "")
|
||||
-- a short description of this quest which may later be used to
|
||||
-- advertise for the quest in a quest log
|
||||
quest.comment = (comment or "")
|
||||
-- comment to other programmers who might want to maintain the
|
||||
-- quest later on
|
||||
quest.owner = owner_name -- creator of the quest
|
||||
quest.var_name = var_name -- name of the variable where progress is stored for each player
|
||||
-- quest.steps = { -- list of names (strings) of the quest steps
|
||||
-- "start", -- the quest needs to start somehow
|
||||
-- "finish"} -- and it needs to finish somehow
|
||||
-- the following things can be determined automaticly, BUT: in order to PLAN a future
|
||||
-- quest, it is easier to gather information here first
|
||||
quest.step_data = {} -- table containing information about a quest step (=key)
|
||||
-- this may also be information about WHERE a quest step shall
|
||||
-- take place
|
||||
quest.subquests = {} -- list of other quest_ids that contribute to this quest
|
||||
-- -> determined from quests.npcs and quests.locations
|
||||
quest.is_subquest_of = {} -- list of quest_ids this quest contributes to
|
||||
-- -> determined from quests.npcs and quests.locations
|
||||
quest.npcs = {} -- list of NPC that contribute to this quest
|
||||
-- -> derived from quest.var_name
|
||||
quest.locations = {} -- list of locations that contribute to this quest
|
||||
-- -> derived from quest.var_name
|
||||
quest.items = {} -- data of quest items created and accepted
|
||||
-- -> derived from the quest steps
|
||||
quest.rewards = {} -- list of rewards (item stacks) for this ques
|
||||
quest.testers = {} -- list of player names that can test the quest
|
||||
-- -> during the created/testing phase: any player for which
|
||||
-- quest.var_name is set to a value
|
||||
quest.solved_by = {} -- list of names of players that solved the quest at least once
|
||||
quest.state = "created" -- state of the quest:
|
||||
-- created: only the creator can do it
|
||||
-- testing: players listed in quest.testers can do the quest
|
||||
-- open: *all* players with interact can try to solve the quest
|
||||
-- *AND* changes to the quest are now impossible (apart from
|
||||
-- changing texts in the NPC)
|
||||
-- official: official server quest; NPC can create items out of thin air
|
||||
-- store the new quest in the quest table
|
||||
yl_speak_up.quests[quest.id] = quest
|
||||
-- and store it on disc
|
||||
yl_speak_up.save_quest(quest.id)
|
||||
return "OK"
|
||||
end
|
||||
|
||||
|
||||
-- returns a list of all quest IDs to which the player has write access
|
||||
yl_speak_up.get_quest_owner_list = function(pname)
|
||||
local var_list = yl_speak_up.get_quest_variables_with_write_access(pname)
|
||||
local quest_id_list = {}
|
||||
for i, var_name in ipairs(var_list) do
|
||||
local t = yl_speak_up.get_variable_metadata(var_name, "var_type")
|
||||
if(t and t == "quest") then
|
||||
local data = yl_speak_up.get_variable_metadata(var_name, "quest_data", true)
|
||||
if(data and data["quest_nr"]) then
|
||||
table.insert(quest_id_list, "q_"..tostring(data["quest_nr"]))
|
||||
end
|
||||
end
|
||||
end
|
||||
return quest_id_list
|
||||
end
|
||||
|
||||
|
||||
yl_speak_up.get_sorted_quest_list = function(pname)
|
||||
local var_list = yl_speak_up.get_quest_variables_with_write_access(pname)
|
||||
local quest_list = {}
|
||||
for i, var_name in ipairs(var_list) do
|
||||
local t = yl_speak_up.get_variable_metadata(var_name, "var_type")
|
||||
if(t and t == "quest") then
|
||||
table.insert(quest_list, var_name)
|
||||
end
|
||||
end
|
||||
yl_speak_up.strip_pname_from_varlist(quest_list, pname)
|
||||
table.sort(quest_list)
|
||||
return quest_list
|
||||
end
|
||||
|
10
show_fs.lua
10
show_fs.lua
@ -92,10 +92,14 @@ yl_speak_up.input_handler = 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
|
||||
-- handled in fs_manage_variables.lua
|
||||
elseif formname == "yl_speak_up:manage_variables" then
|
||||
yl_speak_up.input_fs_manage_variables(player, formname, fields)
|
||||
return true
|
||||
-- handled in fs_manage_quests.lua
|
||||
elseif formname == "yl_speak_up:manage_quests" then
|
||||
yl_speak_up.input_fs_manage_quests(player, formname, fields)
|
||||
return true
|
||||
-- handled in fs_alternate_text.lua
|
||||
elseif formname == "yl_speak_up:show_what_points_to_this_dialog" then
|
||||
yl_speak_up.input_fs_show_what_points_to_this_dialog(player, formname, fields)
|
||||
@ -386,6 +390,10 @@ yl_speak_up.show_fs = function(player, fs_name, param)
|
||||
yl_speak_up.show_fs_ver(pname, "yl_speak_up:manage_variables",
|
||||
yl_speak_up.get_fs_manage_variables(player, param))
|
||||
|
||||
elseif(fs_name == "manage_quests") then
|
||||
yl_speak_up.show_fs_ver(pname, "yl_speak_up:manage_quests",
|
||||
yl_speak_up.get_fs_manage_quests(player, param))
|
||||
|
||||
elseif(fs_name == "show_what_points_to_this_dialog") then
|
||||
yl_speak_up.show_fs_ver(pname, "yl_speak_up:show_what_points_to_this_dialog",
|
||||
yl_speak_up.show_what_points_to_this_dialog(player, param))
|
||||
|
Loading…
Reference in New Issue
Block a user