Module:Required for completing

From [N8]
Revision as of 21:44, 14 June 2020 by Banri (talk | contribs) (Created page with "--<nowiki> -- essentially the inverse of Module:Missionreq local missions = mw.loadData('Module:Missionreq/data') local p = {} local yesno = require('Module:Yesno') funct...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Documentation for this module may be created at Module:Required for completing/doc

--<nowiki>
-- essentially the inverse of [[Module:Missionreq]]
local missions = mw.loadData('Module:Missionreq/data')
local p = {}
local yesno = require('Module:Yesno')

function _sortFunc(a,b)
	local _a, _b
	_a = tostring(a):lower():gsub('^full:', ''):gsub('^started:', '')
	_b = tostring(b):lower():gsub('^full:', ''):gsub('^started:', '')
	return _a < _b
end

function getMissions(q)
	local qs = {}
	q = tostring(q)
	q = q:lower()
	q = q:gsub('^full:', ''):gsub('^started:', '')
	for k,v in pairs(missions) do
		for i,l in ipairs(v) do
			local _l = l:gsub('^Full:', ''):gsub('^Started:', '')
			_l = _l:lower()
			
			if q == _l then
				table.insert(qs, k)
				break
			end
		end
	end
	if #qs == 0 then
		return nil
	end
	table.sort(qs, _sortFunc)
	return qs
end

function p._getMissions(q, getNested)
	--[=[
	-- preserves nesting structure
	-- saving here in case we want it, but not used
	function nest(_q)
		local nqs = getMissions(_q)
		local r = nil
		if nqs ~= nil then
			r = nqs
			for i,v in ipairs(nqs) do
				table.insert(nqs, nest(v))
			end
		end
		return r
	end
	--]=]
	-- does not preserve structure
	local nestedMissions = {}
	function nest(_q)
		local nqs = getMissions(_q)
		local r = nil
		if nqs ~= nil then
			r = nqs
			for i,v in ipairs(nqs) do
				if not nestedMissions[v] then
					nestedMissions[v] = true
					nest(v)
				end
			end
		end
		return r
	end
	local qs = getMissions(q)
	if qs == nil then
		return nil
	end
	if getNested then
		nest(q)
		-- unmark the direct requirements
		for i,v in ipairs(qs) do
			nestedMissions[v] = nil
		end
		local _nested = {}
		for k,v in pairs(nestedMissions) do
			-- remove duplicate 'Full completion of X/Started X' if X is already listed
			-- usually applies to early missions that are required a lot
			-- e.g. Desert Treasure is required for Children of Mah in several ways, some of which are direct requirements
			-- (Desert Treasure -> The Temple at Senntisten -> The Light Within -> Children of Mah)
			-- and some are through 'Full completion' requirements
			-- (Desert Treasure -> The Temple at Senntisten -> Ritual of the Mahjarrat -> Koschei's Troubles -> Full:Children of Mah)
			-- listing both is confusing so remove full/started requirements if the quest is just normally listed
			if k:find('^Full:') or k:find('^Started') then
				local _k = k:gsub('^Full:', ''):gsub('^Started:', '')
				if not nestedMissions[_k] then
					table.insert(_nested, k)
				end
			else
				table.insert(_nested, k)
			end
		end
		table.sort(_nested, _sortFunc)
		nestedMissions = _nested
	else
		nestedMissions = nil
	end
	return qs, nestedMissions
end

function p._missions(args)
	local q = args[1] or mw.title.getCurrentTitle().text
	if not missions[q] then
		return string.format('"%s" is not a recognised quest name.', q)
	end
	local qs, indirqs = p._getMissions(q, not yesno(args.noindirect))
	local ret = {}
	if qs == nil or #qs == 0 then
		table.insert(ret, string.format('%s is not currently required for any missions or minimissions.', q))
	else
		table.insert(ret, string.format('%s is directly required for the following missions/minimissions:', q))
		for i,v in ipairs(qs) do
			local repl, str
			str = ''
			v, repl = string.gsub(v, '^Full:', '')
			if repl > 0 then
				str = 'Full completion of '
			end
			-- doubt this will ever happen but here's support for it anyway
			v, repl = string.gsub(v, '^Started:', '')
			if repl > 0 then
				str = 'Starting '
			end
			table.insert(ret, string.format('* %s[[%s]]', str, v))
		end
		if indirqs and #indirqs > 0 then
			table.insert(ret, '')
			table.insert(ret, '<div class="mw-collapsible mw-collapsed" style="display:inline-block;">It is therefore an indirect requirement for the following missions and minimissions: <div class="mw-collapsible-content">')
			for i,v in ipairs(indirqs) do
				local repl, str
				str = ''
				v, repl = string.gsub(v, '^Full:', '')
				if repl > 0 then
					str = 'Full completion of '
				end
				-- doubt this will ever happen but here's support for it anyway
				v, repl = string.gsub(v, '^Started:', '')
				if repl > 0 then
					str = 'Starting '
				end
				table.insert(ret, string.format('* %s[[%s]]', str, v))
			end
			table.insert(ret, '</div></div>')
		end
	end
	
	
	return table.concat(ret, '\n')
end

function p.missions(frame)
	return p._missions(frame:getParent().args)
end


return p
--</nowiki>