Module:Potion

local getArgs = require('Module:Arguments').getArgs local loader = require('Module:Loader') local string, table, yesno, uitext, inventoryslot, link = loader.require('String', 'Table', 'Yesno', 'UIText', 'Inventory slot', 'Link') local potionData, potionAliases = loader.loadData('Potion/Data', 'Potion/Aliases')

local p = {} local slot = inventoryslot.slot local unknownDisplay = '&r&f&l???&r' local levelsColumnLcm = 2520 -- smallest number evenly divisible by all number before / including 10 local LEVEL_ROMANS = { 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' } local potionPageRowLevelBoosters = { string.wrapHtml('+', 'span', { style={ opacity=0.5 } }), string.wrapHtml('+', 'span', { style={ opacity=0.5 } }), string.wrapHtml('+', 'span', { style={ opacity=0.5 } }), }

--- -- Generates table for Module:Inventory slot/Templates --- function p.getPotionsTemplate local function toTable(v) local t = type(v) == 'table' and table.deepCopy(v, true) or {v} return t	end local function colorCode(col) local temp = uitext.getFormatting(col):match('^[0-9a-z]$') and uitext.getFormatting(col) or uitext.getColorCode(col) return (temp or ''):match('^[0-9a-z]$') and temp or 'f'	end local function effectText(effect, level, duration) if not level or level < 0 then return end local dt = potionData[effect] if dt then local g_desc = dt.desc or unknownDisplay variables = toTable(dt.vars) local desc local color = dt.ttColor or colorCode(dt.color or '&f') desc = g_desc if level > 0 then for i, var in ipairs(variables) do					desc = desc:gsub(('{%d}'):format(i-1), var[level] or unknownDisplay) end end desc = desc:gsub('{%d+}', unknownDisplay) return ('&%s%s %s &r&f%s/&r%s//&r'):format(				color, effect, level > 0 and string._toRoman(level) or '?',				duration and ('(%s&f)'):format(duration) or '', desc				) else return unknownDisplay end end local function generateTooltip(potionname, level) local value = potionData[potionname] local localret = {} local duration, composite = value.duration, value.composite if type(duration) == 'table' then duration = duration[level] end local tooltip if composite then for i, eff in ipairs(toTable(composite)) do				if eff == 'self' then tooltip = effectText(potionname, level, duration) else local eff = toTable(eff) local e, l = eff[1], eff[2] or 1 if type(l) == 'table' then l = l[level] end local compDuration = composite.duration if type(compDuration) == 'table' then compDuration = compDuration[level] end tooltip = effectText(e, l or 0, compDuration or duration) end table.push(localret, tooltip) end else tooltip = effectText(potionname, level, duration) table.push(localret, tooltip) end return table.concat(localret) end local ret = {} for potionname, value in pairs(potionData) do		local name = ('%s Potion'):format(potionname) local rarityTbl = toTable(value.rarity) for level = 1, value.maxLevel or 0, 1 do			local nameRoman = ('%s %s Potion'):format(potionname, string._toRoman(level)) local nameArabic = ('%s %s Potion'):format(potionname, level) local tooltip = generateTooltip(potionname, level) local rarity = rarityTbl[level] or 'C'			local raritytext = rarityTbl[level] and '{l}' or '{r}&l???' table.push(ret, { nameRoman, name, tooltip, raritytext, r = rarity }) table.push(ret, { nameArabic, name, tooltip, raritytext, r = rarity, title = '{r}'..nameRoman }) if level == 1 then table.push(ret, { name, name, tooltip, raritytext, r = rarity, title = '{r}'..nameRoman }) end end end return ret end

--- -- Generates multiple rows needed for a single potion on Potions page -- Invoked by Template:PotionPageRow --- function p.potionPageRow(frame) local args = getArgs(frame) local name = args['name'] local effect = args['effect'] local varnames = args['varnames'] local unlock = args['unlock'] local brews = args['brews'] return p._potionPageRow(name, effect, varnames, unlock, brews) end function p._potionPageRow(name, effect, varnames, unlock, brews) name = potionAliases[name:lower] local pd = potionData[name] if not pd then return unknownDisplay; end local basePotion = pd.ingredients and pd.ingredients.basePotion local basePotionUsedForLevel = pd.ingredients and pd.ingredients.basePotionUsedForLevel local t = {} local BRDR_MID = { ['border-right-width']='3px' } local BRDR_BTM = { ['border-bottom-width']='5px' } local levelColSpan = levelsColumnLcm / (basePotion and pd.maxLevel+1 or pd.maxLevel) -- Basic Row Data local row1 = mw.html.create('tr'):attr{ id=name }:addClass('article-row-main') -- :tag('th'):attr{ rowspan=3 }:css{ ['max-width']=0 }:done :tag('th'):attr{ colspan=4 }:css{ ['text-align']='left !important' }:css(BRDR_MID) :tag('div'):css{ display='flex', gap='4px' } :wikitext( link.potionName{ name.." I Potion", format=true, bold=true } ) :tag('span'):css{ flex=1, ['text-align']='right' } :tag('b'):wikitext('Unlock: '):done :tag('span'):wikitext( unlock or 'Initially Available' ):css{ ['font-weight']='normal' }:done :done :done :done local row2 = mw.html.create('tr'):addClass('centertext'):addClass('article-row-bound'):css{ height='100%' }--100% height needed for cell contents to use 100% height :tag('th'):wikitext( slot{ name.." I Potion" } ):attr{ rowspan=2 }:css(BRDR_BTM):done :tag('td'):attr{ colspan=3, rowspan=2 }:css{ ['text-align']='left' }:css(BRDR_MID):css(BRDR_BTM):css{ height='100%' }--100% height needed for cell contents to use 100% height :tag('div'):css{ display='flex', ['flex-direction']='column' }:css{ height='100%' }--100% height needed for cell contents to use 100% height :tag('div'):css{ flex=1 } -- this flex pushes the varnames text down (if there is any) :wikitext(effect or 'Unknown effect') :wikitext(						brews and string.wrapHtml(table.concat{ brews and string.wrapHtml('Compatible Brews: \n'..brews, 'li') or '', }, 'ul') or ''					) :done :wikitext( varnames and string.wrapHtml(table.concat{ '(in ', varnames, ')' }, 'div', { style={ ['text-align']='right', ['font-style']='italic' } }) or '' ) :done :done local row3 = mw.html.create('tr'):addClass('centertext'):addClass('article-row-bound') if basePotion then row1:tag('th'):attr{ colspan=levelColSpan } :tag('abbr'):wikitext('Base Potion'):attr{ title='Some potions require a non-typical base to be used instead of an Awkward Potion' }:done row2:tag('td'):wikitext( slot{ basePotion } ):attr{ colspan=levelColSpan, rowspan=2 }:css(BRDR_BTM) if basePotionUsedForLevel then row2:tag('td'):wikitext( slot{ pd.ingredients[1] } ):attr{ colspan=levelColSpan }:css{ ['border-right']=0 } -- this dumb **** is because browsers have a max `colspan` of 1000 local columnsLeft = pd.maxLevel-1 row2:tag('td'):wikitext( '(level based on level' ):attr{ colspan=math.ceil(columnsLeft/2)*levelColSpan }:css{ ['text-align']='right', ['border-right']=0, ['border-left']=0, ['padding-right']= '2px !important', ['transform']= 'translateX(15px)' }			row2:tag('td'):wikitext( 'of base potion)' ):attr{ colspan=math.floor(columnsLeft/2)*levelColSpan }:css{ ['text-align']='left', ['border-left']=0, ['padding-left']= '2px !important', ['transform']= 'translateX(15px)' } end end -- Add level data to rows local lastLevelWithItem = 0 for i = 1, pd.maxLevel do		row1:tag('th'):wikitext( LEVEL_ROMANS[i] ):attr{ colspan=levelColSpan } local levelVars = {} if pd.vars then for j, varList in pairs(pd.vars) do				levelVars[#levelVars+1] = varList[i] end end levelVars = table.concat(levelVars, ' ') -- If ingredients exist, show them; if not, then only list the stats if pd.ingredients then local ingredient = nil if pd.ingredients[i] then ingredient = slot{ pd.ingredients[i] } lastLevelWithItem = i			elseif pd.ingredients[i..'text'] then ingredient = pd.ingredients[i..'text'] lastLevelWithItem = i			else ingredient = potionPageRowLevelBoosters[i-lastLevelWithItem] end -- Don't draw ingredient column is base potion used for level, as we already added a colspan for here previously if not basePotionUsedForLevel then row2:tag('td'):wikitext( ingredient or '?' ):attr{ colspan=levelColSpan } end row3:tag('td'):wikitext( levelVars ):attr{ colspan=levelColSpan }:css(BRDR_BTM):css{ ['line-height']=1.3 } else -- show row 3 as row two with rowspan=2 row2:tag('td'):wikitext( levelVars ):attr{ colspan=levelColSpan, rowspan=2 }:css(BRDR_BTM):css{ ['line-height']=1.3 } end end return table.concat{ tostring(row1), tostring(row2), tostring(row3) } end

return p