Module:Elderfield/Index

From Welcome to Elderfield Wiki
Jump to navigation Jump to search
-- Module:Elderfield/Index
--
-- Cross-domain index pages: counts, status listings and name lookups.

local u = require('Module:Elderfield/Utility')
local p = {}

local DOMAINS = { 'Items', 'Weapons', 'Armor', 'Enemies', 'NPCs', 'Quests',
	'Recipes', 'Stations', 'Skills', 'Shops', 'Locations', 'Fishing', 'Mail',
	'Achievements', 'States', 'Abilities' }

--- {{#invoke:Elderfield/Index|counts}} -- how much data the wiki holds
function p.counts(frame)
	local rows = {}
	for _, domain in ipairs(DOMAINS) do
		local n = 0
		for _ in pairs(u.data(domain)) do n = n + 1 end
		if n > 0 then rows[#rows + 1] = { domain, tostring(n) } end
	end
	return u.table({ { label = 'Data set' }, { label = 'Entries', align = 'right' } }, rows)
end

--- {{#invoke:Elderfield/Index|lookup|name=Cleansing Balm}} -- name to page title
function p.lookup(frame)
	local name = u.arg(frame, 'name')
	if not name then return '' end
	local rec = u.data('Index')[mw.ustring.lower(name)]
	if not rec then return name end
	return u.link(rec.title, name)
end

--- {{#invoke:Elderfield/Index|icon|name=Grape Seed}} -- the thing's icon, from IconSet.png,
-- by name or page title, with nothing else: no infobox, no data. For a hand-written page that
-- wants a picture beside a name. |link=yes adds the linked name after it; |size=32 sets the
-- size (24 by default). An unknown name gives nothing, so a list keeps reading.
local ICON_DOMAIN = { item = 'Items', weapon = 'Weapons', armor = 'Armor', enemy = 'Enemies',
	npc = 'NPCs', shop = 'Shops', state = 'States', fish = 'Fishing' }
function p.icon(frame)
	local name = u.arg(frame, 'name') or u.arg(frame, 1)
	if not name then return '' end
	local index = u.data('Index')
	local key = mw.ustring.lower(name)
	-- A piece of gear is often written without its upgrade level: "Angler's Vest".
	local rec = index[key] or index[mw.ustring.gsub(key, ' %+%d+$', '')]
	local record = rec and ICON_DOMAIN[rec.kind] and u.get(ICON_DOMAIN[rec.kind], rec.id)
	local size = tonumber(u.arg(frame, 'size') or '') or 24
	local icon = record and record.icon
	-- |quality= picks a tier's own icon (each has one): 1-4, the game's names (Regular, Silver,
	-- Gold, Void), or the words the Items page uses for its price columns (Basic, Quality,
	-- Artisan, Perfect). A tier the item does not have keeps the ordinary icon.
	local q = u.arg(frame, 'quality')
	if record and q and record.tiers then
		local want = mw.ustring.lower(q)
		local byWord = { basic = 1, quality = 2, artisan = 3, perfect = 4, purple = 4 }
		for _, t in ipairs(record.tiers) do
			if tostring(t.tier) == want or mw.ustring.lower(t.name or '') == want or byWord[want] == t.tier then
				icon = t.icon or icon
				break
			end
		end
	end
	local pic = icon and u.icon(icon, size) or ''
	if u.arg(frame, 'link') == 'yes' then
		return pic .. (pic ~= '' and ' ' or '') .. u.link(rec and rec.title or name, name)
	end
	return pic
end

--- {{#invoke:Elderfield/Index|byStatus|domain=Items|status=unreachable}}
function p.byStatus(frame)
	local domain = u.arg(frame, 'domain', 'Items')
	local status = u.arg(frame, 'status', 'unreachable')
	local rows = {}
	for _, rec in pairs(u.data(domain)) do
		if rec.status == status then
			rows[#rows + 1] = { u.link(rec.title, rec.name), u.text(frame, rec.description) }
		end
	end
	table.sort(rows, function(a, b) return a[1] < b[1] end)
	return u.table({ { label = 'Entry' }, { label = 'Description' } }, rows)
end

return p