[mff_quests] Implement objective iterator, node punch & placement callbacks

This commit is contained in:
Wouters Dorian 2015-09-06 15:35:40 +02:00
parent 9091d61132
commit 16488bf8ed
1 changed files with 65 additions and 47 deletions

View File

@ -13,18 +13,9 @@ mff.quests.quests = {
awards = {["maptools:superapple"] = 1}, awards = {["maptools:superapple"] = 1},
tasks = { tasks = {
diggy = { diggy = {
title = "Dig 99 stone", title = "Dig 100 stone",
description = "Show you can dig through stone", description = "Show you can dig through stone",
max = 99, max = 100,
objective = {
dig = {"default:stone"}
}
},
diggysrevenge = {
title = "Dig the last stone",
description = "You really thought 99 was a good number? Dig the last one.",
requires = {"diggy"},
max = 1,
objective = { objective = {
dig = {"default:stone"} dig = {"default:stone"}
} }
@ -38,18 +29,9 @@ mff.quests.quests = {
awards = {["default:diamond"] = 1}, awards = {["default:diamond"] = 1},
tasks = { tasks = {
diggy = { diggy = {
title = "Dig 19 coal", title = "Dig 20 coal",
description = "Get the fire mineral", description = "Get the fire mineral",
max = 19, max = 20,
objective = {
dig = {"default:stone_with_coal"}
}
},
diggysrevenge = {
title = "Dig the last one",
description = "I do this because of a technical issue, sorry",
requires = {"diggy"},
max = 1,
objective = { objective = {
dig = {"default:stone_with_coal"} dig = {"default:stone_with_coal"}
} }
@ -63,18 +45,9 @@ mff.quests.quests = {
awards = {["moreores:mithril_ingot"] = 1}, awards = {["moreores:mithril_ingot"] = 1},
tasks = { tasks = {
diggy = { diggy = {
title = "Dig 4 diamond", title = "Dig 5 diamonds",
description = "Yarr harr fiddle dee-dee, being a pirate is alright with me! Do what you want 'cause a pirate is free, you are a pirate! Go get the precious booty... underground. Mine it :/", description = "Yarr harr fiddle dee-dee, being a pirate is alright with me! Do what you want 'cause a pirate is free, you are a pirate! Go get the precious booty... underground. Mine it :/",
max = 4, max = 5,
objective = {
dig = {"default:stone_with_diamond"}
}
},
diggysrevenge = {
title = "Ultimate calbon atom alignement",
description = "Really, we must fix this",
requires = {"diggy"},
max = 1,
objective = { objective = {
dig = {"default:stone_with_diamond"} dig = {"default:stone_with_diamond"}
} }
@ -111,27 +84,72 @@ for qname, quest in pairs(mff.quests.quests) do
local ret = quests.register_quest(mff.QPREFIX .. qname, quest) local ret = quests.register_quest(mff.QPREFIX .. qname, quest)
end end
-- TODO -- The callback function parameters are as follows:
-- implement magical iterator, going through BOTH the simple quests -- questname, questdef,
-- AND tasked quests objectives, returning a tuple like this: -- taskname (nil?), taskdef (nil?),
-- questname, questdef, taskname (nil?), taskdef (nil?), objective_container (that is, either questdef or taskdef), pointer_to_function_to_update_the_objective_progress_with_only_one_parameter_the_others_being_automagically_passed_to_the_quests_API_so_that_we_dont_have_to_write_ifs_and_elses_everywhere_to_handle_both_quest_and_tasks_cases_because_it_would_give_crap_code -- objective_container (that is, either questdef or taskdef),
-- objective (=objectives_container.objectives),
minetest.register_on_dignode(function(pos, oldnode, digger) -- function_to_update_the_objective_progress(value)
if not digger or digger.is_fake_player then return end local function iterate_through_objectives(pname, callback)
local pname = digger:get_player_name()
for qname, quest in pairs(mff.quests.quests) do for qname, quest in pairs(mff.quests.quests) do
if quest.tasks then if quest.tasks then
for tname, task in pairs(quest.tasks) do for tname, task in pairs(quest.tasks) do
if quests.is_task_visible(pname, mff.QPREFIX .. qname, tname) if not quests.is_task_disabled(pname, mff.QPREFIX .. qname, tname) then
and not quests.is_task_disabled(pname, mff.QPREFIX .. qname, tname) callback(qname, quest, tname, task, task, task.objective, function (value)
and task.objective.dig then quests.update_quest_task(pname, mff.QPREFIX .. qname, tname, value)
if table.contains(task.objective.dig, oldnode.name) then end)
quests.update_quest_task(pname, mff.QPREFIX .. qname, tname, 1)
end
end end
end end
else
callback(qname, quest, nil, nil, quest, quest.objective, function (value)
quests.update_quest(pname, mff.QPREFIX .. qname, value)
end)
end end
end end
end
local function contains_node_or_group(table, element)
for _, value in pairs(table) do
if value == element or -- Simple node match
(value:len() > 6 and value:sub(0,6) == "group:" and
minetest.get_item_group(element, value:sub(7)) > 0) then -- Group
return true
end
end
return false
end
-- Quest objective: node digging
minetest.register_on_dignode(function(pos, oldnode, digger)
if not digger or digger.is_fake_player then return end
local pname = digger:get_player_name()
iterate_through_objectives(pname, function (_, _, _, _, _, objective, update)
if objective.dig and contains_node_or_group(objective.dig, oldnode.name) then
update(1)
end
end)
end)
-- Quest objective: node punching
minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
if not puncher or puncher.is_fake_player then return end
local pname = puncher:get_player_name()
iterate_through_objectives(pname, function (_, _, _, _, _, objective, update)
if objective.punch and contains_node_or_group(objective.punch, node.name) then
update(1)
end
end)
end)
-- Quest objective: node placement
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
if not placer or placer.is_fake_player then return end
local pname = placer:get_player_name()
iterate_through_objectives(pname, function (_, _, _, _, _, objective, update)
if objective.place and contains_node_or_group(objective.place, newnode.name) then
update(1)
end
end)
end) end)
minetest.register_on_joinplayer(function (player) minetest.register_on_joinplayer(function (player)