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
Advertisement

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;
Advertisement