<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ASlayer_task_library</id>
	<title>Module:Slayer task library - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.runerealm.org/index.php?action=history&amp;feed=atom&amp;title=Module%3ASlayer_task_library"/>
	<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Slayer_task_library&amp;action=history"/>
	<updated>2026-06-15T22:22:42Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://wiki.runerealm.org/index.php?title=Module:Slayer_task_library&amp;diff=34256&amp;oldid=prev</id>
		<title>Alex: Created page with &quot;local SlayerConsts = require (&#039;Module:SlayerConsts&#039; ) local MasterTables = require (&#039;Module:SlayerConsts/MasterTables&#039; )  local p = {}  -- -- Creates a &quot;status&quot; table that holds all information needed to check -- if a player meets task requirements. This function is purely for convenience. -- You are free to create your own table and pass it to the various functions, -- but using this to create your table helps to keep it from being malformed. -- -- The strings in quests...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.runerealm.org/index.php?title=Module:Slayer_task_library&amp;diff=34256&amp;oldid=prev"/>
		<updated>2024-10-15T23:59:58Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;local SlayerConsts = require (&amp;#039;Module:SlayerConsts&amp;#039; ) local MasterTables = require (&amp;#039;Module:SlayerConsts/MasterTables&amp;#039; )  local p = {}  -- -- Creates a &amp;quot;status&amp;quot; table that holds all information needed to check -- if a player meets task requirements. This function is purely for convenience. -- You are free to create your own table and pass it to the various functions, -- but using this to create your table helps to keep it from being malformed. -- -- The strings in quests...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local SlayerConsts = require (&amp;#039;Module:SlayerConsts&amp;#039; )&lt;br /&gt;
local MasterTables = require (&amp;#039;Module:SlayerConsts/MasterTables&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
-- Creates a &amp;quot;status&amp;quot; table that holds all information needed to check&lt;br /&gt;
-- if a player meets task requirements. This function is purely for convenience.&lt;br /&gt;
-- You are free to create your own table and pass it to the various functions,&lt;br /&gt;
-- but using this to create your table helps to keep it from being malformed.&lt;br /&gt;
--&lt;br /&gt;
-- The strings in quests, unlocks, other, and blocks arrays should match&lt;br /&gt;
-- EXACTLY with strings in the respective IDS table.&lt;br /&gt;
--&lt;br /&gt;
-- @param stats {table} A table whose keys and values will be used to update&lt;br /&gt;
--						the default stats table.&lt;br /&gt;
-- @param quests {array} An array containing strings of quests that should be&lt;br /&gt;
--						marked as complete.&lt;br /&gt;
-- @param unlocks {array} An array containing strings of unlocks that should be&lt;br /&gt;
--						marked as complete.&lt;br /&gt;
-- @param other {array} An array containing strings of other things that should be&lt;br /&gt;
--						marked as complete.&lt;br /&gt;
-- @param blocks {array} An array containing strings of tasks that should be&lt;br /&gt;
--						treated as blocked.&lt;br /&gt;
-- @return {table} See status table documentation below.&lt;br /&gt;
--&lt;br /&gt;
function p.create_status(stats, quests, unlocks, other, blocks)&lt;br /&gt;
	&lt;br /&gt;
	--[[&lt;br /&gt;
	The status table needs to keep this layout in order to check requirements.&lt;br /&gt;
	&lt;br /&gt;
	The Stats subtable should hold all levels for the player. You can put any&lt;br /&gt;
	key in the Stats subtable, but make sure to have all the keys required for&lt;br /&gt;
	your task data.&lt;br /&gt;
	&lt;br /&gt;
	The Quests subtable consists of names of quests for keys with values &lt;br /&gt;
	true if completed and false if not completed.&lt;br /&gt;
	&lt;br /&gt;
	The Unlocks subtable consists of names of unlocks for keys with values&lt;br /&gt;
	true if unlocked and false if not unlocked. &lt;br /&gt;
	&lt;br /&gt;
	The Other subtable consists of the names of other tasks (like barbarian&lt;br /&gt;
	training) as keys with values true if completed and false if not.&lt;br /&gt;
	&lt;br /&gt;
	If any required subtable key has value false, check_requirements will by &lt;br /&gt;
	default return false (equivalent to not being able to get the task). &lt;br /&gt;
	You need to manually change that function to check for unlocks which may &lt;br /&gt;
	actually block a task. For example, Stop the Wyvern is an unlock,&lt;br /&gt;
	but unlocking it blocks the task. This logic is handled in check_requirements.&lt;br /&gt;
	&lt;br /&gt;
	]]&lt;br /&gt;
	local status = {&lt;br /&gt;
		Stats = {&lt;br /&gt;
			Combat = 3,&lt;br /&gt;
			Slayer = 1,&lt;br /&gt;
			Magic = 1,&lt;br /&gt;
			Agility = 1,&lt;br /&gt;
			Strength = 1,&lt;br /&gt;
			Firemaking = 1,&lt;br /&gt;
			Defence = 1,&lt;br /&gt;
			Thieving = 1&lt;br /&gt;
		},&lt;br /&gt;
		Quests = {},&lt;br /&gt;
		Unlocks = {},&lt;br /&gt;
		Other = {},&lt;br /&gt;
		Blocks = {}		&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	Populate required quests, unlocks, and others with false values by default.&lt;br /&gt;
	]]&lt;br /&gt;
	for quest_name, _ in SlayerConsts.get_quest_pairs() do&lt;br /&gt;
		p.set_quest_incomplete(status, quest_name)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for unlock_name, _ in SlayerConsts.get_unlock_pairs() do&lt;br /&gt;
		p.set_unlock_inactive(status, unlock_name)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for other_name, _ in SlayerConsts.get_other_pairs() do&lt;br /&gt;
		p.set_other_incomplete(status, other_name)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	If you pass in stats, quests, or unlocks, they will be updated here.&lt;br /&gt;
	]]&lt;br /&gt;
	if stats ~= nil then&lt;br /&gt;
		for k, v in pairs(stats) do&lt;br /&gt;
			p.set_stat(status, k, v)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if quests ~= nil then&lt;br /&gt;
		p.set_quests_complete(status, quests)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if unlocks ~= nil then&lt;br /&gt;
		p.set_unlocks_active(status, unlocks)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if other ~= nil then&lt;br /&gt;
		p.set_others_complete(status, other)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if blocks ~= nil then&lt;br /&gt;
		p.add_blocks(status, blocks)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return status&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Stub Functions&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- These functions are just wrappers for the functions to access the tables in&lt;br /&gt;
-- the SlayerConsts module. They are included for convenience so both this&lt;br /&gt;
-- module and SlayerConsts do not need to be required by as many modules.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
function p.get_unlock_id(name)&lt;br /&gt;
	return SlayerConsts.get_unlock_id(name)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_unlock_name(unlockId)&lt;br /&gt;
	return SlayerConsts.get_unlock_name(unlockId)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_unlock_pairs()&lt;br /&gt;
	return SlayerConsts.get_unlock_pairs()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_quest_id(name)&lt;br /&gt;
	return SlayerConsts.get_quest_id(name)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_quest_name(questId)&lt;br /&gt;
	return SlayerConsts.get_quest_name(questId)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_quest_pairs()&lt;br /&gt;
	return SlayerConsts.get_quest_pairs()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_other_id(name)&lt;br /&gt;
	return SlayerConsts.get_other_id(name)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_other_name(otherId)&lt;br /&gt;
	return SlayerConsts.get_other_name(otherId)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_other_pairs()&lt;br /&gt;
	return SlayerConsts.get_other_pairs()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_monster_id(name)&lt;br /&gt;
	return SlayerConsts.get_monster_id(name)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_monster_name(monsterId)&lt;br /&gt;
	return SlayerConsts.get_monster_name(monsterId)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.get_monster_pairs()&lt;br /&gt;
	return SlayerConsts.get_monster_pairs()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
-- End of stub functions&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Status Helper Functions&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- These helper functions should be somewhat self explanatory.&lt;br /&gt;
-- These are simply included in order to abstract away some of the code&lt;br /&gt;
-- that will need to be written concerning status.&lt;br /&gt;
-- Note that since Lua passes tables by reference, you should NOT set your status&lt;br /&gt;
-- equal to the result of any of these functions. None of them return anything.&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
function p.set_stat(status, statName, statValue)&lt;br /&gt;
	status[&amp;#039;Stats&amp;#039;][statName] = statValue&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_quest_complete(status, questName)&lt;br /&gt;
	status[&amp;#039;Quests&amp;#039;][questName] = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_quest_incomplete(status, questName)&lt;br /&gt;
	status[&amp;#039;Quests&amp;#039;][questName] = false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_quests_complete(status, questNames)&lt;br /&gt;
	if questNames ~= nil then&lt;br /&gt;
		for _, questName in pairs(questNames) do&lt;br /&gt;
			p.set_quest_complete(status, questName)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_quests_incomplete(status, questNames)&lt;br /&gt;
	if questNames ~= nil then&lt;br /&gt;
		for _, questName in pairs(questNames) do&lt;br /&gt;
			p.set_quest_incomplete(status, questName)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_unlock_active(status, unlockName)&lt;br /&gt;
	status[&amp;#039;Unlocks&amp;#039;][unlockName] = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_unlock_inactive(status, unlockName)&lt;br /&gt;
	status[&amp;#039;Unlocks&amp;#039;][unlockName] = false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_unlocks_active(status, unlockNames)&lt;br /&gt;
	if unlockNames ~= nil then&lt;br /&gt;
		for _, unlockName in pairs(unlockNames) do&lt;br /&gt;
			p.set_unlock_active(status, unlockName)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_unlocks_inactive(status, unlockNames)&lt;br /&gt;
	if unlockNames ~= nil then&lt;br /&gt;
		for _, unlockName in pairs(unlockNames) do&lt;br /&gt;
			p.set_unlock_inactive(status, unlockName)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_other_complete(status, otherName)&lt;br /&gt;
	status[&amp;#039;Other&amp;#039;][otherName] = true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_other_incomplete(status, otherName)&lt;br /&gt;
	status[&amp;#039;Other&amp;#039;][otherName] = false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_others_complete(status, otherNames)&lt;br /&gt;
	if otherNames ~= nil then&lt;br /&gt;
		for _, otherName in pairs(otherNames) do&lt;br /&gt;
			p.set_other_complete(status, otherName)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.set_others_incomplete(status, otherNames)&lt;br /&gt;
	if otherNames ~= nil then&lt;br /&gt;
		for _, otherName in pairs(otherNames) do&lt;br /&gt;
			p.set_other_incomplete(status, otherName)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.add_block(status, taskName)&lt;br /&gt;
	-- Might want to check for dupes&lt;br /&gt;
	-- Might want to check for length, although not having a restriction&lt;br /&gt;
	-- here increases flexibility.&lt;br /&gt;
	table.insert(status[&amp;#039;Blocks&amp;#039;], taskName)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.remove_block(status, taskName)&lt;br /&gt;
	toRemove = {}&lt;br /&gt;
	-- Note that because the indices are increasing and being&lt;br /&gt;
	-- added to the front of toRemove, the order of elements in&lt;br /&gt;
	-- toRemove will be decreasing.&lt;br /&gt;
	-- This avoids issues when removing table elements which changes&lt;br /&gt;
	-- indices of elements that come later in the table.&lt;br /&gt;
	for index=1,#status[&amp;#039;Blocks&amp;#039;] do&lt;br /&gt;
		if status[&amp;#039;Blocks&amp;#039;][index] == taskName then&lt;br /&gt;
			table.insert(toRemove, 1, index)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for i=1,#toRemove do&lt;br /&gt;
		table.remove(status[&amp;#039;Blocks&amp;#039;], toRemove[i])&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.add_blocks(status, taskNames)&lt;br /&gt;
	if taskNames ~= nil then&lt;br /&gt;
		for _, taskName in pairs(taskNames) do&lt;br /&gt;
			p.add_block(status, taskName)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.remove_blocks(status, taskNames)&lt;br /&gt;
	if taskNames ~= nil then&lt;br /&gt;
		for _, taskName in pairs(taskNames) do&lt;br /&gt;
			p.remove_block(status, taskName)&lt;br /&gt;
		end&lt;br /&gt;
	end	&lt;br /&gt;
end&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
-- End of status helper functions&lt;br /&gt;
--&lt;br /&gt;
--&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- List of all table names. If more masters are added, add them here.&lt;br /&gt;
-- DO NOT add masters who use the same table as someone else (ie. Steve)&lt;br /&gt;
local tableNames = {&amp;quot;Turael&amp;quot;, &amp;quot;Krystilia&amp;quot;, &amp;quot;Mazchna&amp;quot;, &amp;quot;Vannaka&amp;quot;, &amp;quot;Chaeldar&amp;quot;, &amp;quot;Konar&amp;quot;, &amp;quot;Nieve&amp;quot;, &amp;quot;Duradel&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Handle masters who use the same table here.&lt;br /&gt;
local masterNames = {&lt;br /&gt;
	Turael = tableNames[1],&lt;br /&gt;
	Krystilia = tableNames[2],&lt;br /&gt;
	Mazchna = tableNames[3],&lt;br /&gt;
	Vannaka = tableNames[4],&lt;br /&gt;
	Chaeldar = tableNames[5],&lt;br /&gt;
	Konar = tableNames[6],&lt;br /&gt;
	Nieve = tableNames[7],&lt;br /&gt;
	Steve = tableNames[7],&lt;br /&gt;
	Duradel = tableNames[8]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Given the name of a slayer master, this returns the name of the file that&lt;br /&gt;
-- contains their data. Since Nieve and Steve use the same table, they map to&lt;br /&gt;
-- the same value.&lt;br /&gt;
--&lt;br /&gt;
-- @param masterName {string} A string containing the name of the slayer master&lt;br /&gt;
--							whose table file you want to get.&lt;br /&gt;
-- @return {string} String of the file name for that slayer master&amp;#039;s tasks.&lt;br /&gt;
--&lt;br /&gt;
function p.check_master(masterName)&lt;br /&gt;
	return masterNames[masterName]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
-- Simple mw.loadData wrapper used to access data located on module subpages&lt;br /&gt;
--&lt;br /&gt;
-- @param master {string} Slayer master to retrieve table for&lt;br /&gt;
-- @return {table} Table of master task data&lt;br /&gt;
--&lt;br /&gt;
function p.get_table(master)&lt;br /&gt;
    local t = MasterTables.get_table(p.check_master(master))&lt;br /&gt;
	return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
-- Check to see if a player with the current status has the requirements to get&lt;br /&gt;
-- the task with id taskMonsterId. This should stay internal to this module&lt;br /&gt;
-- to avoid extra complexity for those using the module.&lt;br /&gt;
--&lt;br /&gt;
-- @param status {table} The status table corresponding to the player. See&lt;br /&gt;
--						create_status() documentation for more details.&lt;br /&gt;
-- @param requirements {table} A table containing the requirements for this task.&lt;br /&gt;
--							 See below for an example of the expected layout.&lt;br /&gt;
-- @param taskMonsterId {int} The id of the task.  &lt;br /&gt;
-- @return {boolean} Returns false if any requirement is failed or if the task is&lt;br /&gt;
--					blocked. Returns true otherwise.&lt;br /&gt;
--&lt;br /&gt;
function check_requirements(status, requirements, taskMonsterId)&lt;br /&gt;
	quests = status[&amp;#039;Quests&amp;#039;]&lt;br /&gt;
	unlocks = status[&amp;#039;Unlocks&amp;#039;]&lt;br /&gt;
	other = status[&amp;#039;Other&amp;#039;]&lt;br /&gt;
	stats = status[&amp;#039;Stats&amp;#039;]&lt;br /&gt;
	blocks = status[&amp;#039;Blocks&amp;#039;]&lt;br /&gt;
	&lt;br /&gt;
--	Example requirements table&lt;br /&gt;
--	requirements= {Slayer= 66, Combat= 60, Unlock= &amp;quot;Stop the Wyvern&amp;quot;, Quest= &amp;quot;Bone Voyage&amp;quot;}&lt;br /&gt;
--	In this implementation, values are always expected to be singular.&lt;br /&gt;
--	It may be that a slayer monster in the future requires quests A and B,&lt;br /&gt;
--	where A does not require B and B does not require A. Then the data and this&lt;br /&gt;
--	module will need to be updated to store Quests as arrays and check each quest.&lt;br /&gt;
--	EX:&lt;br /&gt;
-- requirements= {Slayer= 66, Combat= 60, Unlock= {&amp;quot;Stop the Wyvern&amp;quot;}, Quest= {&amp;quot;Bone Voyage&amp;quot;}}&lt;br /&gt;
&lt;br /&gt;
	for k, v in pairs(requirements) do&lt;br /&gt;
		if k == &amp;#039;Quest&amp;#039; then&lt;br /&gt;
			-- Remember that v is an int containing the id of the quest, unlock,&lt;br /&gt;
			-- or other. Since status stores strings as keys we can index in via getting the name.&lt;br /&gt;
			if type(v) == &amp;#039;table&amp;#039; then&lt;br /&gt;
				for _, questId in ipairs(v) do&lt;br /&gt;
					if quests[SlayerConsts.get_quest_name(questId)] == false then&lt;br /&gt;
						return false&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				if quests[SlayerConsts.get_quest_name(v)] == false then&lt;br /&gt;
					return false&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		elseif k == &amp;#039;Unlock&amp;#039; then&lt;br /&gt;
			-- Note that Stop the Wyvern is handled here.&lt;br /&gt;
			if unlocks[SlayerConsts.get_unlock_name(v)] == false and v ~= SlayerConsts.UNLOCK_STOP_THE_WYVERN then&lt;br /&gt;
				return false&lt;br /&gt;
			elseif unlocks[SlayerConsts.get_unlock_name(v)] == true and v == SlayerConsts.UNLOCK_STOP_THE_WYVERN then&lt;br /&gt;
				return false&lt;br /&gt;
			end&lt;br /&gt;
		elseif k == &amp;#039;Other&amp;#039; then&lt;br /&gt;
			if other[SlayerConsts.get_other_name(v)] == false then&lt;br /&gt;
				return false&lt;br /&gt;
			end&lt;br /&gt;
		elseif stats[k] ~= nil then&lt;br /&gt;
			if stats[k] &amp;lt; v then&lt;br /&gt;
				return false&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for i, blockName in ipairs(blocks) do&lt;br /&gt;
	  if SlayerConsts.get_monster_id(blockName) == taskMonsterId then&lt;br /&gt;
	  	return false&lt;br /&gt;
	  end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
-- Reduces the given table down to a table of only tasks the player described by&lt;br /&gt;
-- status can be assigned. Optionally, this can also give you the tasks the&lt;br /&gt;
-- player cannot be assigned.&lt;br /&gt;
--&lt;br /&gt;
-- @param tableToReduce {table} The table of tasks to be reduced. This should&lt;br /&gt;
--								be of the form returned by get_table&lt;br /&gt;
-- @param status {table} The status table corresponding to the player. See&lt;br /&gt;
--						create_status() documentation for more details.&lt;br /&gt;
-- @param returnDisallowed {boolean} If true, returns the tasks the player&lt;br /&gt;
--									cannot be assigned by this master as a second&lt;br /&gt;
--									return value.&lt;br /&gt;
-- @return {table, table|nil} Returns a table that contains only the tasks from tableToReduce&lt;br /&gt;
--					that the player can be assigned. If returnDisallowed is true,&lt;br /&gt;
--					a second table is returned that contains the tasks that cannot&lt;br /&gt;
--					be assigned to the player.&lt;br /&gt;
--&lt;br /&gt;
function p.get_effective_table(tableToReduce, status, returnDisallowed)&lt;br /&gt;
	local availableMonsterTable = {}&lt;br /&gt;
	local unavailableTable = {}&lt;br /&gt;
	for taskMonsterId, taskValue in pairs(tableToReduce) do&lt;br /&gt;
		if check_requirements(status, taskValue[&amp;#039;requirements&amp;#039;], taskMonsterId) then&lt;br /&gt;
			local subtable = taskValue[&amp;#039;subtable&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
			if subtable ~= nil then&lt;br /&gt;
				effectiveSubtable, unavailableSubtable = p.get_effective_table(subtable, status, returnDisallowed)&lt;br /&gt;
&lt;br /&gt;
				local taskValueCopy = {}&lt;br /&gt;
				for k, v in pairs(taskValue) do&lt;br /&gt;
					taskValueCopy[k] = v&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				taskValueCopy[&amp;#039;subtable&amp;#039;] = {}&lt;br /&gt;
				taskValueCopy[&amp;#039;unavailableSubtable&amp;#039;] = {}&lt;br /&gt;
				for subKey, subVal in pairs(effectiveSubtable) do&lt;br /&gt;
					taskValueCopy[&amp;#039;subtable&amp;#039;][subKey] = subVal&lt;br /&gt;
				end&lt;br /&gt;
				for subKey, subVal in pairs(unavailableSubtable) do&lt;br /&gt;
					taskValueCopy[&amp;#039;unavailableSubtable&amp;#039;][subKey] = subVal&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				taskValue = taskValueCopy&lt;br /&gt;
			end&lt;br /&gt;
			availableMonsterTable[taskMonsterId] = taskValue&lt;br /&gt;
		elseif returnDisallowed == true then&lt;br /&gt;
			unavailableTable[taskMonsterId] = taskValue&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return availableMonsterTable, unavailableTable&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
-- Returns the names of the masters who can assign a given task to the player,&lt;br /&gt;
-- regardless of the players status.&lt;br /&gt;
--&lt;br /&gt;
-- @param taskName {string} The name of the task. This needs to match one of the&lt;br /&gt;
--							keys in MONSTER_IDS&lt;br /&gt;
-- @return {array} Returns an array containing the names of the masters who can&lt;br /&gt;
--					assign the task with name taskName.&lt;br /&gt;
--&lt;br /&gt;
function p.get_masters_that_assign(taskName)&lt;br /&gt;
	mastersThatAssign = {}&lt;br /&gt;
	for name, tableName in pairs(masterNames) do&lt;br /&gt;
		taskTable = p.get_table(tableName)&lt;br /&gt;
		for taskMonsterId, taskValue  in pairs(taskTable) do&lt;br /&gt;
			local subtable = taskValue[&amp;#039;subtable&amp;#039;]&lt;br /&gt;
			if subtable ~= nil then&lt;br /&gt;
				for subKey, subVal in pairs(subtable) do&lt;br /&gt;
					if subKey == SlayerConsts.get_monster_id(taskName) then&lt;br /&gt;
						mastersThatAssign[tableName] = true&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if taskMonsterId == SlayerConsts.get_monster_id(taskName) then&lt;br /&gt;
				mastersThatAssign[tableName] = true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return mastersThatAssign&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Alex</name></author>
	</entry>
</feed>