This module implements Template:LootTable.
local p = {}
local tableColors = {
'#EEEEEE',
'#FCCC5D',
'#A8D16E',
'#918C67',
'#EDB5FF',
'#F2FFB5',
'#B5FFCE',
'#FFB5B6',
'#B5F7FF',
'#CCCCCC'
}
-- parse actual loot info; currently supports up to 10 "pool=" arguments, but number can be increased if needed
local function parseLoot(args)
local allPools = {} -- stores each pool as a nested table
local poolWeights = {} -- stores weights for each pool separately
-- determine if these columns have content and should show
allPools.hasNotes = false
allPools.hasLevel = false
allPools.hasXP = false
for poolNumber=1, 10 do
local poolArg = args['pool'..poolNumber]
if poolArg then
local currentPool = {}
currentPool.items = {}
currentPool.poolNumber = poolNumber
currentPool.rolls = args['rolls'..poolNumber]
currentPool.bonusRolls = args['bonusrolls'..poolNumber] or '0'
poolArg = poolArg .. '\n' -- allow last line to be matched like the rest
-- parse input of pool parameter
for line in mw.ustring.gmatch(poolArg, '[^\r\n]+[\r\n]') do -- split on newline
--local splitLine = {}
local currentItem = {}
for key, value in mw.ustring.gmatch(line, '([%a]+)%s*:%s*(.-)%s*[;\r\n]') do
if value ~= '' then
currentItem[key:lower()] = value
end
end
-- convert weight to number; becomes nil if conversion fails
if currentItem.weight then
currentItem.weight = tonumber(currentItem.weight)
end
-- if converted to number successfully
if currentItem.weight then
if not poolWeights[poolNumber] then
poolWeights[poolNumber] = currentItem.weight
else
poolWeights[poolNumber] = poolWeights[poolNumber] + currentItem.weight
end
end
if currentItem.level then
allPools.hasLevel = true
end
if currentItem.xp then
allPools.hasXP = true
end
if currentItem.notes then
allPools.hasNotes = true
end
table.insert(currentPool.items, currentItem)
end
table.insert(allPools, currentPool)
end
end
return allPools, poolWeights
end
-- create output for parsed input
local function createLootOutput(allPools, poolWeights, numberColumns)
local output = {}
for _, currentPool in ipairs(allPools) do
local poolNumber = currentPool.poolNumber
local color = tableColors[poolNumber]
if not color then
color = ''
else
color = ' style="background-color:' .. color .. ';"'
end
for _, currentItem in ipairs(currentPool.items) do
local itemLink = ''
if currentItem.item == nil or mw.ustring.lower(currentItem.item) == 'nothing' then
itemLink = 'Nothing'
else
local itemName = currentItem.item
-- strip "mcw:" from imagelink and displayed name, while allowing article link to work normally
if itemName:sub(1, 4) == 'mcw:' then
itemName = itemName:sub(5)
end
local image = currentItem.image or (itemName .. '.png')
local imagesize = currentItem.imagesize or '32px'
local imageLink = '[[File:' .. image .. '|' .. imagesize .. ']] '
if currentItem.image and currentItem.image:lower() == 'none' then
imageLink = ''
end
itemLink = imageLink .. '[[' .. currentItem.item .. '|' .. itemName .. ']]'
end
local quantity = currentItem.quantity or 'style="text-align:center;" | –'
local looting
if currentItem.looting then
looting = '+' .. currentItem.looting .. ' per level'
else
looting = 'style="text-align:center;" | –'
end
local chance
if currentItem.weight and poolWeights[poolNumber] then -- weight exists and is not 0
chance = string.format("%.1f", (currentItem.weight / poolWeights[poolNumber]) * 100) .. '%'
else
chance = 'style="text-align:center;" | –'
end
local level = ''
if currentItem.level then
level = ' || ' .. currentItem.level
elseif allPools.hasLevel then
level = ' || '
end
local xp = ''
if currentItem.xp then
xp = ' || ' .. currentItem.xp
elseif allPools.hasXP then
xp = ' || '
end
local notes = ''
if currentItem.notes then
notes = ' || ' .. currentItem.notes
elseif allPools.hasNotes then
notes = ' || '
end
table.insert(output, '|-' .. color)
table.insert(output, '| ' .. itemLink .. ' || ' .. quantity .. ' || '
.. looting .. ' || ' .. chance .. level .. xp .. notes)
end
-- display info about pool rolls at the bottom of each pool
if currentPool.rolls then
table.insert(output, '|-' .. color)
local poolText = 'The above pool is rolled '
if currentPool.rolls == '1' then
poolText = poolText .. '1 time'
else
poolText = poolText .. currentPool.rolls .. ' times'
end
if currentPool.bonusRolls ~= '0' then
poolText = poolText .. ', with an additional '
if currentPool.bonusRolls == '1' then
poolText = poolText .. 'roll per point of Luck'
else
poolText = poolText .. currentPool.bonusRolls .. ' rolls per point of Luck'
end
end
table.insert(output, '| colspan = ' .. numberColumns .. ' | ' .. poolText .. '.')
end
end
return table.concat(output, '\n')
end
function p.lootTable(frame)
-- pass args into the module
args = frame:getParent().args
local numberColumns = 4
local output = {} -- list of strings to be concatenated into final output
local allPools, poolWeights = parseLoot(args)
local title = ''
local thirdColumn = ''
if (args.type == 'chest') then
title = 'Chest loot'
thirdColumn = 'Luck'
else
title = 'Unique drops'
thirdColumn = frame:expandTemplate{title = 'tooltip', args = {'Looting', 'The amount of extra items obtainable with the Looting enchantment.'}}
end
if args.title then
title = args.title
end
if args.otherlooting then
thirdColumn = args.otherlooting
end
local columns = '|-\n! Item !! Quantity !! ' .. thirdColumn .. ' !! Chance'
if allPools.hasLevel then
columns = columns .. ' !! Level required'
numberColumns = numberColumns + 1
end
if allPools.hasXP then
columns = columns .. ' !! XP'
numberColumns = numberColumns + 1
end
if allPools.hasNotes then
columns = columns .. ' !! Notes'
numberColumns = numberColumns + 1
end
-- begin creating final output
table.insert(output, '{| class = "wikitable"\n|-')
table.insert(output, '! colspan = ' .. numberColumns .. ' | ' .. title)
table.insert(output, columns .. '\n|-')
lootOutput = createLootOutput(allPools, poolWeights, numberColumns)
table.insert(output, lootOutput)
table.insert(output, '|}')
return table.concat(output, '\n')
end
return p;