Module:ItemInfo

-- local p = {}

local getArgs = require('Module:Arguments').getArgs local loader = require('Module:Loader')

local yesno, color, statname, rarity, ability, slot = loader.require('Yesno', 'Color', 'Statname', 'RarityTier', 'Ability', 'Inventory slot')

local statData = mw.loadData('Module:Statname/Data')

local PAGENAME = mw.title.getCurrentTitle.text

local MODULE = 'ItemInfo' local DATA_MODULES = { -- ['Item'] = 'Item', ['Weapon'] = 'Weapon/Data', ['Armor Piece'] = 'Armor/Data', ['Armor'] = 'Armor/Data', } local TEMPLATES = { ['Item'] = 'ItemInfo', ['Weapon'] = 'ItemInfo', ['Armor Piece'] = 'ItemInfo', ['Armor'] = 'ArmorInfo', }

local VED_BUTTONS = 'V &bull; E &bull; D ' local NOT_USING_DATA_MODULE_BUTTON = '\'\'\'!\'\'\' ' local NOT_USING_DATA_MODULE_MESSAGE = 'It is recommended to use data located at Module:%s for this template. If it is not already present in the Module, you can add the following code to the data Module: %s \n\n:\'\'See Template:%s for more info on how to use the data Module.\'\''

local ARMORPIECEPREFIXES = { {'helmet', 'head', key = 'head'}, {'chestplate', 'chest', key = 'chest'}, {'leggings', 'legs', key = 'legs'}, {'boots', key = 'boots'}, } local MAXABILITIES = 3 local ABILITYTYPES = { {'ability', 'ia', 'ability'}, -- ability type in Module:Ability, table in Data modules, template parameter prefix {'piece', 'pcb', 'piece_bonus'}, {'full_set', 'fsb', 'full_set_bonus'}, {'tiered_armor', 'tab', 'tiered_armor_bonus'}, } local ABILITYPROPERTIES = { {'Soulflow Cost', 'soulflow_cost', color = 'dark_aqua'}, {'Mana Cost', 'cost', color = 'dark_aqua'}, {'Health Cost', 'health_cost', color = 'red'}, {'Coin Cost', 'coin_cost', color = 'gold'}, {'Cooldown', 'cd', color = 'green'}, {'Cooldown', 'cooldownAlt', color = 'dark_gray'}, {'Max Souls', 'max_souls', color = 'light_purple'}, -- not in game {'Armor Pieces Required', 'required_pieces', color = 'gray'}, {'Upgraded By', 'upgraded_by', color = 'green'}, }

local BLANK_CELL = ''

-- converts template arguments into a table following those in Module:Weapon/Data local function convertItemArguments(args) local data = { exists = yesno(args.exist or args.exists, true), type = args.type, name = args.name, slots = args.slot or args.slots, rarity = args.rarity, stats = {}, specialEffect = args.specialEffect or args.special_effects or args.special_effect or args.effects, }

-- stats for k, v in pairs(statData) do -- item stats data.stats[v.shortcode] = args[v.shortcode] -- or nil end

-- abilities for i = 1, MAXABILITIES, 1 do       local suffix = i ~= 1 and tostring(i) or ''

for _, abilityType in ipairs(ABILITYTYPES) do           if args[abilityType[3] .. '_name' .. suffix] then data[abilityType[2] .. suffix] = { name = args[abilityType[3] .. '_name' .. suffix], secret = yesno(args[abilityType[3] .. '_secret' .. suffix]), activation = args[abilityType[3] .. '_activation' .. suffix], req = args[abilityType[3] .. '_requirement' .. suffix] or args[abilityType[3] .. '_req' .. suffix], desc = args[abilityType[3] .. '_desc' .. suffix] or args[abilityType[3] .. '_description' .. suffix], }

for _, property in ipairs(ABILITYPROPERTIES) do                   data[abilityType[2] .. suffix][property[2]] = args[abilityType[3] .. '_' .. property[2] .. suffix] end end end

end

return data end

local function convertArmorArguments(args) local armorData = { head = {}, chest = {}, legs = {}, boots = {}, total = convertItemArguments(args), type = args.type, name = args.name, rarity = args.rarity, }

for _, pieceAliases in ipairs(ARMORPIECEPREFIXES) do	   for __, piece in ipairs(pieceAliases) do	        for k, v in pairs(args) do if k:find('^' .. piece) then armorData[pieceAliases.key][k:gsub(piece .. '_', '')] = v	           end end end end

for _, piece in ipairs(ARMORPIECEPREFIXES) do       armorData[piece.key] = convertItemArguments(armorData[piece.key]) end

return armorData end

local function getSlots(name, default) local slotsList = {}

if name and type(name) == 'table' then for _, slotName in ipairs(name) do           table.insert(slotsList, slot.slot{slotName}) end else table.insert(slotsList, slot.slot{name or default}) end return table.concat(slotsList, ' ') end

local function getStats(statsTable) if not statsTable then return end

local statsList = {}

for k, v in pairs(statsTable) do       table.insert(statsList, ('*%s: +%s'):format(statname.stat(k), tostring(v))) end return table.concat(statsList, '\n') end

local function getTotalStats(data) local statsTable = {} for _, piece in ipairs(ARMORPIECEPREFIXES) do       for k, v in pairs(data[piece.key] and data[piece.key].stats or {}) do	        statsTable[k] = (statsTable[k] and statsTable[k] + tonumber(v)) or tonumber(v) end end for k, v in pairs(data.total and data.total.stats or {}) do   	statsTable[k] = v    end

return getStats(statsTable) end

local function getEffects(data) if not data then return end local effectsList = {data.specialEffect or data.special_effects or data.effects or data.effect} for _, abilityType in ipairs(ABILITYTYPES) do       for i = 1, MAXABILITIES, 1 do            local suffix = i > 1 and tostring(i) or ''

if data[abilityType[2] .. suffix] then local itemAbility = data[abilityType[2] .. suffix]

local abilityString = { (ability._ability('%s', itemAbility.secret, abilityType[1]) .. ' %s%s %s'):format(                       itemAbility.name,                        itemAbility.activation and () or ,                        itemAbility.req and (' (Requires ' .. itemAbility.req .. ')') or ,                        itemAbility.desc or                     ) }

for _, property in ipairs(ABILITYPROPERTIES) do                   if itemAbility[property[2]] then table.insert(abilityString, (' ' .. color.makeColor('dark_gray', '%s:') .. ' %s'):format( property[1], color.makeColor(property.color, itemAbility[property[2]]) ))	               end end

table.insert(effectsList, table.concat(abilityString)) end end end

return table.concat(effectsList, ' ') end

local function notUsingDataModuleWarning(convertedTable, itemName, itemType) local tb = mw.dumpObject(convertedTable) :gsub('table#%d+ ', '') :gsub('%["', )       :gsub('"%]', ) :gsub(' ', '	') .. ','   local message = NOT_USING_DATA_MODULE_MESSAGE:format(DATA_MODULES[itemType], table.concat{'["' .. itemName:lower .. '"] = ', mw.text.nowiki(tb)}, TEMPLATES[itemType]) return NOT_USING_DATA_MODULE_BUTTON:format(DATA_MODULES[itemType], itemName:lower:gsub('%s', '-')), (' \n%s\n '):format(itemName:lower:gsub('%s', '-'), message) end

-- For single items function p.itemInfo(frame) local args = getArgs(frame) local type = args.itemtype return mw.getCurrentFrame:preprocess(p._itemInfo(type, args)) end

function p._itemInfo(itemType, args) local data local usingDataModule = true if args[1] then local dataModule = mw.loadData('Module:' .. DATA_MODULES[itemType]) data = dataModule[(args[1] or PAGENAME):lower] else data = convertItemArguments(args) usingDataModule = false end

local name = data.name or args[1] or PAGENAME local slots = getSlots(data.slot or data.slots, name) local stats = getStats(data.stats) local effects = getEffects(data) local notUsingDataModuleButton, notUsingDataModuleMessage = ,  if not usingDataModule then notUsingDataModuleButton, notUsingDataModuleMessage = notUsingDataModuleWarning(data, name, itemType) end

local wikitable = mw.html.create('table'):addClass('wikitable'):css('overflow', 'auto'):css('border-width', '2px 2px 2px 2px !important'):css('vertical-align', 'text-top'):css('max-width', '20em') wikitable:tag('tr'):css('border-width', '2px'):css('min-width', '150px') :tag('th'):attr('colspan', '2'):wikitext(notUsingDataModuleButton .. (data.type or itemType or 'Item') .. VED_BUTTONS:format(DATA_MODULES[itemType], DATA_MODULES[itemType], MODULE)):done :done :tag('tr') :tag('td'):addClass('ct'):wikitext(slots):done -- slot :tag('td'):wikitext(('%s \n%s'):format(rarity._link(data.rarity or 'c', name), stats or '')):done -- stats :done

if effects ~= '' then wikitable:tag('tr'):css('border-width', '2px') :tag('th'):attr('colspan', '2'):wikitext('Effects'):done :done :tag('tr') :tag('td'):attr('colspan', '2'):wikitext(effects):done -- effects :done end

wikitable:done return table.concat{notUsingDataModuleMessage, tostring(wikitable)} end

-- For Armor Sets function p.armorInfo(frame) local args = getArgs(frame)

return mw.getCurrentFrame:preprocess(p._armorInfo(args)) end

function p._armorInfo(args) local data local usingDataModule = true if args[1] then local dataModule = mw.loadData('Module:Armor/Data') data = dataModule[args[1]:lower or PAGENAME:lower] else data = convertArmorArguments(args) usingDataModule = false end

local armorName = data.name or args[1] or PAGENAME local pieces = { head = not data.head and false or data.head.exists, chest = not data.chest and false or data.chest.exists, legs = not data.legs and false or data.legs.exists, boots = not data.boots and false or data.boots.exists, }   local names = { head = data.head.name or armorName:gsub('Armor', data.head.label or 'Helmet'), chest = data.chest.name or armorName:gsub('Armor', data.chest.label or 'Chestplate'), legs = data.legs.name or armorName:gsub('Armor', data.legs.label or 'Leggings'), boots = data.boots.name or armorName:gsub('Armor', data.boots.label or 'Boots'), }   local slots = { head = getSlots(data.head.slot or data.head.slots, names.head), chest = getSlots(data.chest.slot or data.chest.slots, names.chest), legs = getSlots(data.legs.slot or data.legs.slots, names.legs), boots = getSlots(data.boots.slot or data.boots.slots, names.boots), }   local stats = { head = getStats(data.head.stats), chest = getStats(data.chest.stats), legs = getStats(data.legs.stats), boots = getStats(data.boots.stats), total = getTotalStats(data) }   local effects = { head = getEffects(data.head), chest = getEffects(data.chest), legs = getEffects(data.legs), boots = getEffects(data.boots), total = getEffects(data.total) }   local notUsingDataModuleButton, notUsingDataModuleMessage = ,  if not usingDataModule then notUsingDataModuleButton, notUsingDataModuleMessage = notUsingDataModuleWarning(data, armorName, 'Armor') end

local wikitable = mw.html.create('table'):addClass('wikitable'):css('overflow', 'auto'):css('border-width', '2px 2px 2px 2px !important'):css('vertical-align', 'text-top'):css('max-wdith', '40em') wikitable:tag('tr') :tag('th'):attr('colspan', '4'):css('border-width', '2px'):wikitext(notUsingDataModuleButton .. (data.type or 'Armor Set') .. VED_BUTTONS:format('Armor/Data', 'Armor/Data', MODULE)):done :done :tag('tr') :tag('th'):attr('colspan', '2'):css('border-width', '2px'):css('min-width', '150px'):wikitext(data.head.label or 'Helmet'):done :tag('th'):attr('colspan', '2'):css('border-width', '2px'):css('min-width', '150px'):wikitext(data.chest.label or 'Chestplate'):done :done :tag('tr') :tag('td'):addClass('ct'):wikitext(pieces.head and slots.head or BLANK_CELL):done :tag('td'):wikitext(pieces.head and ('%s \n%s\n%s'):format(rarity._link(data.head.rarity or data.rarity or 'c', names.head), stats.head or , effects.head or ) or BLANK_CELL):done :tag('td'):addClass('ct'):wikitext(pieces.chest and slots.chest or BLANK_CELL):done :tag('td'):wikitext(pieces.chest and ('%s \n%s\n%s'):format(rarity._link(data.chest.rarity or data.rarity or 'c', names.chest), stats.chest or , effects.chest or ) or BLANK_CELL):done :done :tag('tr') :tag('th'):attr('colspan', '2'):css('border-width', '2px'):wikitext(data.legs.label or 'Leggings'):done :tag('th'):attr('colspan', '2'):css('border-width', '2px'):wikitext(data.boots.label or 'Boots'):done :done :tag('tr') :tag('td'):addClass('ct'):wikitext(pieces.legs and slots.legs or BLANK_CELL):done :tag('td'):wikitext(pieces.legs and ('%s \n%s\n%s'):format(rarity._link(data.legs.rarity or data.rarity or 'c', names.legs), stats.legs or , effects.legs or ) or BLANK_CELL):done :tag('td'):addClass('ct'):wikitext(pieces.boots and slots.boots or BLANK_CELL):done :tag('td'):wikitext(pieces.boots and ('%s \n%s\n%s'):format(rarity._link(data.boots.rarity or data.rarity or 'c', names.boots), stats.boots or , effects.boots or ) or BLANK_CELL):done :done :tag('tr') :tag('th'):attr('colspan', '4'):css('border-width', '2px'):wikitext('Total'):done :done :tag('tr') :tag('td'):attr('colspan', '4'):wikitext(('%s\n%s'):format(rarity._link(data.rarity or 'c', armorName), stats.total or '')):done :done :tag('tr') :tag('th'):attr('colspan', '4'):css('border-width', '2px'):wikitext('Effects'):done :done if effects.total ~= '' then wikitable:tag('tr') :tag('td'):attr('colspan', '4'):wikitext(effects.total) :done end

wikitable:done

return table.concat{notUsingDataModuleMessage, tostring(wikitable)} end

return p