Module:Keyword

From He is Coming Official Wiki

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

-- Keyword explanations for He is Coming.
-- Used by {{Keyword}}, by item effects (Module:ItemData) and by the [[Keywords]] page.
-- The explanations are the ones the game shows when you hover a keyword.
local p = {}

local STYLES = 'Template:Keyword/styles.css'

-- order = order on the Keywords page
p.list = {
	{name = 'Battle Start', page = 'Battle start', type = 'Trigger', text = 'Triggers at the very beginning of combat, before any actions are taken.'},
	{name = 'Turn Start', page = 'Turn start', type = 'Trigger', text = 'Triggers at the beginning of your turn, before strikes and other on-turn effects resolve.'},
	{name = 'First Turn', page = 'First Turn', type = 'Trigger', text = 'Triggers at the start of your first turn to give a temporary effect.'},
	{name = 'On Hit', page = 'On hit', type = 'Trigger', text = 'Triggers when your strike hits.'},
	{name = 'Exposed', page = 'Exposed', type = 'Trigger', text = 'Triggers when you lose all of your armor for the first time.'},
	{name = 'Wounded', page = 'Wounded', type = 'Trigger', text = 'Triggers the first time your health drops to 50% or lower.'},
	{name = 'Countdown', page = 'Countdown', type = 'Trigger', text = 'Triggers when the countdown reaches 0. Decreases by 1 at turn start.'},
	{name = 'Symphony', page = 'Symphony', type = 'Trigger', text = 'Trigger the effect of another random instrument item.'},
	{name = 'Acid', page = 'Acid', type = 'Status effect', text = 'Lose armor equal to acid at turn start.'},
	{name = 'Freeze', page = 'Freeze', type = 'Status effect', text = 'Freeze halves attack. Remove 1 freeze at turn end.'},
	{name = 'Poison', page = 'Poison', type = 'Status effect', text = 'Take damage equal to poison at turn start and remove 1 poison. Having armor prevents the damage.'},
	{name = 'Purity', page = 'Purity', type = 'Status effect', text = 'When removed, purity restores 3 health and gives 1 attack.'},
	{name = 'Regeneration', page = 'Regeneration', type = 'Status effect', text = 'Restore health equal to regeneration at turn end, then remove 1 regeneration.'},
	{name = 'Riptide', page = 'Riptide', type = 'Status effect', text = 'Take 5 damage at turn end, then remove 1 riptide.'},
	{name = 'Stun', page = 'Stun', type = 'Status effect', text = 'Stun prevents striking. Remove 1 stun for each strike.'},
	{name = 'Thorns', page = 'Thorns', type = 'Status effect', text = 'Deal damage equal to thorns when struck. Then remove those thorns at turn end.'},
}

-- lookup by any spelling a page might use (link target or the word itself)
local byKey = {}
local function key(s)
	return mw.ustring.lower(mw.text.trim((s or ''):gsub('_', ' ')))
end
for _, k in ipairs(p.list) do
	byKey[key(k.name)] = k
	byKey[key(k.page)] = k
end
byKey['thorn'] = byKey['thorns']
byKey['stunned'] = byKey['stun']
byKey['countdowns'] = byKey['countdown']

function p.get(name)
	return byKey[key(name)]
end

local function styles(frame)
	return frame:extensionTag('templatestyles', '', {src = STYLES})
end

-- inner: the wikitext that is shown (a link, or a coloured word)
local function wrap(k, inner)
	return '<span class="hic-kw">' .. inner .. '<span class="hic-kw-tip">\'\'\'' .. k.name .. ':\'\'\' ' .. k.text .. '</span></span>'
end

-- Add tooltips to text that is already expanded: links to keyword pages and coloured status words.
-- Returns the new text (with the stylesheet in front when anything was added).
function p.annotate(frame, text)
	if not text or text == '' then
		return text
	end
	local n = 0
	-- [[Target]] and [[Target|label]]  (links first, so a coloured word inside a link gets one tooltip, not two)
	text = text:gsub('%[%[([^%[%]|]+)|?([^%[%]]*)%]%]', function(target, label)
		local k = byKey[key(target)]
		if not k then
			return nil
		end
		n = n + 1
		local whole = label ~= '' and ('[[' .. target .. '|' .. label .. ']]') or ('[[' .. target .. ']]')
		return (wrap(k, whole):gsub('<span style="color:', '<span data-kw="1" style="color:'))
	end)
	-- words coloured by Module:ColorText (status effects only; attack, armor, health and speed have no tooltip)
	text = text:gsub('(<span style="color:[^"]*">)([^<]+)(</span>)', function(open, word, close)
		local k = byKey[key(word)]
		if not k or k.type ~= 'Status effect' then
			return nil
		end
		n = n + 1
		return wrap(k, open .. word .. close)
	end)
	text = text:gsub('<span data%-kw="1" style="color:', '<span style="color:')
	if n > 0 then
		text = styles(frame) .. text
	end
	return text
end

-- {{Keyword|Exposed}} or {{Keyword|Exposed|exposes}}
function p.show(frame)
	local args = frame:getParent().args
	local name = mw.text.trim(args[1] or frame.args[1] or '')
	local label = mw.text.trim(args[2] or frame.args[2] or '')
	local k = p.get(name)
	if not k then
		return label ~= '' and label or name
	end
	local link = '[[' .. k.page .. '|' .. (label ~= '' and label or k.name) .. ']]'
	return styles(frame) .. wrap(k, link)
end

-- table for the Keywords page
function p.table(frame)
	local out = {'{| class="wikitable sortable" style="width:100%;"', '! style="width:150px;" | Keyword !! style="width:110px;" | Type !! What it does'}
	for _, k in ipairs(p.list) do
		table.insert(out, '|-')
		table.insert(out, '| [[' .. k.page .. '|' .. k.name .. ']] || ' .. k.type .. ' || ' .. k.text)
	end
	table.insert(out, '|}')
	return table.concat(out, '\n')
end

return p