Advent of Ascension Wiki

This wiki is currently being updated to 1.18.2+ versions of the mod. If you are struggling to find information regarding 1.16.5 AoA, or are curious as to why 1.18.2+ versions are being released incomplete, please check out this page.

READ MORE

Advent of Ascension Wiki
mNo edit summary
m (Added class for styling)
(47 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
local p = {}
 
local p = {}
  +
  +
-- Background colours of pool blocks in template
  +
local poolColours = {
  +
"#EEEEEE",
  +
"#FEEFCD",
  +
"#E8F3D8",
  +
"#EAE9E1",
  +
"#F9E6FF",
  +
"#F6FFCC",
  +
"#E6FFEE",
  +
"#FFE6E6",
  +
"#E6FCFF",
  +
"#F2F2F2"
  +
}
  +
  +
-- Default table titles by loot table type for easy lookup
  +
local tableTypeTitles = {
  +
advancement_entity = "Rewards",
  +
advancement_reward = "Rewards",
  +
command = "Rewards",
  +
barter = "Barter results",
  +
block = "Block drops",
  +
chest = "Chest loot",
  +
empty = "No loot",
  +
entity = "Entity loot",
  +
fishing = "Fishing loot",
  +
generic = "Unique drops",
  +
gift = "Gifts",
  +
selector = "Unique drops"
  +
}
  +
  +
-- Parse loot entries from text to in-memory data.
  +
local function parseLootEntries(args)
  +
local pools = {} -- Container for nested tables which represent each pool
  +
local poolWeights = {} -- Container for each pool's loot entry weights for calculation
  +
  +
-- Default values for optional additional columns
  +
pools.hasNotes = false;
  +
pools.hasLooting = false;
  +
  +
-- Loop over pools to parse data, caps at 10 pools to prevent malicious wiki editing
  +
for poolIndex = 1, 10 do
  +
local poolData = args["pool" .. poolIndex]
  +
  +
-- End pool parsing when reaching non-existent pool
  +
if not poolData then
  +
break
  +
else
  +
local pool = {}
  +
poolWeights[poolIndex] = 0
  +
  +
-- Prep base pool data and variables
  +
pool.items = {}
  +
pool.poolNumber = poolIndex
  +
pool.rolls = args["rolls" .. poolIndex] or "1"
  +
pool.bonusRolls = args["bonusrolls" .. poolIndex]
  +
pool.notes = args["notes" .. poolIndex]
  +
  +
-- Append newline indicator to poolData so the following loop can identify lines properly
  +
poolData = poolData .. "\n"
  +
  +
-- Loop over pool data line by line, delineating by newline markers
  +
for line in string.gmatch(poolData, "[^\r\n]+[\r\n]") do
  +
local entry = {}
  +
  +
-- Split entry lines into data groups of approximate format key:value
  +
for key, value in string.gmatch(line, "([%a]+)%s*:%s*(.-)%s*[;\r\n]") do
  +
if value ~= "" then
  +
entry[key:lower()] = value
  +
end
  +
end
  +
  +
-- Ensure a weight value is present for calculation purposes in numeric format
  +
-- Update table-wide variables based on current entry
  +
entry.weight = tonumber(entry.weight or 1) or 1
  +
poolWeights[poolIndex] = poolWeights[poolIndex] + entry.weight
  +
pools.hasLooting = pools.hasLooting or entry.looting ~= nil
  +
pools.hasNotes = pools.hasNotes or entry.notes ~= nil
  +
  +
table.insert(pool.items, entry)
  +
end
  +
  +
table.insert(pools, pool)
  +
end
  +
end
  +
  +
return pools, poolWeights
  +
end
  +
  +
local function generateLootLines(pools, poolWeights, columnCount)
  +
local output = {}
  +
  +
-- Loop over pools in pool collection for individual formatting
  +
for _, pool in ipairs(pools) do
  +
local backgroundColour = poolColours[pool.poolNumber] or ""
  +
  +
if backgroundColour ~= "" then
  +
backgroundColour = "background-color:" .. backgroundColour .. ";"
  +
end
  +
  +
-- Loop over entries in current pool for individual formatting
  +
for _, entry in ipairs(pool.items) do
  +
-- Prep base variables for entry
  +
local itemLink = "Nothing"
  +
local quantity = entry.quantity or "-"
  +
local looting = ""
  +
local notes = ""
  +
local chance = "100%"
  +
  +
-- Skip empty entries
  +
if entry.item ~= nil and string.lower(entry.item) ~= "nothing" then
  +
local image = entry.image or (entry.item .. ".png")
  +
local imageLink = ""
  +
  +
-- Process image link with formatting
  +
if image:lower() ~= "none" then
  +
imageLink = "[[File:" .. image .. "|" .. (entry.imagesize or "32px") .. "|link=" .. entry.item .. "]]"
  +
end
  +
  +
-- Compile item link with processed image link
  +
itemLink = imageLink .. "[[" .. entry.item .. "]]"
  +
end
  +
  +
-- Format looting column value if applicable
  +
if entry.looting then
  +
looting = " || +" .. entry.looting .. " per level"
  +
elseif pools.hasLooting then
  +
looting = " || -"
  +
end
  +
  +
-- Format chance column value if applicable, calculated by entry's weight over the total pool weight
  +
if entry.weight and poolWeights[pool.poolNumber] then
  +
chance = string.format("%.1f", (entry.weight / poolWeights[pool.poolNumber]) * 100) .. "%"
  +
end
  +
  +
-- Add notes if applicable or empty column value if required
  +
if entry.notes then
  +
notes = " || style=\"text-align:left;\" | " .. entry.notes
  +
elseif pools.hasNotes then
  +
notes = " || "
  +
end
  +
  +
table.insert(output, "|- style=\"text-align:center;" .. backgroundColour .. "\"") -- Add colour to entry row
  +
table.insert(output, "| " .. itemLink .. " || " .. quantity .. looting .. " || " .. chance .. notes) -- Insert formatted data for entry
  +
end
  +
  +
local poolDescription = "| colspan=" .. columnCount .. " | " -- Begin bottom row text
  +
  +
-- Add background colour to pool if applicable
  +
if backgroundColour ~= "" then
  +
table.insert(output, "|- style=\"" .. backgroundColour .. "\"")
  +
else
  +
table.insert(output, "|-")
  +
end
  +
  +
-- Begin adding pool roll count to description
  +
poolDescription = poolDescription .. "The above pool is rolled "
  +
  +
if pool.rolls == "1" then
  +
poolDescription = poolDescription .. "1 time"
  +
else
  +
poolDescription = poolDescription .. pool.rolls .. " times"
  +
end
  +
  +
-- Add bonus rolls text to pool description if applicable
  +
if pool.bonusRolls then
  +
poolDescription = poolDescription .. ", with an additional "
  +
  +
if pool.bonusRolls == "1" then
  +
poolDescription = poolDescription .. "roll per point of [[mcw:Luck|Luck]]"
  +
else
  +
poolDescription = poolDescription .. pool.bonusRolls .. " rolls per point of [[mcw:Luck|Luck]]"
  +
end
  +
end
  +
  +
-- Add notes if present in pool data
  +
if pool.notes then
  +
poolDescription = poolDescription .. "<br/>" .. pool.notes
  +
end
  +
  +
table.insert(output, poolDescription)
  +
end
  +
  +
return table.concat(output, "\n")
  +
end
   
 
function p.lootTable(frame)
 
function p.lootTable(frame)
  +
local data = frame
-- pass args into the module
 
  +
args = frame:getParent().args
 
  +
-- Process arguments from template block on page
  +
if frame == mw.getCurrentFrame() then
  +
data = require("Module:ProcessArgs").merge(true)
  +
else
  +
frame = mw.getCurrentFrame()
  +
end
  +
  +
-- Prep base data for final printout
  +
local columnCount = 3
  +
local linesOut = {} -- Container for per-line text for output
  +
local pools, poolWeights = parseLootEntries(data)
  +
local title = ""
  +
local columnHeader = "|-\n! Item !! Quantity !! " -- Start column header line with base columns
  +
  +
-- Set default value to table type titles. This acts as a safety if we somehow have an invalid table type
  +
setmetatable(tableTypeTitles, {__index = function() return "Unique drops" end})
  +
  +
-- Set table title based on specified title in template or default for loot table type
  +
title = data.title or tableTypeTitles[data.type]
   
  +
-- Add looting column if required
local tableColors = {
 
  +
if pools.hasLooting then
'#EEEEEE',
 
  +
columnHeader = columnHeader .. frame:expandTemplate{title = "tooltip", args = {"Looting", "The amount of extra items obtainable with the Looting enchantment."}} .. " !! "
'#FCCC5D',
 
  +
columnCount = columnCount + 1
'#A8D16E',
 
  +
end
'#918C67',
 
'#EDB5FF',
 
'#F2FFB5',
 
'#B5FFCE',
 
'#FFB5B6',
 
'#B5F7FF',
 
'#CCCCCC'
 
}
 
local output = {} -- list of strings to be concatenated into final output
 
local poolWeights = {} -- stores weights for each pool separately
 
local itemsTable = {} -- stores each item as a nested table
 
 
table.insert(output, '{| class = "wikitable"\n|-')
 
   
  +
-- Insert chance column
local title = ''
 
  +
columnHeader = columnHeader .. "Chance"
local centerColumn = ''
 
 
if (args.type == 'chest') then
 
title = 'Chest loot'
 
centerColumn = 'Luck'
 
elseif (args.type == 'custom') then
 
centerColumn = args.otherlooting
 
else
 
title = 'Unique drops'
 
centerColumn = frame:expandTemplate{title = 'tooltip', args = {'Looting', 'The amount of extra items obtainable with the Loot enchantment.'}}
 
end
 
 
if args.title then
 
title = args.title
 
end
 
   
  +
-- Add notes column if required
-- should colspan be changed to a variable instead of hardcoded number?
 
  +
if pools.hasNotes then
table.insert(output, '! colspan = 5 | ' .. title)
 
  +
columnHeader = columnHeader .. " !! Notes "
table.insert(output, '|-\n! Item !! Quantity !! ' .. centerColumn .. ' !! Chance !! Notes\n|-')
 
  +
columnCount = columnCount + 1
  +
end
   
  +
-- Append newline and next line starter after columns header line compiled
 
  +
columnHeader = columnHeader .. "\n|-"
-- parse actual loot info; currently supports up to 10 "pool=" arguments
 
for poolNumber=1, 10 do
 
local poolArg = args['pool'..poolNumber]
 
if poolArg then
 
-- TODO
 
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
 
 
if not currentItem.quantity then
 
currentItem.quantity = '0'
 
end
 
 
if not currentItem.looting then
 
currentItem.looting = '-'
 
end
 
 
local weight
 
if currentItem.weight then
 
weight = tonumber(currentItem.weight)
 
currentItem.weight = weight
 
end
 
 
if not currentItem.notes then
 
currentItem.notes = ''
 
end
 
 
if not poolWeights[poolNumber] then
 
poolWeights[poolNumber] = weight
 
else
 
poolWeights[poolNumber] = poolWeights[poolNumber] + weight
 
end
 
 
currentItem.poolNumber = poolNumber
 
 
table.insert(itemsTable, currentItem)
 
end
 
end
 
end
 
   
  +
-- Compile final output
-- create output from parsed input
 
  +
table.insert(linesOut, "{| class = \"wikitable loottable\"\n|-")
for _, currentItem in ipairs(itemsTable) do
 
  +
table.insert(linesOut, "! colspan = " .. columnCount .. " | " .. title)
local itemLink = ''
 
  +
table.insert(linesOut, columnHeader)
  +
table.insert(linesOut, generateLootLines(pools, poolWeights, columnCount))
  +
table.insert(linesOut, "|}")
   
  +
return table.concat(linesOut, "\n")
if currentItem.item == '' or not currentItem.item or mw.ustring.lower(currentItem.item) == 'nothing' then
 
itemLink = 'Nothing'
 
else
 
local image = currentItem.item .. '.png'
 
local imagesize = '32px'
 
if currentItem.image then
 
image = currentItem.image
 
end
 
itemLink = '[[File:' .. image .. '|' .. imagesize .. ']] [[' .. currentItem.item .. ']]'
 
end
 
 
local chance = '0%'
 
-- quantity, looting and group stay as is
 
if currentItem.weight then -- weight exists and is not 0
 
chance = string.format("%.1f", (currentItem.weight / poolWeights[currentItem.poolNumber]) * 100) .. '%'
 
end
 
 
local color = tableColors[currentItem.poolNumber]
 
if not color then
 
color = ''
 
else
 
color = ' style="background-color:' .. color .. ';"'
 
end
 
table.insert(output, '|-' .. color)
 
table.insert(output, '| ' .. itemLink .. ' || ' .. currentItem.quantity .. ' || '
 
.. currentItem.looting .. ' || ' .. chance .. ' || ' .. currentItem.notes)
 
end
 
-- footer
 
table.insert(output, '|}')
 
 
return table.concat(output, '\n')
 
 
end
 
end
   
return p;
+
return p

Revision as of 14:41, 22 July 2021

This module implements Template:LootTable.


local p = {}

-- Background colours of pool blocks in template
local poolColours = {
    "#EEEEEE",
    "#FEEFCD",
    "#E8F3D8",
    "#EAE9E1",
    "#F9E6FF",
    "#F6FFCC",
    "#E6FFEE",
    "#FFE6E6",
    "#E6FCFF",
    "#F2F2F2"
}

-- Default table titles by loot table type for easy lookup
local tableTypeTitles = {
    advancement_entity = "Rewards",
    advancement_reward = "Rewards",
    command = "Rewards",
    barter = "Barter results",
    block = "Block drops",
    chest = "Chest loot",
    empty = "No loot",
    entity = "Entity loot",
    fishing = "Fishing loot",
    generic = "Unique drops",
    gift = "Gifts",
    selector = "Unique drops"
}

-- Parse loot entries from text to in-memory data.
local function parseLootEntries(args)
    local pools = {} -- Container for nested tables which represent each pool
    local poolWeights = {} -- Container for each pool's loot entry weights for calculation

    -- Default values for optional additional columns
    pools.hasNotes = false;
    pools.hasLooting = false;

    -- Loop over pools to parse data, caps at 10 pools to prevent malicious wiki editing
    for poolIndex = 1, 10 do
        local poolData = args["pool" .. poolIndex]

        -- End pool parsing when reaching non-existent pool
        if not poolData then
            break
        else
            local pool = {}
            poolWeights[poolIndex] = 0

            -- Prep base pool data and variables
            pool.items = {}
            pool.poolNumber = poolIndex
            pool.rolls = args["rolls" .. poolIndex] or "1"
            pool.bonusRolls = args["bonusrolls" .. poolIndex]
            pool.notes = args["notes" .. poolIndex]

            -- Append newline indicator to poolData so the following loop can identify lines properly
            poolData = poolData .. "\n"

            -- Loop over pool data line by line, delineating by newline markers
            for line in string.gmatch(poolData, "[^\r\n]+[\r\n]") do
                local entry = {}

                -- Split entry lines into data groups of approximate format key:value
                for key, value in string.gmatch(line, "([%a]+)%s*:%s*(.-)%s*[;\r\n]") do
                    if value ~= "" then
                        entry[key:lower()] = value
                    end
                end

                -- Ensure a weight value is present for calculation purposes in numeric format
                -- Update table-wide variables based on current entry
                entry.weight = tonumber(entry.weight or 1) or 1
                poolWeights[poolIndex] = poolWeights[poolIndex] + entry.weight
                pools.hasLooting = pools.hasLooting or entry.looting ~= nil
                pools.hasNotes = pools.hasNotes or entry.notes ~= nil

                table.insert(pool.items, entry)
            end

            table.insert(pools, pool)
        end
    end

    return pools, poolWeights
end

local function generateLootLines(pools, poolWeights, columnCount)
    local output = {}

    -- Loop over pools in pool collection for individual formatting
    for _, pool in ipairs(pools) do
        local backgroundColour = poolColours[pool.poolNumber] or ""

        if backgroundColour ~= "" then
            backgroundColour = "background-color:" .. backgroundColour .. ";"
        end

        -- Loop over entries in current pool for individual formatting
        for _, entry in ipairs(pool.items) do
            -- Prep base variables for entry
            local itemLink = "Nothing"
            local quantity = entry.quantity or "-"
            local looting = ""
            local notes = ""
            local chance = "100%"

            -- Skip empty entries
            if entry.item ~= nil and string.lower(entry.item) ~= "nothing" then
                local image = entry.image or (entry.item .. ".png")
                local imageLink = ""

                -- Process image link with formatting
                if image:lower() ~= "none" then
                    imageLink = "[[File:" .. image .. "|" .. (entry.imagesize or "32px") .. "|link=" .. entry.item .. "]]"
                end

                -- Compile item link with processed image link
                itemLink = imageLink .. "[[" .. entry.item .. "]]"
            end

            -- Format looting column value if applicable
            if entry.looting then
                looting = " || +" .. entry.looting .. " per level"
            elseif pools.hasLooting then
                looting = " || -"
            end

            -- Format chance column value if applicable, calculated by entry's weight over the total pool weight
            if entry.weight and poolWeights[pool.poolNumber] then
                chance = string.format("%.1f", (entry.weight / poolWeights[pool.poolNumber]) * 100) .. "%"
            end

            -- Add notes if applicable or empty column value if required
            if entry.notes then
                notes = " || style=\"text-align:left;\" | " .. entry.notes
            elseif pools.hasNotes then
                notes = " || "
            end

            table.insert(output, "|- style=\"text-align:center;" .. backgroundColour .. "\"") -- Add colour to entry row
            table.insert(output, "| " .. itemLink .. " || " .. quantity .. looting .. " || " .. chance .. notes) -- Insert formatted data for entry
        end

        local poolDescription = "| colspan=" .. columnCount .. " | " -- Begin bottom row text

        -- Add background colour to pool if applicable
        if backgroundColour ~= "" then
            table.insert(output, "|- style=\"" .. backgroundColour .. "\"")
        else
            table.insert(output, "|-")
        end

        -- Begin adding pool roll count to description
        poolDescription = poolDescription .. "The above pool is rolled "

        if pool.rolls == "1" then
            poolDescription = poolDescription .. "1 time"
        else
            poolDescription = poolDescription .. pool.rolls .. " times"
        end

        -- Add bonus rolls text to pool description if applicable
        if pool.bonusRolls then
            poolDescription = poolDescription .. ", with an additional "

            if pool.bonusRolls == "1" then
                poolDescription = poolDescription .. "roll per point of [[mcw:Luck|Luck]]"
            else
                poolDescription = poolDescription .. pool.bonusRolls .. " rolls per point of [[mcw:Luck|Luck]]"
            end
        end

        -- Add notes if present in pool data
        if pool.notes then
            poolDescription = poolDescription .. "<br/>" .. pool.notes
        end

        table.insert(output, poolDescription)
    end

    return table.concat(output, "\n")
end

function p.lootTable(frame)
    local data = frame

    -- Process arguments from template block on page
    if frame == mw.getCurrentFrame() then
        data = require("Module:ProcessArgs").merge(true)
    else
        frame = mw.getCurrentFrame()
    end

    -- Prep base data for final printout
    local columnCount = 3
    local linesOut = {} -- Container for per-line text for output
    local pools, poolWeights = parseLootEntries(data)
    local title = ""
    local columnHeader = "|-\n! Item !! Quantity !! " -- Start column header line with base columns

    -- Set default value to table type titles. This acts as a safety if we somehow have an invalid table type
    setmetatable(tableTypeTitles, {__index = function() return "Unique drops" end})

    -- Set table title based on specified title in template or default for loot table type
    title = data.title or tableTypeTitles[data.type]

    -- Add looting column if required
    if pools.hasLooting then
        columnHeader = columnHeader .. frame:expandTemplate{title = "tooltip", args = {"Looting", "The amount of extra items obtainable with the Looting enchantment."}} .. " !! "
        columnCount = columnCount + 1
    end

    -- Insert chance column
    columnHeader = columnHeader .. "Chance"

    -- Add notes column if required
    if pools.hasNotes then
        columnHeader = columnHeader .. " !! Notes "
        columnCount = columnCount + 1
    end

    -- Append newline and next line starter after columns header line compiled
    columnHeader = columnHeader .. "\n|-"

    -- Compile final output
    table.insert(linesOut, "{| class = \"wikitable loottable\"\n|-")
    table.insert(linesOut, "! colspan = " .. columnCount .. " | " .. title)
    table.insert(linesOut, columnHeader)
    table.insert(linesOut, generateLootLines(pools, poolWeights, columnCount))
    table.insert(linesOut, "|}")

    return table.concat(linesOut, "\n")
end

return p