|
|
Line 1: |
Line 1: |
− | -- Import modules
| + | {{Navigation}} |
− | TableTools = require('Module:TableTools')
| |
− | local Locale = require('Module:Card/Locale')
| |
− | local Type = require('Module:Card/Type')
| |
| | | |
− | -- Generic function for replacing parameters within a string
| + | * This card's ''[[TCG]]'' name is a transliteration of the Japanese word for "eye man". |
− | -- Might move to module of its own.
| |
− | -- @param message string
| |
− | -- @param params table
| |
− | -- @return string
| |
− | function replaceParams(message, params)
| |
− | for param, replacement in pairs(params) do
| |
− | message = string.gsub(message, '{$' .. param .. '}', replacement)
| |
− | end
| |
| | | |
− | return message
| + | * This monster has a [[recolored counterpart|recolored]] [[Flip monster]] counterpart: "[[Hiro's Shadow Scout]]". |
− | end
| |
| | | |
− | -- Capitalize the first letter in a string
| + | * This card is one of eight of [[Joey Wheeler]]'s [[Normal Monster]]s introduced to the ''[[TCG]]'' in ''[[Legendary Collection 4: Joey's World Mega Pack]]'' that have their English [[flavor text]]s written in his [[wikipedia:Brooklyn|Brooklyn]] accent. The other seven are "[[Anthrosaurus]]", "[[Hero of the East]]", "[[Kageningen]]", "[[Little D]]", "[[Skull Stalker]]", "[[Stone Armadiller]]", and "[[Wolf]]". ("[[Alligator's Sword]]", which is included in ''Legendary Collection 4: Joey's World Mega Pack'' but debuted in the ''TCG'' previously, also has this kind of English flavor text.) |
− | -- @param text string
| + | ** All of these cards are seen in Joey's very first [[Deck]], except for "Hero of the East" (which is only seen when Joey has a dream of himself with his inexperienced Deck) and "Little D" (which has not appeared in the anime). |
− | -- @return string
| + | ** In Italian, Portuguese and Spanish, these cards' flavor texts are also written in [[wikipedia:Eye dialect|eye dialect]] for the sake of humor. Apart from the French text which is translated more directly from the Japanese text in a little more serious way, texts in other ''TCG'' languages appear to be translated from the English text. |
− | function ucfirst(text)
| |
− | return text:sub(1,1):upper() .. text:sub(2)
| |
− | end
| |
− | | |
− | -- Create an empty Card object
| |
− | local Card = {
| |
− | cardType = nil,
| |
− | property = nil,
| |
− | attribute = nil,
| |
− | types = {},
| |
− | isNormalMonster = nil,
| |
− | isEffectMonster = nil,
| |
− | isPendulumMonster = nil,
| |
− | level = nil,
| |
− | linkArrows = {},
| |
− | atk = nil,
| |
− | def = nil,
| |
− | linkRating = nil,
| |
− | password = nil,
| |
− | effectTypes = {},
| |
− | locales = {
| |
− | en = {
| |
− | name = nil,
| |
− | lore = nil,
| |
− | pendulumEffect = nil,
| |
− | previousNames = {}
| |
− | }
| |
− | },
| |
− | customColor = nil,
| |
− | | |
− | -- Params for rendered output
| |
− | styles = {
| |
− | 'Module:Card/base.css'
| |
− | },
| |
− | main = false,
| |
− | images = {},
| |
− | rows = {},
| |
− | | |
− | -- Configuration options
| |
− | -- Overwrite these in modules that extend this one
| |
− | config = {
| |
− | baseClass = nil,
| |
− | colorCoded = true,
| |
− | defaultImage = 'Back-EN.png',
| |
− | enableMainLinks = true,
| |
− | icons = {
| |
− | level = '[[File:CG Star.svg|18px|alt=]]',
| |
− | unknownLevel = '[[File:CG Star Unknown.svg|18px|alt=]]',
| |
− | negativeLevel = '[[File:Negative Star.svg|18px|alt=]]',
| |
− | rank = '[[File:Rank Star.svg|18px|alt=]]',
| |
− | unknownRank = '[[File:Rank Star Unknown.svg|18px|alt=]]',
| |
− | | |
− | cardTypes = '[[File:{$cardType_uc}.svg|28px|alt=]]',
| |
− | properties = '[[File:{$property}.svg|28px|alt=]]',
| |
− | attributes = '[[File:{$attribute}.svg|28px|alt=]]',
| |
− | unknownAttribute = '[[File:UNKNOWN.svg|28px|alt=]]',
| |
− | types = nil,
| |
− | },
| |
− | langs = { 'en', 'fr', 'de', 'it', 'es', 'ja', 'ko' },
| |
− | -- Rows to show in the rendered output
| |
− | rows = {
| |
− | 'cardType',
| |
− | 'property',
| |
− | 'attribute',
| |
− | 'type',
| |
− | 'level',
| |
− | 'rank',
| |
− | 'pendulumScale',
| |
− | 'linkArrows',
| |
− | 'atkDef',
| |
− | 'atkLink',
| |
− | 'lore'
| |
− | },
| |
− | types = {
| |
− | type = {},
| |
− | summon = {},
| |
− | ability = {},
| |
− | tuner = {},
| |
− | pendulum = {},
| |
− | normal = {},
| |
− | effect = {},
| |
− | unknown = {},
| |
− | }
| |
− | }
| |
− | }
| |
− | | |
− | | |
− | -- Create a new card object
| |
− | -- @param args table
| |
− | function Card:new(args)
| |
− | -- Create a new instance of the class with all the default values
| |
− | local c = {}
| |
− | setmetatable(c, self)
| |
− | self.__index = self
| |
− | | |
− | -- Type class to accept values based on the card's config
| |
− | Type:setAllowedValues(self.config.types)
| |
− | | |
− | -- Fill with data from the arguments
| |
− | c.number = args.number
| |
− | c.property = args.property
| |
− | c:setCardType(args.card_type, args)
| |
− | c.property = args.property
| |
− | c.attribute = args.attribute
| |
− | c:setTypes(args.types)
| |
− | c:setLinkArrows(args.link_arrows)
| |
− | c.atk = args.atk
| |
− | c.def = args.def
| |
− | c.level = args.level
| |
− | c.rank = args.rank
| |
− | c.pendulumScale = args.pendulum_scale
| |
− | c.password = args.password
| |
− | | |
− | -- Set language related data
| |
− | c.locales = Locale:createMany(c.config.langs, args)
| |
− | c:setName(args.name)
| |
− | | |
− | c.customColor = args.color
| |
− | c:setMainLink(args.main)
| |
− | c:setImages(args.image)
| |
− | | |
− | -- Add template specific styles or use the ones from Module:Card
| |
− | table.insert(c.styles, args.templatestyles or 'Module:Card/styles.css')
| |
− | | |
− | -- Set parameters other than those supplied above
| |
− | -- Classes that inherit from this one can use this to set additional data
| |
− | c:setCustomArgs(args)
| |
− | return c
| |
− | end
| |
− | | |
− | -- Set the English name
| |
− | -- @param name string - The card's name. Default to the page name.
| |
− | function Card:setName(name)
| |
− | -- Check if a name was supplied
| |
− | if (name) then
| |
− | -- Use the supplied name as the card name
| |
− | self.locales.en.name = name
| |
− | else
| |
− | -- Get the name of the page
| |
− | local pageName = mw.title.getCurrentTitle().text
| |
− | | |
− | -- Use the page name before the first parenthesis as the card name.
| |
− | self.locales.en.name = mw.text.split(pageName, ' %(')[1]
| |
− | end
| |
− | end
| |
− | | |
− | -- Set the card type
| |
− | -- @param cardType string
| |
− | -- @param table args
| |
− | function Card:setCardType(cardType, args)
| |
− | -- If the card type is explicitly stated use that
| |
− | if (cardType) then
| |
− | self.cardType = cardType
| |
− | -- Default to 'Monster' if the arguments contain any monster properties
| |
− | elseif (args.atk or args.def or args.attribute or args.types) then
| |
− | self.cardType = 'Monster'
| |
− | end
| |
− | end
| |
− | | |
− | -- Set Types-related data by passing in the type string
| |
− | -- @param typesString string '/'-separated list of types as printed on the card
| |
− | function Card:setTypes(typesString)
| |
− | -- Blank everything and start from a clean slate
| |
− | self.isNormalMonster = false
| |
− | self.isEffectMonster = false
| |
− | self.isPendulumMonster = false
| |
− | self.types = {}
| |
− |
| |
− | if (typesString) then
| |
− | -- Split the type input by forward slash
| |
− | -- Allow spaces at either side of the slash
| |
− | local typeNames = mw.text.split(typesString, '%s*/%s*')
| |
− | | |
− | -- Set these values if their Types are anywhere in the array
| |
− | self.isNormalMonster = TableTools.inArray(typeNames, 'Normal')
| |
− | self.isEffectMonster = TableTools.inArray(typeNames, 'Effect')
| |
− | self.isPendulumMonster = TableTools.inArray(typeNames, 'Pendulum')
| |
− | | |
− | -- Fill the Types table with an object for each type.
| |
− | for _, typeName in pairs(typeNames) do
| |
− | table.insert(self.types, Type:new(typeName))
| |
− | end
| |
− | end
| |
− | end
| |
− | | |
− | -- Set the Link Arrows data
| |
− | -- Doing this will also set the Link Rating equal to the number of arrows
| |
− | -- @param linkArrowsInput string
| |
− | function Card:setLinkArrows(linkArrowsInput)
| |
− | -- Split the input by comma to form an array
| |
− | self.linkArrows = mw.text.split(linkArrowsInput or '', '%s*,%s*')
| |
− | | |
− | -- Link Rating is equal to the number of Link Arrows
| |
− | self.linkRating = #self.linkArrows
| |
− | end
| |
− | | |
− | -- Set the main link
| |
− | -- @param main string - manually specified main link.
| |
− | -- The link will determined automatically otherwise.
| |
− | function Card:setMainLink(main)
| |
− | -- If main links are not enabled, "main" is always `false`.
| |
− | if (not self.config.enableMainLinks) then
| |
− | self.main = false
| |
− | return
| |
− | end
| |
− | | |
− | -- If the input specifically says not to use a main link, "main" is `false`.
| |
− | if (TableTools.inArray({ 'no', 'none', 'false' }, main)) then
| |
− | self.main = false
| |
− | return
| |
− | end
| |
− | | |
− | -- If the main link is specifically provided, use that.
| |
− | if (main) then
| |
− | self.main = main
| |
− | table.insert(self.styles, 'Module:Hatnote/styles.css')
| |
− | return
| |
− | end
| |
− | | |
− | -- Get the page name, strip out parentheses text.
| |
− | local pageName = tostring(mw.title.getCurrentTitle())
| |
− | local cardName = mw.text.split(pageName, ' %(')[1]
| |
− | | |
− | -- If there's a difference, use the non-paretheses version as the main.
| |
− | if (pageName ~= cardName) then
| |
− | self.main = cardName
| |
− | table.insert(self.styles, 'Module:Hatnote/styles.css')
| |
− | return
| |
− | end
| |
− | | |
− | -- If "main" is not found at this point, assume there is none.
| |
− | self.main = false
| |
− | end
| |
− | | |
− | -- Set images data based on the input parameter
| |
− | -- @param string input
| |
− | function Card:setImages(input)
| |
− | -- Clear existing value
| |
− | self.images = {}
| |
− | | |
− | -- Default to backing image if no input
| |
− | input = input or self.config.defaultImage
| |
− | | |
− | -- Split input by new line for multiple artworks
| |
− | local inputLines = mw.text.split(input, '\n')
| |
− | | |
− | local previousArtwork = nil
| |
− | | |
− | -- For each line (artwork)
| |
− | for _, line in pairs(inputLines) do
| |
− | -- Ensure each item on the line ends with `;` to help pattern matching
| |
− | line = line .. ';'
| |
− | | |
− | -- Content before first `;` is the image
| |
− | local image = mw.text.split(line, ';')[1]
| |
− | | |
− | -- Content after `artwork::` in the params string is the artwork number.
| |
− | -- Defaults to 1
| |
− | local artwork = tonumber(line:match('; *artwork::([^;]-) *;') or 1)
| |
− | | |
− | -- Content after `thumb::` in the params string is the thumbnail
| |
− | -- Defaults to the full image
| |
− | local thumbnail = line:match('; *thumb::([^;]-) *;') or image
| |
− | | |
− | -- Content after `name::` in the params string is the artwork name
| |
− | local name = line:match('; *name::([^;]-) *;')
| |
− | | |
− | -- If the params string contains `current`, mark as the current image
| |
− | local isCurrent = line:match('; *current *;') ~= nil
| |
− | | |
− | -- If the artwork has the same base number as its predecessor
| |
− | -- its number is .1 higher than it
| |
− | if (previousArtwork ~= nil and math.floor(artwork) == math.floor(previousArtwork)) then
| |
− | artwork = previousArtwork + .1
| |
− | end
| |
− | | |
− | -- Add object to list of images
| |
− | table.insert(self.images, {
| |
− | image = image,
| |
− | thumbnail = thumbnail,
| |
− | artwork = artwork,
| |
− | name = name,
| |
− | isCurrent = isCurrent
| |
− | })
| |
− | | |
− | -- Prepare for the next iteration of the loop.
| |
− | previousArtwork = artwork
| |
− | end
| |
− | end
| |
− | | |
− | -- Function inherited classes can override to set additional parameters
| |
− | -- @param args table
| |
− | -- @return void
| |
− | function Card:setCustomArgs(args)
| |
− |
| |
− | end
| |
− | | |
− | -- Get the card's summon Type
| |
− | -- @return string
| |
− | function Card:getSummonType()
| |
− | -- Exit early, if not a monster
| |
− | if (self.cardType ~= 'Monster') then return nil end
| |
− | | |
− | -- loop through the Types until the Summon Type is found
| |
− | for _, type in pairs(self.types) do
| |
− | if (type.category == 'Summon') then
| |
− | return type.name
| |
− | end
| |
− | end
| |
− | | |
− | -- Summon Type was not found, return `nil`
| |
− | return nil
| |
− | end
| |
− | | |
− | -- Get the CSS class for the card's color
| |
− | -- (Does not include Pendulum)
| |
− | -- @return string
| |
− | function Card:getColorClass()
| |
− | -- If the card has a custom color, use that
| |
− | if (self.customColor) then
| |
− | return self.customColor .. '-card'
| |
− | end
| |
− | | |
− | -- If the card is not a monster, base the color on the card type
| |
− | if (self.cardType and self.cardType ~= 'Monster') then
| |
− | return string.lower(self.cardType) .. '-card'
| |
− | end
| |
− | | |
− | -- If the card has a Summon type (Fusion, Ritual, etc.),
| |
− | -- base the color on that
| |
− | local summonType = self:getSummonType()
| |
− | if (summonType) then
| |
− | -- Lowercase, replace spaces with dashes, append "-card"
| |
− | return string.gsub(string.lower(summonType), ' ', '-') .. '-card'
| |
− | end
| |
− | | |
− | -- If the card is an Effect Monster, base the color on that
| |
− | if (self.isEffectMonster) then
| |
− | return 'effect-card'
| |
− | end
| |
− | | |
− | -- If the card is a Normal Monster, base the color on that
| |
− | if (self.isNormalMonster) then
| |
− | return 'normal-card'
| |
− | end
| |
− | | |
− | -- If the color couldn't be determined above, use this as the default
| |
− | return 'blank-card'
| |
− | end
| |
− | | |
− | -- Get the variable CSS classes used in the HTML output
| |
− | -- Includes the main color class and the pendulum color class
| |
− | -- @return string
| |
− | function Card:getCssClass()
| |
− | local cssClass = ''
| |
− | | |
− | -- If there is a class to be used for all cards, add that
| |
− | if (self.config.baseClass) then
| |
− | cssClass = cssClass .. self.config.baseClass
| |
− | end
| |
− | | |
− | -- If the cards are color-coded, add more classes
| |
− | if (self.config.colorCoded) then
| |
− | cssClass = cssClass .. self:getColorClass()
| |
− |
| |
− | if (self.isPendulumMonster) then
| |
− | cssClass = cssClass .. ' pendulum-card'
| |
− | end
| |
− | end
| |
− |
| |
− | return cssClass
| |
− | end
| |
− | | |
− | -- Render an icon representing the card type
| |
− | -- @return string
| |
− | function Card:renderCardTypeIcon()
| |
− | -- If the card is not a Spell or Trap, exit early
| |
− | if (self.cardType ~= 'Spell' and self.cardType ~= 'Trap') then
| |
− | return ''
| |
− | end
| |
− | | |
− | -- String containing a pattern matching the card type icons
| |
− | local pattern = self.config.icons.cardTypes
| |
− | | |
− | -- If there's no pattern, don't try to render an icon.
| |
− | if (not pattern) then return '' end
| |
− | | |
− | -- Replace variables in the pattern.
| |
− | -- e.g. replace '{$cardType}' with 'Spell' if this is a Spell Card.
| |
− | local params = {
| |
− | cardType = self.cardType,
| |
− | cardType_uc = string.upper(self.cardType)
| |
− | }
| |
− | | |
− | return replaceParams(pattern, params)
| |
− | end
| |
− | | |
− | -- Render an icon representing the Property
| |
− | -- @return string
| |
− | function Card:renderPropertyIcon()
| |
− | -- If the card is not a Spell or Trap, exit early
| |
− | if (self.cardType ~= 'Spell' and self.cardType ~= 'Trap') then
| |
− | return ''
| |
− | end
| |
− | | |
− | -- String containing a pattern matching the property icons
| |
− | local pattern = self.config.icons.properties
| |
− | | |
− | -- If there's no pattern, don't try to render an icon.
| |
− | if (not pattern) then return '' end
| |
− | | |
− | -- Replace variables in the pattern.
| |
− | -- e.g. replace '{$cardType}' with 'Spell' if this is a Spell Card.
| |
− | local params = {
| |
− | cardType = self.cardType,
| |
− | property = self.property
| |
− | }
| |
− | | |
− | return replaceParams(pattern, params)
| |
− | end
| |
− | | |
− | -- Render an icon representing the Attribute
| |
− | -- @return string
| |
− | function Card:renderAttributeIcon()
| |
− | -- Exit early, if not a monster
| |
− | if (self.cardType ~= 'Monster') then return '' end
| |
− | | |
− | if (self.attribute == nil or self.attribute == '???') then
| |
− | return self.config.icons.unknownAttribute
| |
− | end
| |
− | | |
− | local pattern = self.config.icons.attributes
| |
− | | |
− | -- If there's no pattern, don't try to render an icon.
| |
− | if (not pattern) then return '' end
| |
− | | |
− | local params = {
| |
− | attribute = self.attribute
| |
− | }
| |
− | | |
− | return replaceParams(pattern, params)
| |
− | end
| |
− | | |
− | -- Render the list of Types as a string with links and separators
| |
− | -- @return string
| |
− | function Card:renderTypeString()
| |
− | -- Exit early, if not a monster
| |
− | if (self.cardType ~= 'Monster') then return end
| |
− | | |
− | -- Array containing links to each of the card's Types.
| |
− | local linkedTypes = {}
| |
− | | |
− | -- Loop through all the card's Types
| |
− | for _, type in pairs(self.types) do
| |
− | -- Create a pipe link and add it to the array.
| |
− | local linkedType = ('[[%s|%s]]'):format(type.pageName, type.name)
| |
− | table.insert(linkedTypes, linkedType)
| |
− | end
| |
− | | |
− | -- Join all elements in the array, separating them with slashes.
| |
− | return table.concat(linkedTypes, ' / ')
| |
− | end
| |
− | | |
− | -- Render the Level as star icons
| |
− | -- @return string
| |
− | function Card:renderLevelStars()
| |
− | -- Don't show for non-monsters
| |
− | if (self.cardType ~= 'Monster') then return '' end
| |
− | | |
− | -- Don't show for Xyz or Link monsters
| |
− | local summonType = self:getSummonType()
| |
− | if (TableTools.inArray({'Xyz', 'Link'}, summonType)) then return '' end
| |
− |
| |
− | local icons = self.config.icons
| |
− | | |
− | -- If unknown Level, just show a single instance of the unknown icon.
| |
− | if (self.level == nil or self.level == '?' or self.level == '???') then
| |
− | return icons.unknownLevel
| |
− | end
| |
− | | |
− | -- Now that unknown is out of the way, this can be cast as a number.
| |
− | local level = tonumber(self.level)
| |
− | | |
− | -- Exit early if the Level is 0
| |
− | if (level == 0) then return '' end
| |
− | | |
− | -- Use different icons if Level is positive or negative
| |
− | local icon = level >= 0 and icons.level or icons.negativeLevel
| |
− | | |
− | -- Repeat the same icon a number of times equal to the Level/Rank (stars)
| |
− | return '<span class="card-stars">' ..
| |
− | string.rep(icon, math.abs(level)) ..
| |
− | '</span>'
| |
− | end
| |
− | | |
− | -- Render the Rank as star icons
| |
− | -- @return string
| |
− | function Card:renderRankStars()
| |
− | -- Exit early, if not an Xyz Monster
| |
− | if (self:getSummonType() ~= 'Xyz') then return '' end
| |
− | | |
− | local icons = self.config.icons
| |
− | | |
− | -- If unknown Level/Rank, just show a single instance of the unknown icon.
| |
− | if (self.rank == nil or self.rank == '?' or self.rank == '???') then
| |
− | return icons.unknownRank
| |
− | end
| |
− | | |
− | -- Exit early if the Rank is 0
| |
− | if (self.rank == 0) then return '' end
| |
− | | |
− | -- Repeat the same icon a number of times equal to the Rank
| |
− | return '<span class="card-stars">' .. string.rep(icons.rank, self.rank) .. '</span>'
| |
− | end
| |
− | | |
− | -- Render a grid showing the Link Arrows
| |
− | -- @return string
| |
− | function Card:renderLinkMap()
| |
− | local gridPositions = {
| |
− | 'Top-Left', 'Top-Center', 'Top-Right',
| |
− | 'Middle-Left', 'Middle-Center', 'Middle-Right',
| |
− | 'Bottom-Left', 'Bottom-Center', 'Bottom-Right'
| |
− | }
| |
− | | |
− | -- `div` for a 3x3 grid
| |
− | local map = mw.html.create('div')
| |
− | map
| |
− | :css('display', 'inline-grid')
| |
− | :css('width', '36px'):css('height', '46px')
| |
− | :css('grid-template-rows', '12px 12px 12px')
| |
− | :css('grid-template-columns', '10px 15px 10px')
| |
− | | |
− | -- Add an element for each position in the grid
| |
− | for _, position in pairs(gridPositions) do
| |
− | if (position == 'Middle-Center') then
| |
− | -- Nothing in the center square
| |
− | map:wikitext(' ')
| |
− | else
| |
− | -- Arrow will be highlighted in in the list of Link Arrows
| |
− | local active = TableTools.inArray(self.linkArrows, position)
| |
− | | |
− | -- These two images have a different width than the others
| |
− | local size = TableTools.inArray({ 'Top-Center', 'Bottom-Center' }, position) and 'x10px' or '10px'
| |
− | | |
− | -- Form the file name
| |
− | -- Remove '-' from the position name, add "2" if the position is inactive
| |
− | local file = 'LM-' .. (position:gsub('-', '')) ..(not active and '2' or '') .. '.png'
| |
− | map:wikitext('[[File:' .. file .. '|' ..size .. '|alt=]]')
| |
− | end
| |
− | end
| |
− | | |
− | return tostring(map)
| |
− | end
| |
− | | |
− | -- Render the card image section
| |
− | -- Either a single image or a switcher for multiple images
| |
− | -- @return string
| |
− | function Card:renderImages()
| |
− | -- If there's only one image, show it
| |
− | if (#self.images == 1) then
| |
− | return '[[File:' .. self.images[1].image .. '|200px]]'
| |
− | end
| |
− | | |
− | -- Create the HTML for the image switcher wrapper
| |
− | local imageSwitcher = mw.html.create('div')
| |
− | imageSwitcher
| |
− | :addClass('switcher-container')
| |
− | :css('margin', '0 auto')
| |
− | :css('max-width', '200px')
| |
− | :css('text-align', 'left')
| |
− | | |
− | -- Add a child element for each image and its label
| |
− | for _, image in pairs(self.images) do
| |
− | local title = image.name or ('Artwork ' .. image.artwork)
| |
− | local imageDisplay = '[[File:' .. image.image .. '|200px|alt=' .. title .. ']]'
| |
− | local labelHtml = mw.html.create('div')
| |
− |
| |
− | labelHtml:attr('class', 'switcher-label'):wikitext(title)
| |
− |
| |
− | if (image.isCurrent) then
| |
− | labelHtml:attr('data-switcher-default', 'true')
| |
− | end
| |
− | | |
− | imageSwitcher
| |
− | :tag('div')
| |
− | :css('margin-bottom', '5px')
| |
− | :wikitext(imageDisplay .. tostring(labelHtml))
| |
− | end
| |
− | | |
− | return tostring(imageSwitcher)
| |
− | end
| |
− | | |
− | -- Add something to the list of rows to be rendered in the output
| |
− | -- @param string label - Text to display in the label cell
| |
− | -- @param string value - Text/icons to display in the data cell
| |
− | function Card:addRow(label, value)
| |
− | if (value) then
| |
− | table.insert(self.rows, { label = label, value = value })
| |
− | end
| |
− | end
| |
− | | |
− | -- Add row specifically for the Number
| |
− | function Card:addNumberRow()
| |
− | self:addRow('Number', self.number)
| |
− | end
| |
− | | |
− | -- Add a row specifically for the card type to be rendered in the output
| |
− | function Card:addCardTypeRow()
| |
− | if (self.cardType == nil) then return end
| |
− | | |
− | local text = '[[' .. self.cardType .. ' Card|' .. self.cardType .. ']]'
| |
− | local icon = self:renderCardTypeIcon() or ''
| |
− | self:addRow('[[Card type]]', text .. ' ' .. icon)
| |
− | end
| |
− | | |
− | -- Add a row specifically for the property to be rendered in the output
| |
− | function Card:addPropertyRow()
| |
− | -- Exit early if no card type or property
| |
− | if (self.cardType == nil or self.property == nil) then return end
| |
− |
| |
− | local text = '[[' .. self.property .. ' ' .. self.cardType .. ' Card|' .. self.property .. ']]'
| |
− | local icon = self:renderPropertyIcon()
| |
− |
| |
− | self:addRow('[[Property]]', text .. ' ' .. icon)
| |
− | end
| |
− | | |
− | -- Add a row specifically for the Attribute to be rendered in the output
| |
− | function Card:addAttributeRow()
| |
− | -- If it's not a monster, don't continue
| |
− | if (self.cardType ~= 'Monster') then return end
| |
− | | |
− | local text = '[[' .. (self.attribute or '???') .. ']]'
| |
− | local icon = self:renderAttributeIcon()
| |
− | | |
− | self:addRow([[Attribute]], text .. ' ' .. icon)
| |
− | end
| |
− | | |
− | function Card:addTypeRow()
| |
− | -- If it's not a monster, don't continue
| |
− | if (self.cardType ~= 'Monster') then return end
| |
− |
| |
− | self:addRow('[[Type]]s', self:renderTypeString())
| |
− | end
| |
− | | |
− | -- Add a row specifically for the Level to be rendered in the output
| |
− | function Card:addLevelRow()
| |
− | -- Don't show for non-monsters
| |
− | if (self.cardType ~= 'Monster') then return end
| |
− | | |
− | -- Don't show for Xyz or Link monsters
| |
− | local summonType = self:getSummonType()
| |
− | if (TableTools.inArray({'Xyz', 'Link'}, summonType)) then return end
| |
− | | |
− | self:addRow('[[Level]]', (self.level or '???') .. ' ' .. self:renderLevelStars())
| |
− | end
| |
− | | |
− | -- Add a row specifically for the Rank to be rendered in the output
| |
− | function Card:addRankRow()
| |
− | -- Only show for Xyz Monsters
| |
− | if (self:getSummonType() ~= 'Xyz') then return end
| |
− | | |
− | self:addRow('[[Rank]]', (self.rank or '???') .. ' ' .. self:renderRankStars())
| |
− | end
| |
− | | |
− | function Card:addLinkArrowsRow()
| |
− | -- Not a Link Monster, exit early
| |
− | if (self:getSummonType() ~= 'Link') then
| |
− | return nil
| |
− | end
| |
− | | |
− | -- Cell contains the map showing the different arrows and a textual list
| |
− | -- Wrap the two in a flex div to vertically center them
| |
− | local cell = mw.html.create('div')
| |
− | cell
| |
− | :css('display', 'flex')
| |
− | :css('align-items', 'center')
| |
− | :css('gap', '.25em')
| |
− | :wikitext(self:renderLinkMap())
| |
− | :tag('div')
| |
− | :wikitext(table.concat(self.linkArrows, ', '))
| |
− | | |
− | self:addRow('[[Link Arrow]]s', tostring(cell))
| |
− | end
| |
− | | |
− | -- Add a row specifically for the Pendulum Scale
| |
− | function Card:addPendulumScaleRow()
| |
− | -- Only allow this row for Pendulum Monsters with a Pendulum Scale
| |
− | if (not self.isPendulumMonster or self.pendulumScale == nil) then
| |
− | return nil
| |
− | end
| |
− | | |
− | local icon = '[[File:Pendulum Scale.png|22px|alt=|class=noviewer]]'
| |
− | | |
− | self:addRow('[[Pendulum Scale]]', icon .. ' ' .. self.pendulumScale)
| |
− | end
| |
− | | |
− | -- Add a row specifically for ATK and DEF to be rendered in the output
| |
− | -- Only shows for monsters that are not Link Monsters
| |
− | function Card:addAtkDefRow()
| |
− | if (self.cardType ~= 'Monster' or self:getSummonType() == 'Link') then
| |
− | return nil
| |
− | end
| |
− | | |
− | local atk = self.atk or '???'
| |
− | local def = self.def or '???'
| |
− | | |
− | self:addRow('[[ATK]] / [[DEF]]', atk .. ' / ' .. def)
| |
− | end
| |
− | | |
− | -- Add a row specifically for ATK and Link to be rendered in the output
| |
− | -- Only shows for Link Monsters
| |
− | function Card:addAtkLinkRow()
| |
− | if (self:getSummonType() ~= 'Link') then
| |
− | return nil
| |
− | end
| |
− | | |
− | local atk = self.atk or '???'
| |
− | local link = self.linkRating or '???'
| |
− | | |
− | self:addRow('[[ATK]] / [[Link Rating|LINK]]', atk .. ' / ' .. link)
| |
− | end
| |
− | | |
− | -- Add a rowspecifically for the lore
| |
− | function Card:addLoreRow()
| |
− | local lore = self.locales.en:getFullLore(self.isNormalMonster)
| |
− | | |
− | if (lore == nil or lore == '') then return end
| |
− |
| |
− | local loreHtml = mw.html.create('div')
| |
− | loreHtml:attr('class', 'lore')
| |
− | | |
− | if (self.locales.en.pendulumEffect) then
| |
− | -- Place Pendulum Effect and monster text in a description list
| |
− | local dl = mw.html.create('dl')
| |
− | dl:css('margin', '.5em')
| |
− | dl:tag('dt'):wikitext("'''Pendulum Effect'''")
| |
− | dl:tag('dd'):wikitext(self.locales.en.pendulumEffect)
| |
− | dl:tag('dt'):wikitext("'''Monster text'''")
| |
− | dl:tag('dd'):wikitext(lore)
| |
− | | |
− | loreHtml:wikitext(tostring(dl))
| |
− | else
| |
− | -- Place lore in a single paragraph in the
| |
− | loreHtml:tag('p'):wikitext(lore)
| |
− | end
| |
− | | |
− | self:addRow(nil, tostring(loreHtml))
| |
− | end
| |
− | | |
− | -- Add row specifically for the Password
| |
− | function Card:addPasswordRow()
| |
− | self:addRow('[[Password]]', self.password)
| |
− | end
| |
− | | |
− | -- Create a TemplateStyles tag
| |
− | function renderTemplateStyles(page)
| |
− | if (page == nil or page == '') then return end
| |
− |
| |
− | return tostring( mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = page } } )
| |
− | end
| |
− | | |
− | -- Generate the HTML output
| |
− | function Card:render()
| |
− | local output = ''
| |
− | | |
− | -- Add template styles
| |
− | for _, style in pairs(self.styles) do
| |
− | output = output .. '\n' .. renderTemplateStyles(style)
| |
− | end
| |
− | | |
− | if (self.main) then
| |
− | output = output .. '<div role="note" class="hatnote navigation-not-searchable">Main card page: "[[' .. self.main .. ']]"</div>'
| |
− | end
| |
− | | |
− | output = output .. '\n<div class="card-table ' .. self:getCssClass() .. '">'
| |
− | | |
− | output = output .. '\n <div class="heading">' .. self.locales.en.name .. '</div>'
| |
− | | |
− | output = output .. '\n <div class="card-table-columns">'
| |
− | output = output .. '\n <div class="imagecolumn">'
| |
− | output = output .. self:renderImages()
| |
− | output = output .. '\n </div>' -- .imagecolumn
| |
− | | |
− | output = output .. '\n <div class="infocolumn">'
| |
− | output = output .. '\n <table class="innertable">'
| |
− | | |
− | for _, row in pairs(self.rows) do
| |
− | output = output .. '\n<tr>'
| |
− | if (row.label) then
| |
− | output = output .. '\n <th scope="row" style="text-align: left;">' .. row.label .. '</th>'
| |
− | output = output .. '\n <td>' .. row.value .. '</td>'
| |
− | else
| |
− | output = output .. '\n <td colspan="2">' .. row.value .. '</td>'
| |
− | end
| |
− | output = output .. '\n</tr>'
| |
− | end
| |
− | | |
− | output = output .. '\n </table>'
| |
− | output = output .. '\n </div>' -- .infocolumn
| |
− | | |
− | output = output .. '\n </div>' -- .card-table-columns
| |
− | output = output .. '\n</div>' -- .card-table
| |
− | | |
− | output = output .. self:renderLocalesTable()
| |
− | | |
− | return output
| |
− | end
| |
− | | |
− | function Card:renderLocalesTable()
| |
− | -- Needs to have at least two languages
| |
− | -- i.e. Needs at least one language other than English
| |
− | if (TableTools.size(self.locales) < 2) then return '' end
| |
− |
| |
− | output = '\n==Other languages=='
| |
− | | |
− | output = output .. '\n<table class="wikitable">'
| |
− | output = output .. '\n <tr>'
| |
− | output = output .. '\n <th scope="col">Language</th>'
| |
− | output = output .. '\n <th scope="col">Name</th>'
| |
− | output = output .. '\n <th scope="col">Card text</th>'
| |
− | output = output .. '\n </tr>'
| |
− | | |
− | for _, locale in pairs(self.locales) do
| |
− | local langCode = locale:getHtmlLang()
| |
− | if locale.lang ~= 'en' then
| |
− | output = output .. '\n<tr>'
| |
− | output = output .. '\n <th scope="row">' .. locale.language.name .. '</th>'
| |
− | output = output .. '\n <td lang="' .. langCode .. '">' .. (locale.name or '') .. '</td>'
| |
− | output = output .. '\n <td lang="' .. langCode .. '">' .. (locale:getFullLore(self.isNormalMonster) or '') .. '</td>'
| |
− | output = output .. '\n</tr>'
| |
− | end
| |
− | end
| |
− | | |
− | output = output .. '</table>'
| |
− | | |
− | return output
| |
− | end
| |
− | | |
− | -- Function to be invoked by the module
| |
− | -- Takes all template parameters and returns the HTML
| |
− | function Card.card(frame)
| |
− | -- Get the template parameters
| |
− | local args = frame:getParent().args
| |
− | | |
− | -- Create a new card object
| |
− | local c = Card:new(args)
| |
− | | |
− | -- For each row configured to show, call the function to add it
| |
− | for _, row in pairs(c.config.rows) do
| |
− | c['add' .. ucfirst(row) .. 'Row'](c)
| |
− | end
| |
− | | |
− | -- Render the output
| |
− | return c:render()
| |
− | end
| |
− | | |
− | return Card
| |