Module:Elderfield/NPC

From Welcome to Elderfield Wiki
Jump to navigation Jump to search
-- Module:Elderfield/NPC
--
-- Character data: gift preferences, placements and the tasks they give.

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

local function findByName(name)
	if not name then return nil end
	local lower = mw.ustring.lower(name)
	for _, rec in pairs(u.data('NPCs')) do
		if mw.ustring.lower(rec.name or '') == lower then return rec end
	end
	return nil
end

--- {{#invoke:Elderfield/NPC|gifts|name=Sam}}
function p.gifts(frame)
	local rec = findByName(u.arg(frame, 'name'))
	if not rec then return u.missing('Character', u.arg(frame, 'name') or '?') end
	local tiers = { { 'loves', 'Loves' }, { 'likes', 'Likes' }, { 'neutral', 'Neutral' }, { 'hates', 'Hates' } }
	local rows = {}
	for _, t in ipairs(tiers) do
		local list = (rec.gifts or {})[t[1]] or {}
		if u.count(list) > 0 then
			local links = {}
			-- Each gift with its bag icon first, as the character page draws it.
			for _, title in ipairs(list) do
				local icon = u.icon((rec.giftIcons or {})[title])
				links[#links + 1] = icon ~= '' and (icon .. ' ' .. u.link(title)) or u.link(title)
			end
			rows[#rows + 1] = { t[2], tostring(u.count(list)), table.concat(links, ' \u{00b7} ') }
		end
	end
	return u.table({ { label = 'Reaction' }, { label = 'Count', align = 'right' }, { label = 'Items' } },
		rows, 'elderfield-gifts')
end

--- {{#invoke:Elderfield/NPC|likes|item=Pizza}} -- who wants this item
function p.likes(frame)
	local item = u.arg(frame, 'item')
	if not item then return '' end
	local tiers = { 'loves', 'likes', 'neutral', 'hates' }
	local found = {}
	for _, rec in pairs(u.data('NPCs')) do
		for _, tier in ipairs(tiers) do
			for _, title in ipairs((rec.gifts or {})[tier] or {}) do
				if title == item then
					found[tier] = found[tier] or {}
					table.insert(found[tier], u.link(rec.title, rec.name))
				end
			end
		end
	end
	local out = {}
	for _, tier in ipairs(tiers) do
		if found[tier] then
			table.sort(found[tier])
			out[#out + 1] = "; " .. tier:sub(1, 1):upper() .. tier:sub(2) .. "\n: " .. table.concat(found[tier], ', ')
		end
	end
	return table.concat(out, '\n')
end

--- {{#invoke:Elderfield/NPC|index}} -- the character roster
function p.index(frame)
	local list = {}
	for _, rec in pairs(u.data('NPCs')) do
		if rec.status == 'player-facing' then list[#list + 1] = rec end
	end
	table.sort(list, function(a, b) return (a.name or '') < (b.name or '') end)
	local rows = {}
	for _, rec in ipairs(list) do
		rows[#rows + 1] = {
			u.link(rec.title, rec.name),
			rec.role or '',
			u.join(rec.maps, ', '),
			rec.relationship and 'Yes' or '',
		}
	end
	return u.table({ { label = 'Character' }, { label = 'Role' }, { label = 'Found in' },
		{ label = 'Friendship' } }, rows, 'elderfield-npcs')
end

return p