Module:Reforge

require('Module:LoadLib')(_G, {	rarityData = 'Module:RarityTier/Data',	statData = 'Module:Statname/Data',	list = 'Module:List',	mctxt = 'Module:Mctxt',	item = 'Module:Item',	stringT = 'Module:String/Templates' }) local reforgeData = mw.loadData('Module:Reforge/Data')

local p = {}

- -- Template:Reforge Stone Table -- -- Creates a table that formats the cost of a reforge stone - function p.reforgeStoneTable(frame) local args = getArgs(frame) local allData, allStats, allRarities = {}, {}, 0 local specialText, sevFlag -- allRarities is a number that stores the existence of every rarity in a binary way -- if 'common' exists, 2^0 (=1) is added; if 'uncommon' exists, 2^1 (=2) is added, etc.	local function statExt(s) return not not table.find(allStats, s)	end local function rarityExt(i) -- extract in a binary way whether one value exists -- here, for 'common', i = 0 if type(i) == 'string' then i = rarityTier._getTier(i).order end return math.floor(allRarities / (2^i)) % 2 == 1 end local function recStat(s) if not statExt(s) then table.insert(allStats, s) end end local function recRarity(i) if not rarityExt(i) then allRarities = allRarities + 2^(i) end end local infoNeededVals = { 'in', 'infoneeded', 'ineeded', 'infon', 'moreinfoneeded', 'moreinfo', 'info needed', 'more info needed', 'more info', 'info n', '?', } local confirmVals = { 'confirm', 'c', 'con', 'conf', 'check', 'not confirmed', 'unconfirmed', 'notconfirmed', } local srcNeededVals = { 'source needed', 'src needed', 'src n', 'sn', 'source n', 'source?', 'souce', 's?', 's', } local blankCellVals = { 'n/a', 'no', 'n', 'none', 'f', 'fal', 'false', '0', '-0', '+0', '-0%', '+0%', '0%', '', 'unapplicable', } local function searchTier(index, short) local v, k = rarityTier._getTier(index-1) return yesno(short, false) and v.short or k	end local function isNormal(arg) if not table.find(infoNeededVals, arg:lower) and not table.find(blankCellVals, arg:lower) then return true else return false end end

local function processOtherArg(arg) if table.find(blankCellVals, arg:lower) then return end return table.find(infoNeededVals, arg:lower) and stringT.infoNeeded or arg end local function extractEndNotice(arg) if arg:match('%s*;%s*') then arg, endNotice = arg:match('(.+)%s*;%s*(.*)') else endNotice = '' end if endNotice ~= '' then endNotice = table.find(confirmVals, endNotice:lower) and  or table.find(srcNeededVals, endNotice:lower) and  or '' end return arg, endNotice end local function processCostArgs if args.cost then return string.split(args.cost, '%s*,%s*') else local t = {} for i = 1, table.length(rarityData) do				t[i] = args["cost_"..searchTier(i)] or args["cost_"..searchTier(i,true)] end return t		end end local function processStatArgs(statname, statlong, statshort) local argShort, argNormal = args['stats_'..statshort], args['stats_'..statlong] if argShort or argNormal then ret = (mw.text.split(argShort or argNormal, '%s*\,%s*')) else ret = {} for j = 1, table.length(rarityData), 1 do				local r, rshort = searchTier(j), searchTier(j,true) ret[j] = args[statshort..rshort] or args[statshort..r] or args[statlong..r] or args[statlong..rshort] end end return ret end local function dataProcessing -- main function to build allData table -- initialize table for rKey, rTable in rarityTier._getTierIterable do			table.insert(allData, { rKey }) end -- process stats for statname, stattable in pairs(statData) do			local statlong = statname:gsub(' ', '_') local statshort = stattable.shortcode:lower local argsList = processStatArgs(statname, statlong, statshort) for j = 1, table.length(rarityData), 1 do				if argsList[j] then local arg, endNotice = extractEndNotice(argsList[j]) allData[j][statname] = (isNormal(arg) and not arg:match('([^%d%%%-%+%.%,]+)')) and ('%s%s'):format(makeColor( 'green', arg:gsub('^([%+%-]*)(%d+)(%%?)$',								function(prep, d)									local pattern = tostring(d)									if stattable.percent or false then											pattern = pattern..'%'									end									return (prep == '-' and prep or '+')..pattern								end							)), endNotice) or processOtherArg(arg) if allData[j][statname] then recStat(statname) recRarity(j-1) end end end end -- process costs local costsList = processCostArgs for j = 1, table.length(rarityData), 1 do			if costsList[j] then local arg, endNotice = extractEndNotice(costsList[j]) allData[j].__cost = arg and isNormal(arg) and tostring(coins{arg, nil, true })..endNotice or processOtherArg(arg) recRarity(j-1) end end end local function specialProcessing -- Process reforge special effect local specialEffect = args["special effect"] or args["specialeff"] or args["special"] or args["eff"] or args["se"] if specialEffect then local name, desc = mw.ustring.match(specialEffect, '([^;]+);%s*(.+)') name, desc = string.trim(name), string.trim(desc) local varStrs = desc:match(';\n') and mw.text.split(desc:match('.+;\n(.+)'), '%s*,%s*') local desc = varStrs and desc:match('(.+);\n.+') or desc local desc = desc:gsub('\n', ' ') if varStrs then local showPerc = table.some(varStrs, function(_, v) 						return v:match('%%')					end) if showPerc then table.each(varStrs, function(v, i, t)						t[i] = v:gsub('%%', '')					end) end desc = desc:gsub('$VALUES', makeColor('Green', { '+',						table.concat(table.map(varStrs, function(v) return isNormal(v) and v or nil end), '/'), showPerc and '%' or '', }))				for j = 1, table.length(rarityData), 1 do					if varStrs[j] and (not table.find(blankCellVals, varStrs[j]:lower)) then allData[j].__sev = table.find(infoNeededVals, varStrs[j]:lower) and stringT.infoNeeded or makeColor('Green', varStrs[j]) sevFlag = true recRarity(j-1) end end end specialText = ('%s: %s'):format(makeColor('Blue', name), desc) end end local function trimdata -- removes all unused rarities do local i = 1 while i <= #allData do				local key = allData[i][1] if rarityExt(key) then i = i + 1 else table.remove(allData, i)				end end end end dataProcessing specialProcessing trimdata local lenX = #allData -- Process all data from main table local wikitable = mw.html.create('table'):addClass('wikitable') local row = wikitable:tag('tr') row:tag('th') :attr{ rowspan = 2 }:wikitext(string.centerText('Stat Bonus')) :done row:tag('th') :attr{ colspan = lenX == 0 and 1 or lenX, }:wikitext(string.centerText('Rarity')) :done row:done local row = wikitable:tag('tr') for i = 1, lenX, 1 do		row:tag('th'):wikitext(string.centerText(('%s%s'):format(			-- handles first rarity as ' (or below)' if it is not 'Common'			-- handles last rarity as ' (or above)' if it is not 'Very Special'			makeRarity(allData[i][1]),			i == 1 and allData[i][1] ~= 'common' and ' ' .. string.wrapHtml('or below', 'small')			or i == lenX and allData[i][1] ~= 'very_special' and ' ' .. string.wrapHtml('or above', 'small')			or ''		))):done if i == lenX then row:done end end if lenX == 0 then row:tag('td'):wikitext(stringT.blankCell):done end for _, statname in ipairs(allStats) do		local statlong = statname:gsub('_', ' ') local row = wikitable:tag('tr'):tag('td'):wikitext(string.centerText(makeStat(statlong))):done for j = 1, lenX, 1 do			local score = allData[j][statname] row:tag('td'):wikitext(score and string.centerText(score) or stringT.blankCell):done end row:done end local row = wikitable:tag('tr') row:tag('th'):wikitext('Cost to apply'):done for i = 1, lenX, 1 do		local c = allData[i].__cost row:tag('td'):wikitext(c and string.centerText(c) or stringT.blankCell):done end -- Process reforge special effect if specialText then local row = wikitable:tag('tr') row:tag('th') :wikitext('Reforge Special Effect') :done row:tag('td') :attr{ colspan = lenX }:wikitext(specialText) :done row:done end -- Process reforge special effect values if sevFlag then local row = wikitable:tag('tr') row:tag('th') :wikitext('Reforge Special Effect Values') :done for i= 1, lenX, 1 do			local s = allData[i].__sev row:tag('td'):wikitext(s and string.centerText(s) or stringT.blankCell):done end row:done end wikitable:done wikitable = string.wrapHtml(tostring(wikitable), 'div', {class='article-scrollable', style='overflow-x: auto;'}) return mw.getCurrentFrame:preprocess(tostring(wikitable)) end

function p.listSearchSuggestions(frame) local suggestions = {} for reforgeType,v in pairs(reforgeData) do		for reforge,v in pairs(reforgeData[reforgeType]) do			suggestions[#suggestions+1] = reforge end end return table.concat(suggestions, ",") end

function p.displayReforgeData(frame) local args = getArgs(frame) local reforgeName = args[1] return p._displayReforgeData(reforgeName) end

function p._displayReforgeData(reforgeName) local reforge, reforgeType = nil, nil for rt,v in pairs(reforgeData) do		if reforgeData[rt][reforgeName] then reforge = reforgeData[rt][reforgeName] reforgeType = rt		end end if not reforge then return string.wrapHtml("Reforge not found", 'div', {style='color:red'}) end local t = {} t[#t+1] = string.wrapHtml(reforgeName, 'h3') if reforgeType == 'Accessory' then t[#t+1] = ' These reforges have been removed, but reforged accessories prior to April 20, 2022 still display the name of the reforge. Accessory reforges were replaced with Thaumaturgy. '	end t[#t+1] = ' ' t[#t+1] = ' ' -- start list holder column t[#t+1] = '\n*Type: ' .. reforgeType if reforge.tool then t[#t+1] = '\n*Tool: ' .. reforge.tool end if reforge.source then if reforge.source == "Basic" then t[#t+1] = '\n*Source: Blacksmith' else t[#t+1] = '\n*Source: ' .. item.itemDisplay{ reforge.source } end end t[#t+1] = '\n' t[#t+1] = ' ' -- end list holder column if reforge.description then t[#t+1] = mw.getCurrentFrame:preprocess(string.wrapHtml(mctxt._raw(reforge.description), 'p')) end t[#t+1] = ' ' -- end grid local wikitable = mw.html.create('table'):addClass('wikitable') local rowH = wikitable:tag('tr') local rowD = wikitable:tag('tr') local raritiesOrdered = { 'c', 'u', 'r', 'e', 'l', 'm', 'd' } for _,r in pairs(raritiesOrdered) do		-- skip empty columns if reforge.stats[r] then local statLines, extras = {}, {} for statN,statV in pairs(reforge.stats[r]) do				if statN == "xpbonus" then extras[#extras+1] = mw.getCurrentFrame:preprocess(" Exp") else statLines[#statLines+1] = ((type(statV) == 'number' and statV < 0) and statV or "+"..statV).." "..statN end end -- skip blank columns if #statLines > 0 or #extras > 0 then rowH:tag('th'):wikitext(rarityTier._link(r)) rowD:tag('td') :wikitext(#statLines > 0 and list._statsList(statLines, true, true) or '') :wikitext(table.concat(extras,"\n")) end end end t[#t+1] = tostring(wikitable) return table.concat(t) end

return p