Module:ElementMatchups
Appearance
Documentation for this module may be created at Module:ElementMatchups/doc
require( 'strict' )
local TableLua = require( 'Module:TableLua' )
local Element = require( 'Module:Element' )
local p = {}
--- Same source the element chart is built from, so the per-element tables and
--- the chart can never disagree.
local DATA = 'Module:GameData/EvoCreo2/ElementTable.json'
--- FIRE -> Fire
---
--- @param name string
--- @return string
local function toTitle( name )
return name:sub( 1, 1 ):upper() .. name:sub( 2 ):lower()
end
--- @param entry table
--- @return table
local function getBonuses( entry )
local bonuses = {}
for _, comparison in ipairs( entry.elementComparisonMaps or {} ) do
bonuses[comparison.elementToCompareId] = comparison.bonus
end
return bonuses
end
--- @param elements table
--- @param name string
--- @return table|nil
local function findElement( elements, name )
local target = name:upper()
for _, element in ipairs( elements ) do
if element.name:upper() == target then
return element
end
end
end
--- @param badges table
--- @return string
local function join( badges )
if #badges == 0 then
return '—'
end
return table.concat( badges, ' ' )
end
--- Split every element into how the attacker fares against it.
---
--- @param elements table
--- @param attacker table
--- @return table, table, table
local function split( elements, attacker )
local bonuses = getBonuses( attacker )
local strong = {}
local neutral = {}
local weak = {}
for _, defender in ipairs( elements ) do
local bonus = bonuses[defender.id]
local badge = Element._main( defender.name )
if bonus == 1 then
table.insert( strong, badge )
elseif bonus == -1 then
table.insert( weak, badge )
else
table.insert( neutral, badge )
end
end
return strong, neutral, weak
end
--- The three-way breakdown for one element, as used on the element pages.
---
--- @param elementName string
--- @return string
local function renderMatchups( elementName )
local elements = mw.loadJsonData( DATA )
local attacker = findElement( elements, elementName )
if not attacker then
error( 'Unknown element: ' .. tostring( elementName ) )
end
local strong, neutral, weak = split( elements, attacker )
return TableLua.render( {
caption = string.format( '%s matchups', toTitle( attacker.name ) ),
hideCaption = true,
columns = {
{ label = 'Super effective' },
{ label = 'Neutral' },
{ label = 'Not very effective' }
},
data = { { join( strong ), join( neutral ), join( weak ) } },
class = 'wikitable--border'
} )
end
--- One row per element, as used on the Elements overview page.
---
--- @return string
local function renderList()
local elements = mw.loadJsonData( DATA )
local rows = {}
for _, attacker in ipairs( elements ) do
local strong, _, weak = split( elements, attacker )
table.insert( rows, {
string.format( '[[%s]]', toTitle( attacker.name ) ),
join( strong ),
join( weak )
} )
end
return TableLua.render( {
caption = 'Elements',
hideCaption = true,
columns = {
{ label = 'Element' },
{ label = 'Strong against' },
{ label = 'Weak against' }
},
data = rows,
class = 'sortable wikitable--border'
} )
end
--- Wikitext entry point for the module
---
--- @param frame mw.frame
--- @return string
function p.main( frame )
local getArgs = require( 'Module:Arguments' ).getArgs
return p._main( getArgs( frame ) )
end
--- Lua entry point for the module
---
--- @param args table
--- @return string
function p._main( args )
args = args or {}
if args.mode == 'list' then
return renderList()
end
local elementName = args.element or args[1]
if type( elementName ) ~= 'string' or elementName == '' then
error( 'Module:ElementMatchups requires an element name, or mode=list' )
end
return renderMatchups( elementName )
end
return p