Module:Sandbox/User:Alsang/PotionList

Documentation for this module may be created at Module:Sandbox/User:Alsang/PotionList/doc

local p = {}
local param = require( 'Module:Paramtest' )


-- non dynamic module, no inputs
function p.main()
	
	-- returns almost every parameter needed for the row, except buy values for reagents
	local query = {
		'[[Category:Potions]]',
		'[[Uses facility::Standard Potion Station||Potent Potion Station]]',
		'[[Variant of::Fear]]',
		'?Profession Level A = lvl',
		'? #- = name',
		'?Uses item.Uses item #- = reagents',
		'?Value = sell',
		'?Recipe XP = brewXP',
		'?Uses item.Recipe XP = prepXP',
		'?Recipe KP = brewKP',
		'?Uses item.Recipe KP = prepKP',
		'?Recipe duration = brewDuration',
		'?Uses item.Recipe duration = prepDuration',
		'sort = Profession Level A'
	}
	local results = mw.smw.ask(query)
	
	results = p.makeTableStrings(results)

	-- actual output
	return p.displayTable(results)
	
	-- for testing
	--return '<pre>' ..mw.text.jsonEncode(results, mw.text.JSON_PRETTY).. '</pre>'
	
end

-- do calculations and determine strings to go in cells
function p.makeTableStrings(results)

    -- iterate through potions
    for i, item in ipairs(results) do
    	
    	--in case of single reagent potions, make table of 1 element
    	if type(item.reagents) ~= 'table' then
    		item.reagents = {item.reagents}
    	end
    	
    	-- iterate through reagents, adding buy price to running total (individuals not needed)
    	-- starting value 20 is for bottle
    	item.buy = 20
    	for j, reagent in ipairs(item.reagents) do
    		
    		--shamelessley lifted from Module:Products
    		local shopPriceQuery = '[[:+]][[Sold item::' .. reagent .. ']]|?Shop buy price|mainlabel=' .. reagent
            local shopPriceResult = mw.smw.ask(shopPriceQuery) or {}
            local shopPrice = 0

            if shopPriceResult[1] and shopPriceResult[1]["Shop buy price"] then
                shopPrice = tonumber(shopPriceResult[1]["Shop buy price"]) or 0
            end
    		
            item.buy = item.buy + shopPrice
    	end
    	
    	
    	-- sanitise data, set to 0 if its not there
    	local lvl = item.lvl or 0
    	local sell = item.sell or 0
    	local brewXP = item.brewXP or 0
    	local prepXP = item.prepXP or 0
    	local brewKP = item.brewKP or 0
    	local prepKP = item.prepKP or 0
    	local brewDuration = item.brewDuration or 0
    	local prepDuration = item.prepDuration or 0
    	
    	-- direct values
    	item.profit = sell - item.buy 
   		item.XP = brewXP  + prepXP 
    	item.KP = brewKP + prepKP 
    	item.profitPerXP = math.floor(item.profit / item.XP * 100) / 100

    	-- 40 seconds to buy new supplies and travel and deposit and everything, per 12 potions
    	local batchSize = 12
    	local downtime = 40
    	item.duration = prepDuration + brewDuration + downtime/batchSize
    	item.potionPerHour = 1 / item.duration * 3600
    	
    	-- properties per hour
    	item.XPPerHour = math.floor(item.XP * item.potionPerHour)
    	item.KPPerHour = math.floor(item.KP * item.potionPerHour) / 100
    	item.profitPerHour = math.floor(item.profit * item.potionPerHour)
    	
    	-- currency strings for table
    	if param.has_content(item.buy) then 
    		item.buyString = '|| {{Currency cell|' .. item.buy .. '}}'
    	else
    		item.buyString = '|| colspan="10" | Unknown'
    	end
    	
    	if param.has_content(item.sell) then 
    		item.sellString = '|| {{Currency cell|' .. item.sell .. '}}'
    	else
    		item.sellString = '|| colspan="10" | Unknown'
    	end
    	
    	if param.has_content(item.buy) and param.has_content(item.sell) then 
    		item.profitString = '|| {{Currency cell|' .. item.profit .. '}}'
    	else
    		item.profitString = '|| colspan="10" | Unknown'
    	end
    	
    	if param.has_content(item.buy) and param.has_content(item.sell) and param.has_content(item.brewXP) and param.has_content(item.prepXP) then 
    		item.profitPerXPString = '|| {{Currency cell|' .. item.profitPerXP .. '}}'
    	else
    		item.profitPerXPString = '|| colspan="10" | Unknown'
    	end
    	
    	if param.has_content(item.buy) and param.has_content(item.sell) and param.has_content(item.brewDuration) and param.has_content(item.prepDuration) then 
    		item.profitPerHourString = '|| {{Currency cell|' .. item.profitPerHour .. '}}'
    	else
    		item.profitPerHourString = '|| colspan="10" | Unknown'
    	end
		
		
		-- KP/KP strings
		if param.has_content(item.brewXP) and param.has_content(item.prepXP) then 
    		item.XPString = '|| {{formatnum:' .. item.XP .. '}}'
    	else
    		item.XPString = '|| Unknown'
		end
		
		if param.has_content(item.brewKP) and param.has_content(item.prepKP)  then 
    		item.KPString = '|| {{formatnum:' .. item.KP .. '}}%'
    	else
    		item.KPString = '|| Unknown'
		end
		
		if param.has_content(item.brewXP) and param.has_content(item.prepXP) and param.has_content(item.brewDuration) and param.has_content(item.prepDuration) then 
    		item.XPPerHourString = '|| {{formatnum:' .. item.XPPerHour .. '}}'
    	else
    		item.XPPerHourString = '|| Unknown'
		end
		
		if param.has_content(item.brewKP) and param.has_content(item.prepKP) and param.has_content(item.brewDuration) and param.has_content(item.prepDuration) then 
    		item.KPPerHourString =  '|| {{formatnum:' .. item.KPPerHour .. '}}'
    	else
    		item.KPPerHourString = '|| Unknown'
		end
		
	end

    return results
end

-- make the table
function p.displayTable(results)
	
    local out = {}
    table.insert(out, 'Potions per hour assumes 40 seconds resupply between each batch of 12 potions.')
    table.insert(out, '{| class="wikitable sortable"')
    
    local headerRow = {}
    table.insert(headerRow, '! Level')
    table.insert(headerRow, '!! Potion')
    table.insert(headerRow, '!! Reagents (plus bottle)')
    table.insert(headerRow, '!! colspan="10" | Buy Value')
    table.insert(headerRow, '!! colspan="10" | Sell Value')
    table.insert(headerRow, '!! colspan="10" | Profit')
    table.insert(headerRow, '!! colspan="10" | Profit/hr')
    table.insert(headerRow, '!! XP')
    table.insert(headerRow, '!! XP/hr')
    table.insert(headerRow, '!! colspan="10" | Profit/XP')
    table.insert(headerRow, '!! KP')
    table.insert(headerRow, '!! KP/hr')
	table.insert(out, table.concat(headerRow, ' '))
	
	for i,item in ipairs(results) do
		table.insert(out, '|-')
		
		local itemRow = {}
		table.insert(itemRow, '| [[File:Alchemist small icon.png|15px]]  ' .. item.lvl )
		table.insert(itemRow, '|| {{plink|' .. item.name .. '}}')
		
		table.insert(itemRow, '||')
		for j, reagent in ipairs(item.reagents) do
			table.insert(itemRow, '{{plink|' .. reagent .. '}}<br>')
		end
		
		table.insert(itemRow, item.buyString )
		table.insert(itemRow, item.sellString )
		table.insert(itemRow, item.profitString ) 
		table.insert(itemRow, item.profitPerHourString )
		table.insert(itemRow, item.XPString )
		table.insert(itemRow, item.XPPerHourString )
		table.insert(itemRow, item.profitPerXPString )
		table.insert(itemRow, item.KPString )
		table.insert(itemRow, item.KPPerHourString )
		
		table.insert(out, table.concat(itemRow, ' '))
	end
	
	table.insert(out, '|}')
	return table.concat(out, '\n')
end

return p