Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
MediaWiki help
Creopedia
Search
Search
Appearance
Log in
Personal tools
Log in
View source for Module:Creo/Components/Evolution
Module
Discussion
English
Read
View source
View history
Tools
Tools
move to sidebar
hide
Actions
Read
View source
View history
General
What links here
Related changes
Special pages
Page information
Appearance
move to sidebar
hide
←
Module:Creo/Components/Evolution
require( 'strict' ) local getThumbnail = require( 'Module:Creo' ).getThumbnail local cardLua = require( 'Module:CardLua' ) local element = require( 'Module:Element' )._main local ec2GameData = require( 'Module:GameData/EvoCreo2' ) local p = {} --- Build the evolution data structure from the raw arguments --- --- @param args table --- @return table local function getEvolutionsData( args ) local tempNodes = {} for k, v in pairs( args ) do if type( k ) == 'string' then local parts = mw.text.split( k, '_' ) -- Example key: "creo_1_1_name" -> parts: {"creo", "1", "1", "name"} if parts[1] == 'creo' and #parts >= 3 then table.remove( parts, 1 ) -- Remove "creo" -> {"1", "1", "name"} local prop = table.remove( parts, #parts ) -- prop: "name", parts: {"1", "1"} -- We only care about name and content properties if prop == 'name' or prop == 'content' then local path = table.concat( parts, '_' ) -- path: "1_1" tempNodes[path] = tempNodes[path] or {} tempNodes[path][prop] = v end end end end local evolutions = {} local nodes = {} -- path -> final node map local sortedPaths = {} for path in pairs( tempNodes ) do table.insert( sortedPaths, path ) end table.sort( sortedPaths ) for _, path in ipairs( sortedPaths ) do local data = tempNodes[path] -- A node is only valid if it has a name. if data.name then local node = { name = data.name, content = data.content, evolutions = {} } local parentPath = path:match( '^(.*)_[^_]+$' ) if parentPath then local parentNode = nodes[parentPath] if parentNode then table.insert( parentNode.evolutions, node ) end else -- It's a root node table.insert( evolutions, node ) end nodes[path] = node end end return evolutions end --- How many nodes a parsed argument tree describes. --- --- Every Creo article was created with a stub that names only the Creo itself, --- with the content "Evolution text for <Name>". A lone root describes no --- family, so it is treated as unwritten and the tree comes from the game data --- instead; a page that does spell out its family keeps what was written. --- --- @param evolutions table|nil --- @return number local function countNodes( evolutions ) local total = 0 for _, node in ipairs( evolutions or {} ) do total = total + 1 + countNodes( node.evolutions ) end return total end --- Describe what triggers one evolution. --- --- The export only ever sets a level or an element affinity, but item and --- loyalty evolutions exist in the schema and are handled so a future export --- does not render a blank card. --- --- @param step table --- @return string|nil local function getConditionWikitext( step ) if step.element then return string.format( 'Maxed %s affinity', tostring( element( step.element ) ) ) end if step.level then return string.format( 'Evolves at Level %s', tostring( step.level ) ) end if step.item then return string.format( 'Evolves with %s', tostring( step.item ) ) end if step.loyalty then return string.format( 'Evolves at %s loyalty', tostring( step.loyalty ) ) end return nil end --- Build the family tree around the Creo whose article this is. --- --- The index only records where an evolution leads, so the parent map is --- rebuilt here in order to climb to the base form. Every member of a family --- then renders the same tree, with its own entry marked as the current one by --- getEvolutionListHtml. --- --- @param name string --- @return table local function getEvolutionsFromData( name ) local index = ec2GameData.getEvolutionIndex() or {} local parents = {} for parent, steps in pairs( index ) do for _, step in ipairs( steps ) do parents[step.name] = parent end end -- Climb to the base form. `seen` is paranoia: the export describes a tree -- today, and a cycle introduced later would otherwise hang the render. local root = name local seen = {} while parents[root] and not seen[root] do seen[root] = true root = parents[root] end --- @param creoName string --- @param content string|nil --- @return table local function build( creoName, content ) local node = { name = creoName, content = content, evolutions = {} } for _, step in ipairs( index[creoName] or {} ) do table.insert( node.evolutions, build( step.name, getConditionWikitext( step ) ) ) end return node end local content = 'Does not evolve' if index[root] then content = 'Base form' end return { build( root, content ) } end --- Return the wikitext for the evolution list item --- --- @param name string --- @param content string --- @return string local function getEvolutionListItemWikitext( name, content ) return cardLua.render( { title = name, page = name, description = content, thumbnail = getThumbnail( name ), thumbnailSize = '80px', class = 'cp-image-pixelated' } ) end --- Return the wikitext for the evolution list --- --- @param evolutions table --- @return mw.html|nil local function getEvolutionListHtml( evolutions ) if not evolutions or #evolutions == 0 then return nil end local currentPage = mw.title.getCurrentTitle().fullText local list = mw.html.create( 'ul' ):addClass( 't-creo-evolution-tree' ) for _, evoNode in ipairs( evolutions ) do local li = list:tag( 'li' ):addClass( 't-creo-evolution-tree-item' ) li:wikitext( getEvolutionListItemWikitext( evoNode.name, evoNode.content ) ) if evoNode.name == currentPage then li:addClass( 't-creo-evolution-tree-item--current' ) end local sublist = getEvolutionListHtml( evoNode.evolutions ) if sublist then li:node( sublist ) end end return list end --- Build the evolution list HTML recursively --- --- @param evolutions table --- @return mw.html local function getEvolutionsHtml( evolutions ) local html = mw.html.create( 'div' ) html :addClass( 't-creo-evolution' ) :tag( 'div' ) :addClass( 't-creo-evolution-wrapper' ) :node( getEvolutionListHtml( evolutions ) ) :done() return html end --- Return the wikitext for the evolution list --- --- @param context ComponentContext --- @return string function p.render( context ) local evolutions = getEvolutionsData( context.args or {} ) if countNodes( evolutions ) < 2 then evolutions = getEvolutionsFromData( mw.title.getCurrentTitle().text ) end return mw.getCurrentFrame():extensionTag { name = 'templatestyles', args = { src = 'Module:Creo/Components/Evolution/styles.css' } } .. tostring( getEvolutionsHtml( evolutions ) ) end return p
Templates used on this page:
Template:Documentation
(
view source
)
Module:Creo/Components/Evolution/doc
(
view source
)
Return to
Module:Creo/Components/Evolution
.