Make tasked quests work with HUD
This commit is contained in:
parent
fb8f4fbc51
commit
a3328d9fb5
84
core.lua
84
core.lua
@ -136,6 +136,12 @@ end
|
||||
-- In this previous example the 2 last tasks enables once the `start` one is completed, and the
|
||||
-- last one disables upon `another_task` completion, effectively making it optional if one
|
||||
-- completes `another_task` before it.
|
||||
-- Some task names are reserved and will be ignored:
|
||||
--
|
||||
-- * `metadata`
|
||||
-- * `finished`
|
||||
-- * `value`
|
||||
--
|
||||
-- Note: this function *copies* the `quest` table, keeping only what's needed. This way you can implement custom
|
||||
-- quest attributes in your mod and register the quest directly without worrying about keyvalue name collision.
|
||||
-- @param questname Name of the quest. Should follow the naming conventions: `modname:questname`
|
||||
@ -151,7 +157,7 @@ function quests.register_quest(questname, quest)
|
||||
description = quest.description or S("missing description"),
|
||||
icon = quest.icon or "quests_default_quest_icon.png",
|
||||
startcallback = quest.startcallback or empty_callback,
|
||||
autoaccept = quest.autoaccept or true,
|
||||
autoaccept = not(quest.autoaccept == false),
|
||||
completecallback = quest.completecallback or empty_callback,
|
||||
abortcallback = quest.abortcallback or empty_callback,
|
||||
repeating = quest.repeating or 0
|
||||
@ -168,6 +174,7 @@ function quests.register_quest(questname, quest)
|
||||
new_quest.tasks = {}
|
||||
local tcount = 0
|
||||
for tname, task in pairs(quest.tasks) do
|
||||
if tname ~= "metadata" and tname ~= "finished" and tname ~= "value" then
|
||||
new_quest.tasks[tname] = {
|
||||
title = task.title or S("missing title"),
|
||||
description = task.description or S("missing description"),
|
||||
@ -181,6 +188,7 @@ function quests.register_quest(questname, quest)
|
||||
}
|
||||
tcount = tcount + 1
|
||||
end
|
||||
end
|
||||
if tcount == 0 then -- No tasks!
|
||||
quests.registered_quests[questname] = nil
|
||||
return false
|
||||
@ -218,8 +226,8 @@ function quests.start_quest(playername, questname, metadata)
|
||||
finished = false
|
||||
}
|
||||
end
|
||||
end
|
||||
compute_tasks(playername, questname)
|
||||
end
|
||||
|
||||
quests.update_hud(playername)
|
||||
quests.show_message("new", playername, S("New quest:") .. " " .. quest.title)
|
||||
@ -280,6 +288,23 @@ function quests.update_quest(playername, questname, value)
|
||||
return false -- the quest continues
|
||||
end
|
||||
|
||||
--- Get a *simple* quest's progress.
|
||||
-- @param playername Name of the player
|
||||
-- @param questname Quest to get the progress value from
|
||||
-- @return `number` of the progress
|
||||
-- @return `nil` if there is no such quest, it is a tasked or non-active one
|
||||
-- @see quests.get_task_progress
|
||||
function quests.get_quest_progress(playername, questname)
|
||||
if not check_active_quest(playername, questname) or not quests.registered_quests[questname].simple then
|
||||
return nil
|
||||
end
|
||||
local plr_quest = quests.active_quests[playername][questname]
|
||||
if plr_quest.finished then
|
||||
return nil
|
||||
end
|
||||
return plr_quest.value
|
||||
end
|
||||
|
||||
--- Updates a *tasked* quest task's status.
|
||||
-- Calls the quest's `completecallback` if autoaccept is `true` and all the quest's visible
|
||||
-- and non-disabled tasks reaches their max value.
|
||||
@ -336,6 +361,33 @@ function quests.update_quest_task(playername, questname, taskname, value)
|
||||
return task_finished
|
||||
end
|
||||
|
||||
--- Get a task's progress.
|
||||
-- Returns the max progress value possible for the given task if it is complete.
|
||||
-- @param playername Name of the player
|
||||
-- @param questname Quest the task belongs to
|
||||
-- @param taskname Task to get the progress value from
|
||||
-- @return `number` of the progress
|
||||
-- @return `false` if the task has been disabled by another
|
||||
-- @return `nil` if there is no such quest/task, or is a simple or non-active quest
|
||||
-- @see quests.get_quest_progress
|
||||
function quests.get_task_progress(playername, questname, taskname)
|
||||
if not not check_active_quest_task(playername, questname, taskname) then
|
||||
return nil
|
||||
end
|
||||
local plr_quest = quests.active_quests[playername][questname]
|
||||
if plr_quest.finished then
|
||||
return nil
|
||||
end
|
||||
local plr_task = plr_quest[taskname]
|
||||
if not plr_task then
|
||||
return nil
|
||||
end
|
||||
if plr_task.disabled then
|
||||
return false
|
||||
end
|
||||
return plr_task.value
|
||||
end
|
||||
|
||||
--- Checks if a quest's task is visible to the player.
|
||||
-- @param playername Name of the player
|
||||
-- @param questname Quest which contains the task
|
||||
@ -517,6 +569,34 @@ function quests.abort_quest(playername, questname)
|
||||
return true
|
||||
end
|
||||
|
||||
--- Set quest HUD visibility.
|
||||
-- @param playername Player's name
|
||||
-- @param questname Quest name
|
||||
-- @param visible `bool` indicating if the quest should be visible
|
||||
-- @see quests.get_quest_hud_visibility
|
||||
function quests.set_quest_hud_visibility(playername, questname, visible)
|
||||
if not check_active_quest(playername, questname) then
|
||||
return
|
||||
end
|
||||
quests.info_quests[playername] = quests.info_quests[playername] or {}
|
||||
quests.info_quests[playername][questname] = quests.info_quests[playername][questname] or {}
|
||||
quests.info_quests[playername][questname].hide_from_hud = not visible
|
||||
quests.update_hud(playername)
|
||||
end
|
||||
|
||||
--- Get quest HUD visibility.
|
||||
-- @param playername Player's name
|
||||
-- @param questname Quest name
|
||||
-- @return `bool`: quest HUD visibility
|
||||
-- @see quests.set_quest_hud_visibility
|
||||
function quests.get_quest_hud_visibility(playername, questname)
|
||||
if not check_active_quest(playername, questname) then
|
||||
return false
|
||||
end
|
||||
local plr_qinfos = quests.info_quests[playername]
|
||||
return not(plr_qinfos and plr_qinfos[questname] and plr_qinfos[questname].hide_from_hud)
|
||||
end
|
||||
|
||||
--- Get quest metadata.
|
||||
-- @return Metadata of the quest, `nil` if there is none
|
||||
-- @return `nil, false` if the quest doesn't exist or isn't active
|
||||
|
@ -7,13 +7,13 @@ else
|
||||
S = function(s) return s end
|
||||
end
|
||||
|
||||
|
||||
-- construct the questlog
|
||||
function quests.create_formspec(playername, tab, integrated)
|
||||
local queststringlist = {}
|
||||
local questlist = {}
|
||||
quests.formspec_lists[playername] = quests.formspec_lists[playername] or {}
|
||||
quests.formspec_lists[playername].id = 1
|
||||
quests.formspec_lists[playername] = quests.formspec_lists[playername] or {
|
||||
id = 1
|
||||
}
|
||||
quests.formspec_lists[playername].list = {}
|
||||
tab = tab or quests.formspec_lists[playername].tab or "1"
|
||||
if tab == "1" then
|
||||
@ -25,8 +25,8 @@ function quests.create_formspec(playername, tab, integrated)
|
||||
end
|
||||
quests.formspec_lists[playername].tab = tab
|
||||
|
||||
local no_quests = true
|
||||
for questname,questspecs in pairs(questlist) do
|
||||
local quest_count = 0
|
||||
for questname,questspecs in quests.sorted_pairs(questlist) do
|
||||
if not questspecs.finished then
|
||||
local quest = quests.registered_quests[questname]
|
||||
if quest then -- Quest might have been deleted
|
||||
@ -54,23 +54,33 @@ function quests.create_formspec(playername, tab, integrated)
|
||||
end
|
||||
table.insert(queststringlist, queststring)
|
||||
table.insert(quests.formspec_lists[playername].list, questname)
|
||||
no_quests = false
|
||||
quest_count = quest_count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
if quest_count ~= 0 and quests.formspec_lists[playername].id > quest_count then
|
||||
quests.formspec_lists[playername].id = quest_count
|
||||
end
|
||||
local formspec = ""
|
||||
if not integrated then
|
||||
formspec = formspec .. "size[7,9]"
|
||||
end
|
||||
formspec = formspec .. "tabheader[0,0;quests_header;" .. S("Open quests") .. "," .. S("Finished quests") .. "," .. S("Failed quests") .. ";" .. tab .. "]"
|
||||
if no_quests then
|
||||
if quest_count == 0 then
|
||||
formspec = formspec .. "label[0.25,0.25;" .. S("There are no quests in this category.") .. "]"
|
||||
else
|
||||
formspec = formspec .. "textlist[0.25,0.25;6.5,6;quests_questlist;"..table.concat(queststringlist, ",") .. ";1;false]"
|
||||
formspec = formspec .. "textlist[0.25,0.25;6.5,6;quests_questlist;"..table.concat(queststringlist, ",") .. ";" .. tostring(quests.formspec_lists[playername].id) .. ";false]"
|
||||
end
|
||||
if quests.formspec_lists[playername].tab == "1" then
|
||||
local hud_display = "true"
|
||||
if quests.formspec_lists[playername].id then
|
||||
local questname = quests.formspec_lists[playername].list[quests.formspec_lists[playername].id]
|
||||
if not quests.get_quest_hud_visibility(playername, questname) then
|
||||
hud_display = "false"
|
||||
end
|
||||
end
|
||||
formspec = formspec .."button[0.25,7.1;3,.7;quests_abort;" .. S("Abort quest") .. "]" ..
|
||||
"checkbox[.25,6.2;quests_show_quest_in_hud;" .. S("Show in HUD") .. ";" .. "false" .. "]"
|
||||
"checkbox[.25,6.2;quests_show_quest_in_hud;" .. S("Show in HUD") .. ";" .. hud_display .. "]"
|
||||
end
|
||||
formspec = formspec .. "button[3.75,7.1;3,.7;quests_config;" .. S("Configure") .. "]"..
|
||||
"button[.25,8;3,.7;quests_info;" .. S("Info") .. "]"..
|
||||
@ -248,37 +258,53 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
end
|
||||
return
|
||||
end
|
||||
if (fields["quests_questlist"]) then
|
||||
local event = minetest.explode_textlist_event(fields["quests_questlist"])
|
||||
if (event.type == "CHG") then
|
||||
if fields.quests_questlist then
|
||||
local event = minetest.explode_textlist_event(fields.quests_questlist)
|
||||
if event.type == "CHG" then
|
||||
quests.formspec_lists[playername].id = event.index
|
||||
end
|
||||
end
|
||||
if (fields["quests_abort"]) then
|
||||
if (quests.formspec_lists[playername].id == nil) then
|
||||
return
|
||||
end
|
||||
quests.abort_quest(playername, quests.formspec_lists[playername]["list"][quests.formspec_lists[playername].id])
|
||||
if (formname == "quests:questlog") then
|
||||
if formname == "quests:questlog" then
|
||||
minetest.show_formspec(playername, "quests:questlog", quests.create_formspec(playername))
|
||||
else
|
||||
unified_inventory.set_inventory_formspec(player, "quests")
|
||||
end
|
||||
end
|
||||
if (fields["quests_config"]) then
|
||||
if (formname == "quests:questlog") then
|
||||
end
|
||||
if fields.quests_abort then
|
||||
if quests.formspec_lists[playername].id == nil then
|
||||
return
|
||||
end
|
||||
quests.abort_quest(playername, quests.formspec_lists[playername].list[quests.formspec_lists[playername].id])
|
||||
if formname == "quests:questlog" then
|
||||
minetest.show_formspec(playername, "quests:questlog", quests.create_formspec(playername))
|
||||
else
|
||||
unified_inventory.set_inventory_formspec(player, "quests")
|
||||
end
|
||||
end
|
||||
if fields.quests_config then
|
||||
if formname == "quests:questlog" then
|
||||
minetest.show_formspec(playername, "quests:config", quests.create_config(playername))
|
||||
else
|
||||
unified_inventory.set_inventory_formspec(player, "quests_config")
|
||||
end
|
||||
end
|
||||
if (fields["quests_info"]) then
|
||||
if (formname == "quests:questlog") then
|
||||
if fields.quests_info then
|
||||
if formname == "quests:questlog" then
|
||||
minetest.show_formspec(playername, "quests:info", quests.create_info(playername, quests.formspec_lists[playername].list[quests.formspec_lists[playername].id], nil, false))
|
||||
else
|
||||
unified_inventory.set_inventory_formspec(player, "quests_info")
|
||||
end
|
||||
end
|
||||
if fields.quests_show_quest_in_hud ~= nil then
|
||||
local questname = quests.formspec_lists[playername].list[quests.formspec_lists[playername].id]
|
||||
if questname then
|
||||
quests.set_quest_hud_visibility(playername, questname, fields.quests_show_quest_in_hud == "true")
|
||||
if formname == "quests:questlog" then
|
||||
minetest.show_formspec(playername, "quests:questlog", quests.create_formspec(playername))
|
||||
else
|
||||
unified_inventory.set_inventory_formspec(player, "quests")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- config
|
||||
if (fields["quests_config_enable"]) then
|
||||
|
306
hud.lua
306
hud.lua
@ -17,32 +17,30 @@ local hud_config = { position = {x = 1, y = 0.2},
|
||||
number = quests.colors.new }
|
||||
|
||||
--- Show quests HUD to player.
|
||||
-- The HUD can only show up to show_max quests
|
||||
-- The HUD can only show up to `show_max` quests
|
||||
-- @param playername Player whose quests HUD must be shown
|
||||
-- @param autohide Whether to automatically hide the HUD once it's empty
|
||||
function quests.show_hud(playername, autohide)
|
||||
if (quests.hud[playername] == nil) then
|
||||
quests.hud[playername] = { autohide = autohide}
|
||||
if quests.hud[playername] == nil then
|
||||
quests.hud[playername] = { autohide = autohide }
|
||||
end
|
||||
if (quests.hud[playername].list ~= nil) then
|
||||
if quests.hud[playername].list ~= nil then
|
||||
return
|
||||
end
|
||||
local hud = {
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if player == nil then
|
||||
return false
|
||||
end
|
||||
quests.hud[playername].header = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
alignment = {x=1, y=1},
|
||||
position = {x = hud_config.position.x, y = hud_config.position.y},
|
||||
offset = {x = hud_config.offset.x, y = hud_config.offset.y},
|
||||
offset = {x = hud_config.offset.x, y = hud_config.offset.y - 20},
|
||||
number = hud_config.number,
|
||||
text = S("Quests:") }
|
||||
text = S("Quests:")
|
||||
})
|
||||
|
||||
|
||||
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if (player == nil) then
|
||||
return false
|
||||
end
|
||||
quests.hud[playername].list = {}
|
||||
table.insert(quests.hud[playername].list, { value=0, id=player:hud_add(hud) })
|
||||
minetest.after(0, quests.update_hud, playername)
|
||||
end
|
||||
|
||||
@ -50,7 +48,7 @@ end
|
||||
-- @param playername Player whose quests HUD must be hidden
|
||||
function quests.hide_hud(playername)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if (player == nil or quests.hud[playername] == nil or quests.hud[playername].list == nil) then
|
||||
if player == nil or quests.hud[playername] == nil or quests.hud[playername].list == nil then
|
||||
return
|
||||
end
|
||||
for _,quest in pairs(quests.hud[playername].list) do
|
||||
@ -66,145 +64,203 @@ function quests.hide_hud(playername)
|
||||
end
|
||||
|
||||
|
||||
local function get_quest_hud_string(questname, quest)
|
||||
local quest_string = quests.registered_quests[questname].title
|
||||
if quest.simple and quests.registered_quests[questname].max ~= 1 then
|
||||
quest_string = quest_string .. "\n ("..quests.round(quest.value, 2).."/"..quests.registered_quests[questname].max..")"
|
||||
else
|
||||
quest_string = quest_string .. "\n (...)"
|
||||
end
|
||||
return quest_string
|
||||
local function get_quest_hud_string(title, value, max)
|
||||
return title .. "\n ("..quests.round(value, 2).."/"..max..")"
|
||||
end
|
||||
|
||||
-- only for internal use
|
||||
-- updates the hud
|
||||
function quests.update_hud(playername)
|
||||
if (quests.hud[playername] == nil or quests.active_quests[playername] == nil) then
|
||||
return
|
||||
end
|
||||
if (quests.hud[playername].list == nil) then
|
||||
if (quests.hud[playername].autohide and next(quests.active_quests[playername]) ~= nil) then
|
||||
quests.show_hud(playername)
|
||||
end
|
||||
return
|
||||
end
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if (player == nil) then
|
||||
return
|
||||
end
|
||||
|
||||
-- Check for changes in the hud
|
||||
local i = 2 -- the first element is the title
|
||||
local change = false
|
||||
local visible = {}
|
||||
local remove = {}
|
||||
for j,hud_element in ipairs(quests.hud[playername].list) do
|
||||
if (hud_element.name ~= nil) then
|
||||
if (quests.active_quests[playername][hud_element.name] ~= nil) then
|
||||
if (hud_element.value ~= quests.active_quests[playername][hud_element.name].value) then
|
||||
hud_element.value = quests.active_quests[playername][hud_element.name].value
|
||||
player:hud_change(hud_element.id, "text", get_quest_hud_string(hud_element.name, quests.active_quests[playername][hud_element.name]))
|
||||
if (hud_element.id_bar ~= nil) then
|
||||
player:hud_change(hud_element.id_bar, "scale",
|
||||
{ x = math.floor(20 * hud_element.value / quests.registered_quests[hud_element.name].max),
|
||||
y = 1})
|
||||
end
|
||||
end
|
||||
if (i ~= j) then
|
||||
player:hud_change(hud_element.id, "offset", { x= hud_config.offset.x, y=hud_config.offset.y + (i-1) *40})
|
||||
if (hud_element.id_background ~= nil) then
|
||||
player:hud_change(hud_element.id_background, "offset", { x= hud_config.offset.x, y=hud_config.offset.y + (i-1) *40 + 22})
|
||||
end
|
||||
if (hud_element.id_bar ~= nil) then
|
||||
player:hud_change(hud_element.id_bar, "offset", { x= hud_config.offset.x + 2, y=hud_config.offset.y + (i-1) *40 + 24})
|
||||
end
|
||||
|
||||
end
|
||||
visible[hud_element.name] = true
|
||||
i = i + 1
|
||||
else
|
||||
player:hud_remove(hud_element.id)
|
||||
if (hud_element.id_background ~= nil) then
|
||||
player:hud_remove(hud_element.id_background)
|
||||
end
|
||||
if (hud_element.id_bar ~= nil) then
|
||||
player:hud_remove(hud_element.id_bar)
|
||||
end
|
||||
table.insert(remove, j)
|
||||
end
|
||||
end
|
||||
end
|
||||
--remove ended quests
|
||||
if (remove[1] ~= nil) then
|
||||
for _,j in ipairs(remove) do
|
||||
table.remove(quests.hud[playername].list, j)
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
|
||||
if (i >= show_max + 1) then
|
||||
return
|
||||
end
|
||||
-- add new quests
|
||||
local counter = i - 1
|
||||
for questname,questspecs in pairs(quests.active_quests[playername]) do
|
||||
if not visible[questname] then
|
||||
local function get_hud_list(playername)
|
||||
local deftable = {}
|
||||
local counter = 0
|
||||
for questname, plr_quest in quests.sorted_pairs(quests.active_quests[playername]) do
|
||||
local quest = quests.registered_quests[questname]
|
||||
if quest then -- Quest might have been deleted
|
||||
if quest.simple then
|
||||
local id = player:hud_add({ hud_elem_type = "text",
|
||||
local hide_from_hud
|
||||
if quests.info_quests[playername] and quests.info_quests[playername][questname] then
|
||||
hide_from_hud = quests.info_quests[playername][questname].hide_from_hud
|
||||
else
|
||||
hide_from_hud = false
|
||||
end
|
||||
if quest and not hide_from_hud then -- Quest might have been deleted
|
||||
local function get_table(name, value, max)
|
||||
local def = {
|
||||
text = {
|
||||
hud_elem_type = "text",
|
||||
alignment = { x=1, y= 1 },
|
||||
position = {x = hud_config.position.x, y = hud_config.position.y},
|
||||
offset = {x = hud_config.offset.x, y = hud_config.offset.y + counter * 40},
|
||||
number = hud_config.number,
|
||||
text = get_quest_hud_string(questname, questspecs) })
|
||||
local id_background
|
||||
local id_bar
|
||||
if quest.max ~= 1 then
|
||||
id_background = player:hud_add({ hud_elem_type = "image",
|
||||
text = name
|
||||
}
|
||||
}
|
||||
if plr_quest.finished then
|
||||
if quests.failed_quests[playername] and quests.failed_quests[playername][questname] then
|
||||
def.text.number = quests.colors.failed
|
||||
else
|
||||
def.text.number = quests.colors.success
|
||||
end
|
||||
else
|
||||
def.text.number = hud_config.number
|
||||
end
|
||||
if value and max then
|
||||
def.bar = {
|
||||
hud_elem_type = "image",
|
||||
scale = { x = math.floor(20 * value / max), y = 1 },
|
||||
alignment = { x = 1, y = 1 },
|
||||
position = { x = hud_config.position.x, y = hud_config.position.y },
|
||||
offset = { x = hud_config.offset.x + 2, y = hud_config.offset.y + counter * 40 + 24 },
|
||||
text = "quests_questbar.png"
|
||||
}
|
||||
def.background = {
|
||||
hud_elem_type = "image",
|
||||
scale = { x = 1, y = 1 },
|
||||
size = { x = 2, y = 4 },
|
||||
alignment = { x = 1, y = 1 },
|
||||
position = { x = hud_config.position.x, y = hud_config.position.y },
|
||||
offset = { x = hud_config.offset.x, y = hud_config.offset.y + counter * 40 + 22 },
|
||||
text = "quests_questbar_background.png" })
|
||||
id_bar = player:hud_add({hud_elem_type = "image",
|
||||
scale = { x = math.floor(20 * questspecs.value / quest.max),
|
||||
y = 1 },
|
||||
alignment = { x = 1, y = 1 },
|
||||
position = { x = hud_config.position.x, y = hud_config.position.y },
|
||||
offset = { x = hud_config.offset.x + 2, y = hud_config.offset.y + counter * 40 + 24 },
|
||||
text = "quests_questbar.png" })
|
||||
text = "quests_questbar_background.png"
|
||||
}
|
||||
end
|
||||
|
||||
table.insert(quests.hud[playername].list, { name = questname,
|
||||
id = id,
|
||||
id_background = id_background,
|
||||
id_bar = id_bar,
|
||||
value = questspecs.value })
|
||||
else
|
||||
-- TODO
|
||||
return def
|
||||
end
|
||||
if quest.simple then
|
||||
deftable[questname] = get_table(get_quest_hud_string(quest.title, plr_quest.value, quest.max), plr_quest.value, quest.max)
|
||||
counter = counter + 1
|
||||
if (counter >= show_max + 1) then
|
||||
else
|
||||
deftable[questname] = get_table(quest.title, plr_quest.value, quest.max)
|
||||
counter = counter + 0.5
|
||||
for taskname, task in pairs(quest.tasks) do
|
||||
local plr_task = quests.active_quests[playername][questname][taskname]
|
||||
if plr_task.visible and not plr_task.disabled and not plr_task.finished then
|
||||
deftable[questname .. "#" .. taskname] = get_table("- " .. get_quest_hud_string(task.title, plr_task.value, task.max), plr_task.value, task.max)
|
||||
counter = counter + 1
|
||||
if counter >= show_max + 1 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
counter = counter + 0.1
|
||||
end
|
||||
if counter >= show_max + 1 then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return deftable
|
||||
end
|
||||
|
||||
local DELETED = {}
|
||||
-- only for internal use
|
||||
-- updates the hud
|
||||
function quests.update_hud(playername)
|
||||
if quests.hud[playername] == nil or quests.active_quests[playername] == nil then
|
||||
return
|
||||
end
|
||||
if quests.hud[playername].list == nil then
|
||||
if quests.hud[playername].autohide and next(quests.active_quests[playername]) ~= nil then
|
||||
quests.show_hud(playername)
|
||||
end
|
||||
return
|
||||
end
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if player == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if quests.hud[playername].autohide then
|
||||
if (next(quests.active_quests[playername]) == nil) then
|
||||
player:hud_change(quests.hud[playername].list[1].id, "text", S("No more Quests"))
|
||||
if next(quests.active_quests[playername]) == nil then
|
||||
player:hud_change(quests.hud[playername].header, "text", S("No more Quests"))
|
||||
minetest.after(3, function(playername)
|
||||
if (next(quests.active_quests[playername]) ~= nil) then
|
||||
player:hud_change(quests.hud[playername].list[1].id, "text", S("Quests:"))
|
||||
if next(quests.active_quests[playername]) ~= nil then
|
||||
player:hud_change(quests.hud[playername].header, "text", S("Quests:"))
|
||||
quests.update_hud(playername)
|
||||
else
|
||||
quests.hide_hud(playername)
|
||||
end
|
||||
end, playername)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for changes in the hud
|
||||
local function table_diff(tab1, tab2)
|
||||
local result_tab
|
||||
for k, v in pairs(tab2) do
|
||||
if not tab1[k] or tab1[k] ~= v then
|
||||
if type(tab1[k]) == "table" and type(v) == "table" then
|
||||
local diff = table_diff(tab1[k], v)
|
||||
if diff ~= nil then
|
||||
if not result_tab then
|
||||
result_tab = {}
|
||||
end
|
||||
result_tab[k] = diff
|
||||
end
|
||||
else
|
||||
if not result_tab then
|
||||
result_tab = {}
|
||||
end
|
||||
result_tab[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
for k, _ in pairs(tab1) do
|
||||
if tab2[k] == nil then
|
||||
if not result_tab then
|
||||
result_tab = {}
|
||||
end
|
||||
result_tab[k] = DELETED
|
||||
end
|
||||
end
|
||||
return result_tab
|
||||
end
|
||||
-- Merge `from` into table `into`
|
||||
local function table_merge(from, into)
|
||||
for k, v in pairs(from) do
|
||||
if type(v) == "table" and type(into[k]) == "table" then
|
||||
table_merge(v, into[k])
|
||||
else
|
||||
into[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
local old_hud = quests.hud[playername].list
|
||||
local new_hud = get_hud_list(playername)
|
||||
local diff = table_diff(old_hud, new_hud)
|
||||
-- Copy the HUD IDs from the old table to the new one, to avoid loosing them
|
||||
for questname, hud_elms in pairs(old_hud) do
|
||||
for elm_name, elm_def in pairs(hud_elms) do
|
||||
if new_hud[questname] and new_hud[questname][elm_name] then
|
||||
new_hud[questname][elm_name].id = elm_def.id
|
||||
end
|
||||
end
|
||||
end
|
||||
if diff ~= nil then
|
||||
for questname, hud_elms in pairs(diff) do
|
||||
if hud_elms == DELETED then
|
||||
for elm_name, elm_def in pairs(old_hud[questname]) do
|
||||
player:hud_remove(elm_def.id)
|
||||
end
|
||||
else
|
||||
for elm_name, elm_def in pairs(hud_elms) do
|
||||
if not old_hud[questname] or not old_hud[questname][elm_name] or not old_hud[questname][elm_name].id then
|
||||
new_hud[questname][elm_name].id = player:hud_add(elm_def)
|
||||
else
|
||||
for elm_prop_name, elm_prop in pairs(elm_def) do
|
||||
if elm_prop_name ~= "id" then
|
||||
if type(elm_prop) == "table" then
|
||||
-- For table-based properties, MT expects a full table to be specified,
|
||||
-- so we must create a merged table. Just merge the changes with the old
|
||||
-- HUD table, since it will disappear.
|
||||
table_merge(elm_prop, old_hud[questname][elm_name][elm_prop_name])
|
||||
else
|
||||
old_hud[questname][elm_name][elm_prop_name] = elm_prop
|
||||
end
|
||||
player:hud_change(new_hud[questname][elm_name].id, elm_prop_name, old_hud[questname][elm_name][elm_prop_name])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
quests.hud[playername].list = new_hud
|
||||
end
|
||||
|
||||
|
||||
|
16
init.lua
16
init.lua
@ -26,12 +26,26 @@ end
|
||||
quests.colors = {
|
||||
new = "0xAAAA00",
|
||||
success = "0x00AD00",
|
||||
failed = "0xAD0000"
|
||||
failed = "0xAD0000",
|
||||
}
|
||||
|
||||
|
||||
local MP = minetest.get_modpath("quests")
|
||||
|
||||
function quests.sorted_pairs(t)
|
||||
local a = {}
|
||||
for n in pairs(t) do table.insert(a, n) end
|
||||
table.sort(a)
|
||||
local i = 0 -- iterator variable
|
||||
local iter = function () -- iterator function
|
||||
i = i + 1
|
||||
if a[i] == nil then return nil
|
||||
else return a[i], t[a[i]]
|
||||
end
|
||||
end
|
||||
return iter
|
||||
end
|
||||
|
||||
dofile(MP .. "/central_message.lua")
|
||||
dofile(MP .. "/core.lua")
|
||||
dofile(MP .. "/hud.lua")
|
||||
|
Loading…
Reference in New Issue
Block a user