Module:Sandbox/User:Alsang/PotionList: Difference between revisions

From Brighter Shores Wiki
Jump to navigation Jump to search
Content added Content deleted
(reorder columns)
(mostly done, minor formatting left (commas in numbes, decimal places, zero currency replacement))
Line 1: Line 1:
require('Module:Mw.html extension')
local p = {}
local param = require( 'Module:Paramtest' )
local param = require( 'Module:Paramtest' )
local currency = require('Module:Currency')



local p = {}


-- non dynamic module, no inputs
-- non dynamic module, no inputs
Line 10: Line 13:
'[[Category:Potions]]',
'[[Category:Potions]]',
'[[Uses facility::Standard Potion Station||Potent Potion Station]]',
'[[Uses facility::Standard Potion Station||Potent Potion Station]]',
'[[Variant of::Fear]]',
'?Profession Level A = lvl',
'?Profession Level A = lvl',
'? #- = name',
'? #- = name',
Line 25: Line 27:
local results = mw.smw.ask(query)
local results = mw.smw.ask(query)
results = p.makeTableStrings(results)
results = p.formatResults(results)


-- actual output
return p.displayTable(results)
return p.displayTable(results)
end
-- for testing

--return '<pre>' ..mw.text.jsonEncode(results, mw.text.JSON_PRETTY).. '</pre>'
-- makes the html for the cells containing currency directly, no tags needed
-- flag is for if the number should not be known, replaces with zero
local function currency_cell(amount,flag)
local a = {}
if flag then
a = currency._cell(amount, { html = 'yes' })
else
a = currency._cell(0, { html = 'yes' }) -- replace this with blank, if I can figure out how to
end
return a
end
end


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


-- iterate through potions
-- iterate through potions
Line 65: Line 75:
-- sanitise data, set to 0 if its not there
-- sanitise data, set to 0 if its not there
local lvl = item.lvl or 0
local lvl = item.lvl or '?'
local buy = item.buy or 0
local sell = item.sell or 0
local sell = item.sell or 0
local brewXP = item.brewXP or 0
local brewXP = item.brewXP or 0
Line 75: Line 86:
-- direct values
-- direct values
item.profit = sell - item.buy
item.profit = sell - buy
item.XP = brewXP + prepXP
item.XP = brewXP + prepXP
item.KP = brewKP + prepKP
item.KP = brewKP + prepKP
Line 91: Line 102:
item.profitPerHour = math.floor(item.profit * item.potionPerHour)
item.profitPerHour = math.floor(item.profit * item.potionPerHour)
-- currency strings for table
-- flags for if data values should be shown
if param.has_content(item.buy) then
item.hasBuy = param.has_content(item.buy)
item.buyString = '|| {{Currency cell|' .. item.buy .. '}}'
item.hasSell = param.has_content(item.sell)
item.hasProfit = item.hasBuy and item.hasSell
else
item.hasXP = param.has_content(item.brewXP) and param.has_content(item.prepXP)
item.buyString = '|| colspan="10" | Unknown'
item.hasKP = param.has_content(item.brewKP) and param.has_content(item.prepKP)
end
item.hasDuration = param.has_content(item.brewDuration) and param.has_content(item.prepDuration)
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
-- XP/KP strings, if the requisite data isnt there then display "unknown"
if item.hasXP then
-- KP/KP strings
item.xp = tostring(item.xp) -- format to include commas
if param.has_content(item.brewXP) and param.has_content(item.prepXP) then
else
item.XPString = '|| {{formatnum:' .. item.XP .. '}}'
item.XP = 'Unknown'
else
item.XPString = '|| Unknown'
end
end
if param.has_content(item.brewKP) and param.has_content(item.prepKP) then
if item.hasKP then
item.KPString = '|| {{formatnum:' .. item.KP .. '}}%'
item.KP = tostring(item.KP) .. '%' -- want 1 decimal place
else
else
item.KPString = '|| Unknown'
item.KP = 'Unknown'
end
end
if item.hasXP and item.hasDuration then
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 .. '}}'
item.XPPerHour = tostring(item.XPPerHour) -- format to include commas
else
else
item.XPPerHourString = '|| Unknown'
item.XPPerHour = 'Unknown'
end
end
if item.hasKP and item.hasDuration then
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 .. '}}'
item.KPPerHour = tostring(item.KPPerHour) -- want 2 decimal places
else
else
item.KPPerHourString = '|| Unknown'
item.KPPerHour = 'Unknown'
end
end
Line 156: Line 144:
function p.displayTable(results)
function p.displayTable(results)
local out = {}
local out = mw.html.create('table')
:addClass('wikitable sortable')
table.insert(out, 'Potions per hour assumes 40 seconds resupply between each batch of 12 potions.')
:tag('tr')
table.insert(out, '{| class="wikitable sortable"')
:tag('th')
:wikitext('Level')
local headerRow = {}
:done()
table.insert(headerRow, '! Level')
:tag('th')
table.insert(headerRow, '!! Potion')
:wikitext('Potion')
table.insert(headerRow, '!! Reagents (plus bottle)')
:done()
table.insert(headerRow, '!! colspan="10" | Buy Value')
:tag('th')
table.insert(headerRow, '!! colspan="10" | Sell Value')
:wikitext('Reagents (plus bottle)')
table.insert(headerRow, '!! colspan="10" | Profit')
:done()
table.insert(headerRow, '!! colspan="10" | Profit/hr')
:tag('th')
table.insert(headerRow, '!! XP')
:attr{ colspan = '10' }
table.insert(headerRow, '!! XP/hr')
:wikitext('Buy Value')
table.insert(headerRow, '!! colspan="10" | Profit/XP')
:done()
table.insert(headerRow, '!! KP')
:tag('th')
table.insert(headerRow, '!! KP/hr')
:attr{ colspan = '10' }
table.insert(out, table.concat(headerRow, ' '))
:wikitext('Sell Value')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Profit')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Profit/hr')
:done()
:tag('th')
:wikitext('XP')
:done()
:tag('th')
:wikitext('XP/hr')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Profit/XP')
:done()
:tag('th')
:wikitext('KP')
:done()
:tag('th')
:wikitext('KP/hr')
:done()
:done()
for i,item in ipairs(results) do
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 .. '}}')
-- need to generate the text for the reagent cell before starting the row
table.insert(itemRow, '||')
local reagentCell = ''
for j, reagent in ipairs(item.reagents) do
for j, reagent in ipairs(item.reagents) do
table.insert(itemRow, '{{plink|' .. reagent .. '}}<br>')
reagentCell = reagentCell .. '[[File:' .. reagent .. '.png|30px|link=' .. reagent .. ']] [[' .. reagent .. ']]<br>'
end
end
out
table.insert(itemRow, item.buyString )
:tag('tr')
table.insert(itemRow, item.sellString )
:tag('td')
table.insert(itemRow, item.profitString )
:wikitext('[[File:Alchemist small icon.png|15px]] ' .. item.lvl)
table.insert(itemRow, item.profitPerHourString )
:done()
table.insert(itemRow, item.XPString )
:tag('td')
table.insert(itemRow, item.XPPerHourString )
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']] [[' .. item.name .. ']]')
table.insert(itemRow, item.profitPerXPString )
:done()
table.insert(itemRow, item.KPString )
:tag('td')
table.insert(itemRow, item.KPPerHourString )
:wikitext(reagentCell)
:done()
:wikitext(currency_cell(item.buy,item.hasBuy))
:wikitext(currency_cell(item.sell,item.hasSell))
:wikitext(currency_cell(item.profit,item.hasProfit))
:wikitext(currency_cell(item.profitPerHour,item.hasProfit and item.hasDuration))
:tag('td')
:wikitext(item.XP,item.hasXP)
:done()
:tag('td')
:wikitext(item.XPPerHour)
:done()
:wikitext(currency_cell(item.profitPerXP,item.hasXP and item.hasProfit))
:tag('td')
:wikitext(item.KP)
:done()
:tag('td')
:wikitext(item.KPPerHour)
:done()
:done()
table.insert(out, table.concat(itemRow, ' '))
end
end
return out
table.insert(out, '|}')
return table.concat(out, '\n')
end
end



Revision as of 16:49, 27 November 2024

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

require('Module:Mw.html extension')
local param = require( 'Module:Paramtest' )
local currency = require('Module:Currency')


local p = {}

-- 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]]',
		'?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.formatResults(results)

	return p.displayTable(results)
	
end

-- makes the html for the cells containing currency directly, no tags needed
-- flag is for if the number should not be known, replaces with zero
local function currency_cell(amount,flag)
	local a = {}
	if flag then
		a = currency._cell(amount, { html = 'yes' })
	else
		a = currency._cell(0, { html = 'yes' }) -- replace this with blank, if I can figure out how to
	end
	return a
end

-- do calculations and determine strings to go in cells
function p.formatResults(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 '?'
    	local buy = item.buy 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 - 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)
    	
    	-- flags for if data values should be shown
    	item.hasBuy = param.has_content(item.buy)
    	item.hasSell = param.has_content(item.sell)
    	item.hasProfit = item.hasBuy and item.hasSell
    	item.hasXP = param.has_content(item.brewXP) and param.has_content(item.prepXP)
    	item.hasKP = param.has_content(item.brewKP) and param.has_content(item.prepKP)
    	item.hasDuration = param.has_content(item.brewDuration) and param.has_content(item.prepDuration)
    	
		
		-- XP/KP strings, if the requisite data isnt there then display "unknown"
		if item.hasXP then 
			item.xp = tostring(item.xp) -- format to include commas
		else
    		item.XP = 'Unknown'
		end
		
		if item.hasKP  then 
    		item.KP = tostring(item.KP) .. '%' -- want 1 decimal place
    	else
    		item.KP = 'Unknown'
		end
		
		if item.hasXP and item.hasDuration then 
    		item.XPPerHour = tostring(item.XPPerHour) -- format to include commas
    	else
    		item.XPPerHour = 'Unknown'
		end
		
		if item.hasKP and item.hasDuration then 
    		item.KPPerHour =  tostring(item.KPPerHour) -- want 2 decimal places
    	else
    		item.KPPerHour = 'Unknown'
		end
		
	end

    return results
end

-- make the table
function p.displayTable(results)
	
    local out = mw.html.create('table')
		:addClass('wikitable sortable')
		:tag('tr')
			:tag('th')
				:wikitext('Level')
			:done()
			:tag('th')
				:wikitext('Potion')
			:done()
			:tag('th')
				:wikitext('Reagents (plus bottle)')
			:done()
			:tag('th')
				:attr{ colspan = '10' }
				:wikitext('Buy Value')
			:done()
			:tag('th')
				:attr{ colspan = '10' }
				:wikitext('Sell Value')
			:done()
			:tag('th')
				:attr{ colspan = '10' }
				:wikitext('Profit')
			:done()
			:tag('th')
				:attr{ colspan = '10' }
				:wikitext('Profit/hr')
			:done()
			:tag('th')
				:wikitext('XP')
			:done()
			:tag('th')
				:wikitext('XP/hr')
			:done()
			:tag('th')
				:attr{ colspan = '10' }
				:wikitext('Profit/XP')
			:done()
			:tag('th')
				:wikitext('KP')
			:done()
			:tag('th')
				:wikitext('KP/hr')
			:done()
		:done()
		
	
	for i,item in ipairs(results) do
		
		-- need to generate the text for the reagent cell before starting the row	
		local reagentCell = ''
		for j, reagent in ipairs(item.reagents) do
			reagentCell = reagentCell .. '[[File:' .. reagent .. '.png|30px|link=' .. reagent .. ']] [[' .. reagent .. ']]<br>'
		end
		
	out
		:tag('tr')
			:tag('td')
				:wikitext('[[File:Alchemist small icon.png|15px]]  ' .. item.lvl)
			:done()
			:tag('td')
				:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']] [[' .. item.name .. ']]')
			:done()
			:tag('td')
				:wikitext(reagentCell)
			:done()
			:wikitext(currency_cell(item.buy,item.hasBuy))
			:wikitext(currency_cell(item.sell,item.hasSell))
			:wikitext(currency_cell(item.profit,item.hasProfit))
			:wikitext(currency_cell(item.profitPerHour,item.hasProfit and item.hasDuration))
			:tag('td')
				:wikitext(item.XP,item.hasXP)
			:done()
			:tag('td')
				:wikitext(item.XPPerHour)
			:done()
			:wikitext(currency_cell(item.profitPerXP,item.hasXP and item.hasProfit))
			:tag('td')
				:wikitext(item.KP)
			:done()
			:tag('td')
				:wikitext(item.KPPerHour)
			:done()
		:done()
		
	end
	
	return out
end

return p