FANDOM


-- <pre> -- Module - Data
--[=============================================================================[
Use this module contains various utility function to lookup, format, and return 
 information from its database sub-modules.
]=============================================================================]
 
local getArgs = require('Dev:Arguments').getArgs
 
--=======================================
--[==[Data Tables]==]
 
-- Patch notes that have been archived on this wiki.
--   For the functions that use this to work correctly, the patches MUST be listed in reverse-chronological order. Add new patches to the beginning of this list.
local patches = {'1.51.5.7491', '1.51.5', '1.51.3.7395j', '1.51.3.7395i', '1.51.3.7395h', '1.51.3.7395g', '1.51.3.7395f', '1.51.3.7395e', '1.51.3.7395d', '1.51.3.7395c', '1.51.3.7395b', '1.51.3.7395', '1.51.3.7338d', '1.51.3.7338c', '1.51.3.7338b', '1.51.3.7338', '1.51.3', '1.51.0.7198k', '1.51.0.7198j', '1.51.0.7198i', '1.51.0.7198h', '1.51.0.7198g', '1.51.0.7198f', '1.51.0.7198e', '1.51.0.7198d', '1.51.0.7198c', '1.51.0.7198b', '1.51.0.7198', '1.51', '1.50.0.7103i', '1.50.0.7103h', '1.50.0.7103g', '1.50.0.7103f', '1.50.0.7103e', '1.50.0.7103d', '1.50.0.7103c', '1.50.0.7103b', '1.50.0.7103', '1.50', '1.49.0.7017f', '1.49.0.7017e', '1.49.0.7017d', '1.49.0.7017c', '1.49.0.7017b', '1.49.0.7017', '1.49', '1.48.0.6918h', '1.48.0.6918g', '1.48.0.6918f', '1.48.0.6918e', '1.48.0.6918d', '1.48.0.6918c', '1.48.0.6918b', '1.48.0.6918', '1.48', '1.47.2c', '1.47.2b', '1.47.2', '1.47.1.6863', '1.47.1', '1.47', '1.46.10b', '1.46.10', '1.46.8.6730c', '1.46.8.6730b', '1.46.8.6730', '1.46.7.6693', '1.46.6.6648e', '1.46.6.6648d', '1.46.6.6648c', '1.46.6.6648b', '1.46.6.6648', '1.46.2.6516d', '1.46.2.6516c', '1.46.2.6516b', '1.46.2.6516', '1.46.2', '1.46.1', '1.46', '1.45.1.6394b', '1.45.1.6394', '1.45.1', '1.45.0.6365', '1.45', '1.44.0.6287', '1.44', '1.43.0.6195', '1.43.0.6161', '1.43', '1.42.5', '1.42.3', '1.42.2.6052', '1.42.2', '1.42.1', '1.42', '1.41.4', '1.41.2', '1.40', '1.39.1', '1.39', '1.38', '1.37.5', '1.37.4', '1.37.3', '1.37', '1.36.5', '1.36.4', '1.36','1.35.2', '1.35', '1.31.8', '1.31.6', '1.31.5', '1.31', '1.30', '1.29', '1.28.7', '1.28', '1.27', '1.26.5', '1.26.3', '1.26.2', '1.26.1', '1.26', '1.25.6', '1.25', '1.24', '1.23.4', '1.23', '1.22.4', '1.22.3', '1.22', '1.21', '1.20.2', '1.20', '1.19.2', '1.19', '1.18.2', '1.18', '1.17.3', '1.17', '1.16', '1.15', '1.14.1', '1.14', '1.13', '1.12', '1.11', '1.10.2', '1.10', '1.9.1', '1.9', '1.8.3', '1.8.2', '1.8.1', '1.8', '1.7.4', '1.7.3'}
 
local sets = {
    -- expansions
    large = {
        { name = "The Empty Throne (Set 0)", SetNumber  = 0 },
        { name = "The Empty Throne", SetNumber  = 1 },
        { name = "Omens of the Past", SetNumber  = 2 },
        { name = "The Dusk Road", SetNumber  = 3 },
        { name = "The Fall of Argenport", SetNumber  = 4 },
        { name = "Defiance", SetNumber  = 5 },
        { name = "Dark Frontier", SetNumber  = 6 },
        { name = "The Flame of Xulta", SetNumber  = 7 },
        { name = "Echoes of Eternity", SetNumber  = 8 },
        { name = "Argent Depths", SetNumber  = 9 },
    },
    -- campaigns & bundle sets
    small = {
        { name = "Jekk's Bounty", SetNumber  = 1001 },
        { name = "The Tale of Horus Traver", SetNumber  = 1002 },
        { name = "Dead Reckoning", SetNumber  = 1003 },
        { name = "Into Shadow", SetNumber  = 1004 },
        { name = "Homecoming", SetNumber  = 1005 },
        { name = "The Trials of Grodov", SetNumber  = 1006 },
        { name = "Promises by Firelight", SetNumber  = 1007 },
        { name = "Whispers of the Throne", SetNumber  = 1085 },
        { name = "Shadow of the Spire", SetNumber  = 1087 },
        { name = "Awakening", SetNumber  = 1095 },
    }
}
 
--=======================================
--[==[Non-Invokable Functions]==]
 
-- Create a table of another table's keys
function keysToTable(t)
    local keyset={}
    local n=0
 
    for k,v in pairs(t) do
        n=n+1
        keyset[n]=k
    end
 
    return keyset
end
 
--=======================================
--[==[Invokable Functions]==]
-- These Frame Object functions can be called from a wiki article or template 
--   with the syntax: {{#invoke:ModuleName|functionName|arg1|arg2|...}}
local p = {}
 
-- {{#invoke:Data|cardCount|set=<<SetName>>}}
-- Returns a count of the cards in the requested set "<<SetName>>",
-- Both a total, and a breakdown by rarity.
-- Requires an up-to-date database module page for the set, under "/Module:Data/<<SetName>>"
function p.cardCount(frame)
    local args = getArgs(frame)
 
    local set = args.set or args[1] or ''
    local data = mw.loadData("Module:Data/"..set)
    if data then else return [[Error, the set named in the "set" parameter is misspelled or its data doesn't exit.]] end
 
    local rarities = {Common = 0, Uncommon = 0, Rare = 0, Legendary = 0, Promo = 0, None = 0, Noncollectible = 0,}
 
    local types = {}
    types['Unit'] = 0
    types['Spell'] = 0
    types['Fast Spell'] = 0
    types['Weapon'] = 0
    types['Relic Weapon'] = 0
    types['Curse'] = 0
    types['Cursed Relic'] = 0
    types['Relic'] = 0
    types['Power'] = 0
    types['Site'] = 0
    types['Attachment'] = 0
 
    for _,card in pairs(data) do
        local rarity = card.Rarity
        local ctype = card.Type
        if rarities[rarity] then rarities[rarity] = rarities[rarity] + 1 end
        if types[ctype] then types[ctype] = types[ctype] + 1 end
    end
 
    if rarities.Noncollectible == 0 then rarities.Noncollectible = rarities.None end
 
    local total = rarities.Common + rarities.Uncommon + rarities.Rare
                    + rarities.Legendary + rarities.Promo -- + rarities.None
 
    types['Spell'] = types['Spell'] + types['Fast Spell']
    types['Attachment'] = types['Attachment'] 
        + types['Weapon'] + types['Relic Weapon'] + types['Curse']
        + types['Cursed Relic'] + types['Relic']
 
    result = "''" .. set .. "'' currently contains " .. total .. " collectible cards.<br>"
            .. "This includes " .. rarities.Common .. " Commons, "
                                .. rarities.Uncommon .. " Uncommons, "
                                .. rarities.Rare .. " Rares, "
                                .. rarities.Legendary .. " Legendaries, and "
                                .. rarities.Promo .. " Promos.<br>"
 
            .. "It has "        .. types.Power .. " Power, "
                                .. types.Unit .. " Units, "
                                .. types.Spell .. " Spells, "
                                .. types.Attachment .. " Attachments, and "
                                .. types.Site .. " Sites.<br>"                                
            .. rarities.Noncollectible .. " non-collectible cards were introduced in this set.<br>"
            .. "<small>''Note: these numbers are based on the data found in Module:Data/"
            .. set .. ". The information may be incorrect if the database has errors or is out of date.''</small>"
 
    return result
end
 
-- {{#invoke:Data|cardStats|set=<<SetName>>|card=<<CardName>>|stat=<<StatName>>}}
-- Returns a <pre>-wrapped list of all the array info present for the card "<<CardName>>" in the set "<<SetName>>",
-- Requires an up-to-date database module page for the set, under "/Module:Data/<<SetName>>"
-- The optional "stat" parameter may be used to only return a specific card stat
function p.cardStats(frame)
    local args = getArgs(frame)
 
    local set = args.set or ''
    local card = args.card or ''
    if set == '' or card == '' then return 'Error, "set" and "card" parameters are required!' end
 
    local stat = args.stat
 
    local data = mw.loadData("Module:Data/"..set)
 
    if data then else return [[Error, the set named in the "set" parameter is misspelled or its data doesn't exit.]] end
 
    local cardInfo = data[card]
 
    if cardInfo then else return [[Error, the card named in the "card" parameter is misspelled or its data doesn't exit in the database for ]] .. set .. '.' end
 
    local result = ''
 
    if stat then
        result = cardInfo[stat] or 'That stat is missing!'
    else
        for i,v in pairs(cardInfo) do
            result = result .. '[' .. i .. '] = ' .. v .. '\n'
        end 
    end
 
    -- if the optional "prewrap" parameter is used, with the input "true",
    -- prevent wikitext conversion & wrap in pre tags
    local prewrap = args.prewrap or ''
    if prewrap == 'true' then
    -- prevent wikitext conversion & wrap in pre tags
        result = mw.text.nowiki(result)
        result = "<pre>" .. result .. "</pre>"
    end
 
    return result
end
 
-- {{#invoke:Data|makeCardList|set=<<SetName>>}}
-- Returns a <pre>-wrapped list of the names of all cards in the set "<<SetName>>", to add to or update Module:CardList/Sets
-- Requires an up-to-date database module page for the set, under "/Module:Data/<<SetName>>"
function p.makeCardList(frame)
    local args = getArgs(frame)
 
    local set = args.set or ''
    if set == '' then return 'Error, "set" parameters is required!' end
 
    local rarity = args.rarity or ''
 
    local data = mw.loadData("Module:Data/"..set)
    if data then else return [[Error, the set named in the "set" parameter is misspelled or its data doesn't exit.]] end
 
    local result = [[
data["]] .. set .. [["] = {]]
 
    for i,v in pairs(data) do
        if rarity == '' then
            result = result .. '\n    "' .. i .. '",'
        else
            if v.Rarity == rarity then
                result = result .. '\n    "' .. i .. '",'
            end
        end
    end
 
    result = result .. '\n}'
    result = "<pre>" .. result .. "</pre>"
 
    return result
end 
 
function p.newCardPageTEST(frame)
    local args = getArgs(frame)
 
    local set = args.set or ''
    local card = args.card or mw.title.getCurrentTitle().text or ''
    local patch = args.patch or ''
    if set == '' or patch == '' then return 'Error, the "set" and "patch" parameters are required!' end
 
    return card
end
 
-- New page assistant
--   {{#invoke:Data|newCardPage|set=<<SetName>>|card=<<CardName>>|patch=<<#.##>>}}
-- Returns pre-formatted wikitext, which can then be copy/pasted into a new card page's
--   source editor to create the new page. Some minor tweaking will be required, such 
--   as creating links or adding keywords & tokens to the CardInfobox parameters.
-- Requires an up-to-date database module page for the set, under "/Module:Data/<<SetName>>"
function p.newCardPage(frame)
 
    local args = getArgs(frame) -- clean the arguments using Module:Arguments on the dev wiki
 
    local set = args.set
    local setType = args.setType or 'expansion'
    local card = args.card or mw.title.getCurrentTitle().text
    local patch = args.patch
    if not set or not patch then return 'Error, the "set" and "patch" parameters are required!' end
 
    local data = assert(mw.loadData("Module:Data/"..set), [[Error, the set named in the "set" parameter is misspelled or its data doesn't exit.]])
 
    local cardInfo = assert(data[card], [[Error, the card named in the "card" parameter is misspelled or its data doesn't exit in the database for ]] .. set .. [[. If "card" wasn't specified, this page's name is used as the default value.]])
 
    local attachments = { ["Weapon"] = '', ["Curse"] = '', ["Relic"] = '', ["Relic Weapon"] = '', ["Cursed Relic"] = '',}
 
    local cardtype = (cardInfo.Type or '')
 
    -- custom history section release text (ex. for draft previews)
    local release = args.release
 
    local function parseType()
        if cardtype == 'Unit' then
            local unitTypes =  [=[
 
 | type          = Unit
 | subtype       = ]=] .. (cardInfo.UnitType or '')
            if cardInfo.Hero then 
                unitTypes = unitTypes .. [=[
 
 | hero          = ]=] .. cardInfo.Hero
            end
            return unitTypes
 
        elseif cardtype == 'Fast Spell' then
            return [=[
 
 | type          = Spell
 | subtype       = Fast Spell]=]
 
        elseif attachments[cardtype] then
            return [=[
 
 | type          = Attachment
 | subtype       = ]=] .. cardtype
 
        else
            return "\n | type          = " .. cardtype
 
        end
    end
 
    local function powerCheck()
        if cardtype ~= 'Power' then
            return "\n | cost          = " .. (cardInfo.Cost or '')
        else return ''
        end
    end
 
    local function parseInfluence()
        if cardtype ~= 'Power' then
            return "\n | requirements  = " .. (cardInfo.Influence or '') 
 
        else
            return "\n | factions      = " .. (cardInfo.Factions or '') 
 
        end
    end
 
    local function heroCheck()
        if cardInfo.Hero == 'true' then return '[[Hero]] '  end 
    end
 
    local function parseStats()
        if (cardtype == 'Unit' or cardtype == 'Weapon' or cardtype == 'Relic Weapon') then
            return "\n | strength      = " .. (cardInfo.Attack or '')
                .. "\n | health        = " .. (cardInfo.Health or '')
 
        elseif cardtype == 'Site' then
            return "\n | durability    = " .. (cardInfo.Durability or cardInfo.Health or '')
 
        else
            return ''
        end
    end
 
    local function parseText()
        local result = ''
 
        if cardInfo.CardText and cardInfo.CardText ~= '' then
            result = result .. "\n | text          = " .. cardInfo.CardText
        end
 
        if cardInfo.Keywords and cardInfo.Keywords ~= '' then
            result = result .. "\n | keywords      = " .. cardInfo.Keywords
        end
 
        if cardInfo.Tokens and cardInfo.Tokens ~= '' then
            result = result .. "\n | tokens        = " .. cardInfo.Tokens
        end
 
        return result
    end
 
    local function parseAlt()
        if cardInfo.AltArt == 'true' then
            return "\n | altart        = true"
        else return ''
        end
    end
 
    local function parseID()
        if cardInfo.EternalID and cardInfo.EternalID ~= 0 then
            return "\n | cardnumber    = " .. cardInfo.EternalID
        else return ''
        end
    end
 
    local function ncCheck()
        if cardInfo.Rarity == 'Noncollectible' then return " as a noncollectible token" end
    end
 
    local function releaseCheck()
        if release then
            return (ncCheck() or '') .. release
        else 
            return "Released" .. (ncCheck() or '') .. " in ''" .. set .. "''."
        end
    end
 
    -- temporary function, should break out into its own function or module
    -- premium costs only for now, for campaign/bundle set HtG sections
    local function craftingCost(rarity)
        local costs = {
            -- ["common"] = "100",
            -- ["uncommon"] = "200",
            -- ["rare"] = "800",
            -- ["legendary"] = "3200",
            ["common"] = "800",
            ["uncommon"] = "1600",
            ["rare"] = "3200",
            ["legendary"] = "9600",
        }
        return costs[string.lower(rarity)]
    end
 
    local function howToGet()
 
        if string.lower(setType) == "campaign" then
            return "After purchasing the ''[[" .. set .. [=[]]'' [[campaign]], beating its ''MISSIONNAME'' story mission unlocks a playset of {{PAGENAME}}.
 
Premium versions of {{PAGENAME}} also unlock if the premium campaign is purchased. Without it, the premium cards can be [[crafted]] for {{i|Shiftstone}}]=] .. craftingCost(cardInfo.Rarity) .. [=[ [[Shiftstone]] each, after being unlocked in the mission."]=]
 
        elseif string.lower(setType) == "bundle" then
            return "Purchasing the ''[[" .. set .. [=[]]'' Bundle, Premium Bundle, or Legendary Bundle from the in-game store unlocks a playset of {{PAGENAME}}.
 
Premium versions of {{PAGENAME}} also unlock if the premium bundles are purchased. Without it, the premium cards can be [[crafted]] for {{i|Shiftstone}}]=] .. craftingCost(cardInfo.Rarity) .. [=[ [[Shiftstone]] each after the regular bundle is purchased."]=]
 
        else
            return "{{Crafting|" .. (cardInfo.Rarity or '') .. [=[|]=] .. set .. "}}"
        end
    end
 
    local function createdBy()
        if cardInfo.CreatedBy then return '\n\n' .. 
[=[
=== Created By ===
{{cb|]=] .. cardInfo.CreatedBy .. [=[}}]=]
        end 
    end
 
    local function altArt()
        if cardInfo.AltArt == 'true' then return '\n\n' .. 
[=[
=== Alternate Art ===
''Needs how-to-get description!'']=]
        end 
    end
 
    local result = [=[
{{CardInfobox]=] .. 
"\n | set           = " .. set
 .. parseID()
 .. parseAlt() ..
"\n | rarity        = " .. (cardInfo.Rarity or '') 
 .. parseType()
 .. powerCheck()
 
 .. parseInfluence()
 .. parseStats()
 .. parseText() .. -- includes keyword and tokens parameters
"\n | artist        = " .. (cardInfo.Artist or '') .. 
"\n | voiceactor    = " .. (cardInfo.VoiceActor or '') .. [=[
 
 | flavor        = 
}}
'''{{PAGENAME}}''' is a ]=] .. (heroCheck() or '') .. '[[' .. (string.lower(cardInfo.Type) or '') .. [=[]] card.
 
== How to Get ==
]=] .. howToGet()
    .. (createdBy() or '')
    .. (altArt() or '') .. '\n\n' .. 
[=[
== Strategy ==
Nothing here yet!
 
{{hs|
{{hi|]=] .. patch .. "|" .. releaseCheck() .. "}}\n}}"
 
 
    -- if the optional "prewrap" parameter is used, with the input "true",
    -- prevent wikitext conversion & wrap in pre tags
    local prewrap = args.prewrap or ''
    if prewrap == 'true' then
    -- prevent wikitext conversion & wrap in pre tags
        result = mw.text.nowiki(result)
        result = "<pre>" .. result .. "</pre>"
    end
 
    return result
end
 
-- {{#invoke:Data|version|get=<<SetName>>}}
-- Returns either:
--   * the current patch version, or
--   * the previous or next version of a given version
-- The "get" parameter requires the input "current", "previous", or "next".
-- Requires the "patches" table in this module to be up-to-date.
function p.version(frame)
    --local versions = table.sort(patches)
 
    local args = getArgs(frame)
 
    local get = args.get or ''
    if get == '' then return '' end -- return nothing if 'get' isn't specified
    get = string.lower(get)
 
    local v = args.v or ''
 
--    local max = patches[table.maxn(patches)]
    local max = patches[1]
--    local max = 0
 
--    for _,v in pairs(patches) do
--      if type(v) == 'number' and v > max then max = v end
--    end
 
    if get == 'current' then -- Return most recent NQmod version
      return max
 
    elseif get == 'previous' or  get == 'next' then
      if v == '' then return '' end -- return nothing if 'v' isn't specified
      if v == 'Current' then -- set to most recent version if 'v' is 'Current' 
          v = max            -- (i.e. the "Patch Notes/Current" page)
      end
      local index = ''
 
      for i,patch in pairs(patches) do
          if v == patch then index = i break end
      end
 
      if index == '' then return '' end -- return nothing if 'v' isn't listed in 'patches'
 
      if get == 'previous' then
        index = index + 1
      elseif get == 'next' then
        index = index - 1
      end
 
      return patches[index]
    else
      return '' -- return nothing if 'get' isn't 'current', 'previous', or 'next'
    end
end
 
-- return most recent set from the 'sets' data tables
function p.currentSet(frame)
    local args = getArgs(frame)
 
    local setType = args['type'] or args[1] or 'Expansion'
    setType = string.lower(setType)
 
    local queryLarge = {
        expansion = '', 
        large = ''
    }
    local querySmall = {
        campaign = '', 
        bundle = '', 
        small = ''
    }
 
    local s, i
    if queryLarge[setType] then
        s = sets.large
        i = #s
    elseif querySmall[setType] then
        s = sets.small
        i = #s
    else
        error("The set-type 'type' parameter is an invalid value.")
    end
    return s[i].name
end
 
-- test to make sure patch order is sorted correctly by 'table.sort(patches)'
function p.testPatchList()
    local versions = table.sort(patches)
 
    local result = ''
    for _,v in pairs(patches) do
      result = result .. v .. '\n'
    end
 
    return "<pre>" .. result .. "</pre>"
end
 
-- -----------------------------------------------------
return p
-- </pre> [[Category:Eternal Wiki Modules]]
Community content is available under CC-BY-SA unless otherwise noted.