Module:Creo/Components/Infobox
Appearance
This documentation is transcluded from Module:Creo/Components/Infobox/doc.
Output an infobox for Module:Creo using Module:InfoboxLua.
require( 'strict' )
local infoboxLua = require( 'Module:InfoboxLua' )
local getDisplayImage = require( 'Module:Creo' ).getDisplayImage
-- TODO: If we use this in other places, then we should inject this into the Module:Creo instead of loading it here
local rarityTable = mw.loadJsonData( 'Module:GameData/EvoCreo2/RarityTable.json' )
local p = {}
--- @param rarityId number
--- @return mw.html|nil
local function getRarityHtml( rarityId )
local rarity = rarityTable[rarityId]
if not rarity or not rarity.name then
return nil
end
return require( 'Module:Rarity' )._main( rarity.nameId )
end
--- @param elementMap table
--- @return mw.html|nil
local function getElementHtml( elementMap )
if not elementMap.element or not elementMap.element.name then
return nil
end
return require( 'Module:Element' )._main( elementMap.element.name )
end
--- One badge per distinct element, leading with the primary one.
---
--- The export writes some single-element Creo twice -- Samurak is AIR/AIR and
--- Karazim EARTH/EARTH -- as two maps that differ only in `primary`, so the raw
--- list renders the same badge twice. Collapsing the repeat and ordering by
--- `primary` is how creosprites.py and the Creo listing table already read this
--- field, so the infobox now agrees with them.
---
--- @param elements table
--- @return mw.html
local function getElementsHtml( elements )
local html = mw.html.create( 'div' )
html:addClass( 't-creo-infobox-elements' )
local seen = {}
--- Two passes rather than a sort, because table.sort is not stable and would
--- shuffle Creo whose maps share a `primary` value.
---
--- @param wantPrimary boolean
local function addElements( wantPrimary )
for _, elementMap in ipairs( elements ) do
local name = elementMap.element and elementMap.element.name
local isPrimary = ( elementMap.primary or 0 ) ~= 0
if name and isPrimary == wantPrimary and not seen[name] then
local elementHtml = getElementHtml( elementMap )
if elementHtml then
seen[name] = true
html:node( elementHtml )
end
end
end
end
addElements( true )
addElements( false )
return html
end
--- @param data table
--- @return string
local function getOverlayContent( data )
return tostring( mw.html.create( 'div' )
:addClass( 't-creo-infobox-overlay' )
:node( getRarityHtml( data.rarityId ) )
:node( getElementsHtml( data.creoElementMaps ) )
)
end
--- @param args table
--- @return table
local function getInfoboxCss( args )
local css = {}
if args.imageOffsetTop then
css['--t-creo-image-offset-top'] = args.imageOffsetTop
end
if args.imageOffsetBottom then
css['--t-creo-image-offset-bottom'] = args.imageOffsetBottom
end
if args.imageOffsetLeft then
css['--t-creo-image-offset-left'] = args.imageOffsetLeft
end
if args.imageOffsetRight then
css['--t-creo-image-offset-right'] = args.imageOffsetRight
end
return css
end
--- @param args table
--- @param data table
--- @return table
local function getInfoboxSections( args, data )
return {
{
columns = 2,
items = {
{
label = 'Height',
content = ( args.height or tostring( data.creo.height ) or '?' ) .. ' m'
},
{
label = 'Weight',
content = ( args.weight or tostring( data.creo.weight ) or '?' ) .. ' kg'
},
{
label = 'Lifespan',
content = ( args.lifespan or tostring( data.creo.lifespan ) or '?' ) .. ' years'
}
}
}
}
end
--- Build the infobox data needed from the raw data
---
--- @param context table
--- @return table
local function getInfoboxData( context )
local data = context.data
local args = context.args or {}
return {
class = 't-creo-infobox',
title = args.name or data.creo.name,
subtitle = tostring( data.creo.id ),
css = getInfoboxCss( args ),
image = {
-- The display image, not the raw battle sprite: every one of these
-- shares a 120x116 canvas, so this width-only size renders the same
-- box on every Creo page.
src = args.image or getDisplayImage( data.creo.name ),
size = 240,
overlay = getOverlayContent( data ),
class = 'cp-image-pixelated t-creo-infobox-image'
},
sections = getInfoboxSections( args, data )
}
end
--- @param context ComponentContext
--- @return string
function p.render( context )
return mw.getCurrentFrame():extensionTag {
name = 'templatestyles', args = { src = 'Module:Creo/Components/Infobox/styles.css' }
} .. infoboxLua.render( getInfoboxData( context ) )
end
return p