Module:Fossil

From Pokemon Revolution Online Wiki
Revision as of 14:24, 2 August 2026 by Cae (talk | contribs) (created page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

local p = {}

local DATA_FORMAT = 'CSV with header'

local function nonEmpty(s)
	if s == nil then return nil end
	s = mw.text.trim(tostring(s))
	if s == '' then return nil end
	return s
end

-- Bulk fetch of the whole raw list, shared by every {{Fossil}}/{{FossilCombo}}
-- call on a page instead of each one running its own filtered
-- {{#get_file_data:}} query.
local pokemonRowsCache = nil
local function pokemonByName()
	if pokemonRowsCache then return pokemonRowsCache end
	local csvData = mw.ext.externalData.getExternalData{
		url = 'https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList',
		format = DATA_FORMAT,
		data = { number = 'Pokedex Number', name = 'Name' },
	}
	pokemonRowsCache = {}
	if csvData then
		for _, row in ipairs(csvData) do
			if nonEmpty(row.name) then
				pokemonRowsCache[row.name] = row
			end
		end
	end
	return pokemonRowsCache
end

-- Every fossil entry uses the same Ground color theme, computed once and
-- reused instead of re-expanding the color templates on every call.
local groundColors = nil
local function colors(frame)
	if not groundColors then
		groundColors = {
			light = frame:expandTemplate{ title = 'Ground color light' },
			base = frame:expandTemplate{ title = 'Ground color' },
			dark = frame:expandTemplate{ title = 'Ground color dark' },
		}
	end
	return groundColors
end

local function obtainabilityList(locationsText)
	local items = {}
	for _, part in ipairs(mw.text.split(locationsText or '', '\\', true)) do
		local trimmed = mw.text.trim(part)
		if trimmed ~= '' then
			items[#items + 1] = '<li style="margin-left: 50px;">' .. trimmed .. '</li>'
		end
	end
	return table.concat(items)
end

local function iconPill(fileName, label, dark)
	return '<table align="center"><tr><td style="background-color:#FFFFFF; border-radius: 25px; padding: 3px;">' ..
		'[[File:' .. fileName .. ']]</td><td>' .. label .. '</td></tr></table>'
end

local function pokemonCell(frame, pokemonName, dark)
	local row = pokemonByName()[pokemonName]
	local number = row and row.number or ''
	local link = '[[' .. pokemonName .. '|<span style="color:#' .. dark .. ';">' .. pokemonName .. '</span>]]'
	return '<table align="center"><tr><td style="background-color:#FFFFFF; border-radius: 25px; padding: 4px;">' ..
		'[[File:' .. number .. 'Icon.png]]</td><td>' .. link .. '</td></tr></table>'
end

local function wrap(frame, fromCellHtml, resultCellHtml, locationsText)
	local c = colors(frame)
	local buf = {}
	buf[#buf + 1] = '<table style="width:50%; background-color:#' .. c.base .. '; border: 5px solid #' .. c.dark ..
		'; font-weight: bold; color: #' .. c.dark .. '; border-radius: 25px; padding: 4px; text-align: center;">'

	buf[#buf + 1] = '<tr style="background-color:#' .. c.light .. ';">' ..
		'<td style="border-radius: 25px 1px 1px 25px; padding: 3px; border: 3px solid #' .. c.dark ..
		'; width: 33%;">' .. fromCellHtml .. '</td>' ..
		'<td style="border: 3px solid #' .. c.dark .. '; width: 33%;">Reanimates into ' ..
		'<span style="font-weight: bold; font-size: 25px;">&#8594;</span></td>' ..
		'<td style="border-radius: 1px 25px 25px 1px; border: 3px solid #' .. c.dark .. '; width: 33%;">' ..
		resultCellHtml .. '</td></tr>'

	buf[#buf + 1] = '<tr><td colspan="3" style="border-radius: 25px; border: 3px solid #' .. c.dark ..
		'; background-color:#' .. c.light .. '; padding: 3px;">' ..
		'<table class="collapsible collapsed" width="100%"><tr><th>Obtainability</th></tr>' ..
		'<tr><td style="padding: 10px;"><ul style="background-color:#FFFFFF; border-radius: 20px; border: 1px solid #' ..
		c.dark .. '; text-align: left; font-weight: normal; color:#000000;">' ..
		obtainabilityList(locationsText) .. '</ul></td></tr></table></td></tr>'

	buf[#buf + 1] = '</table>'
	return table.concat(buf)
end

function p.single(frame)
	local parent = frame:getParent()
	local args = (parent and parent.args) or frame.args

	local fossil = nonEmpty(args.Fossil)
	local pokemonName = nonEmpty(args.Pokemon)
	if not fossil or not pokemonName then
		return "<span style='color:red'>Usage: {{Fossil|Fossil=FossilName|Pokemon=PokemonName|Locations=...}}</span>"
	end

	local c = colors(frame)
	local fromCell = iconPill(fossil .. '.png', fossil, c.dark)
	local resultCell = pokemonCell(frame, pokemonName, c.dark)
	return wrap(frame, fromCell, resultCell, args.Locations)
end

function p.combo(frame)
	local parent = frame:getParent()
	local args = (parent and parent.args) or frame.args

	local fossil1 = nonEmpty(args.Fossil1)
	local fossil2 = nonEmpty(args.Fossil2)
	local pokemonName = nonEmpty(args.Pokemon)
	if not fossil1 or not fossil2 or not pokemonName then
		return "<span style='color:red'>Usage: {{FossilCombo|Fossil1=FossilName|Fossil2=FossilName|" ..
			"Pokemon=PokemonName|Locations=...}}</span>"
	end

	local c = colors(frame)
	local fromCell = '<table align="center"><tr>' ..
		'<td style="background-color:#FFFFFF; border-radius: 25px; padding: 3px;">[[File:' .. fossil1 ..
		'.png]]</td><td>' .. fossil1 .. '</td>' ..
		'<td style="font-weight: bold; font-size: 18px; padding: 0 6px;">+</td>' ..
		'<td style="background-color:#FFFFFF; border-radius: 25px; padding: 3px;">[[File:' .. fossil2 ..
		'.png]]</td><td>' .. fossil2 .. '</td></tr></table>'
	local resultCell = pokemonCell(frame, pokemonName, c.dark)
	return wrap(frame, fromCell, resultCell, args.Locations)
end

return p