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

From Brighter Shores Wiki
Jump to navigation Jump to search
Content added Content deleted
(reorder columns)
(remove vestigial KP per hour calcs, add in thousands separator commas)
 
(5 intermediate revisions by the same user not shown)
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 lang = mw.getContentLanguage()
require("Module:Mw.html extension")



local p = {}


-- non dynamic module, no inputs
-- non dynamic module, no inputs
Line 10: Line 15:
'[[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',
'?Uses item.Uses item #- = reagents',
'?Uses item.Uses item #- = reagents',
'?Value = sell',
'?Value = sell',
'?Recipe XP = brewXP',
'?Activity XP = brewXP',
'?Uses item.Recipe XP = prepXP',
'?Uses item.Activity XP = prepXP',
'?Recipe KP = brewKP',
'?Activity KP = brewKP',
'?Uses item.Recipe KP = prepKP',
'?Uses item.Activity KP = prepKP',
'?Recipe duration = brewDuration',
'?Activity duration = brewDuration',
'?Uses item.Recipe duration = prepDuration',
'?Uses item.Activity duration = prepDuration',
'sort = Profession Level A'
'sort = Profession Level A'
}
}
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)
-- for testing
--return '<pre>' ..mw.text.jsonEncode(results, mw.text.JSON_PRETTY).. '</pre>'
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)
return currency._cell(amount, { html = 'yes' })
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 71:
-- 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 82:
-- 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 98:
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.hasLvl = param.has_content(item.lvl)
item.buyString = '|| {{Currency cell|' .. item.buy .. '}}'
item.hasBuy = param.has_content(item.buy)
item.hasSell = param.has_content(item.sell)
else
item.buyString = '|| colspan="10" | Unknown'
item.hasProfit = item.hasBuy and item.hasSell
item.hasXP = param.has_content(item.brewXP) and param.has_content(item.prepXP)
end
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)
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
end


Line 156: Line 115:
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('[[File:Alchemist small icon.png|15px]] 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('Coins/XP')
:done()
:done()
for i,item in ipairs(results) do
for i,item in ipairs(results) do
table.insert(out, '|-')
-- need to generate the text for the reagent cell before starting the row
local itemRow = {}
local reagentCell = ''
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
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 )
table.insert(itemRow, item.profitString )
:tag('td')
table.insert(itemRow, item.profitPerHourString )
table.insert(itemRow, item.XPString )
:IF(item.hasBuy)
:css{ ['text-align'] = 'center' }
table.insert(itemRow, item.XPPerHourString )
:wikitext(item.lvl)
table.insert(itemRow, item.profitPerXPString )
:ELSE()
table.insert(itemRow, item.KPString )
:addClass('table-bg-grey')
table.insert(itemRow, item.KPPerHourString )
:css{ ['text-align'] = 'center' }
:wikitext('unknown')
:END()
:done()
:tag('td')
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']] [[' .. item.name .. ']]')
:done()
:tag('td')
:wikitext(reagentCell)
:done()
:IF(item.hasBuy)
:wikitext(currency_cell(item.buy))
:ELSE()
:tag('td')
:addClass('table-bg-grey')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'center' }
:wikitext('unknown')
:done()
:END()
:IF(item.hasSell)
:wikitext(currency_cell(item.sell))
:ELSE()
:tag('td')
:addClass('table-bg-grey')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'center' }
:wikitext('unknown')
:done()
:END()
:IF(item.hasProfit)
:wikitext(currency_cell(item.profit))
:ELSE()
:tag('td')
:addClass('table-bg-grey')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'center' }
:wikitext('unknown')
:done()
:END()
:IF(item.hasProfit and item.hasDuration)
:wikitext(currency_cell(item.profitPerHour))
:ELSE()
:tag('td')
:addClass('table-bg-grey')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'center' }
:wikitext('unknown')
:done()
:END()
:tag('td')
:IF(item.hasXP)
:wikitext(lang:formatNum(tonumber(item.XP)))
:ELSE()
:addClass('table-bg-grey')
:css{ ['text-align'] = 'center' }
:wikitext('unknown')
:END()
:done()
:tag('td')
:IF(item.hasXP and item.hasDuration)
:wikitext(lang:formatNum(tonumber(item.XPPerHour)))
:ELSE()
:addClass('table-bg-grey')
:css{ ['text-align'] = 'center' }
:wikitext('unknown')
:END()
:done()
:IF(item.hasXP and item.hasProfit)
:wikitext(currency_cell(item.profitPerXP))
:ELSE()
:tag('td')
:addClass('table-bg-grey')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'center' }
:wikitext('unknown')
:done()
:END()
:done()
table.insert(out, table.concat(itemRow, ' '))
end
end
return out
table.insert(out, '|}')
return table.concat(out, '\n')
end
end



Latest revision as of 00:20, 28 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 lang = mw.getContentLanguage()
require("Module:Mw.html extension")


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',
		'?Activity XP = brewXP',
		'?Uses item.Activity XP = prepXP',
		'?Activity KP = brewKP',
		'?Uses item.Activity KP = prepKP',
		'?Activity duration = brewDuration',
		'?Uses item.Activity 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)
	return currency._cell(amount, { html = 'yes' })
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.hasLvl = param.has_content(item.lvl)
    	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)
    	
	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('[[File:Alchemist small icon.png|15px]]  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('Coins/XP')
			: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')
				:IF(item.hasBuy)
					:css{ ['text-align'] = 'center' }
					:wikitext(item.lvl)
				:ELSE()
					:addClass('table-bg-grey')
					:css{ ['text-align'] = 'center' }
					:wikitext('unknown')
				:END()
			:done()
			
			:tag('td')
				:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']] [[' .. item.name .. ']]')
			:done()
			
			:tag('td')
				:wikitext(reagentCell)
			:done()
			
			:IF(item.hasBuy)
				:wikitext(currency_cell(item.buy))
			:ELSE()
				:tag('td')
					:addClass('table-bg-grey')
					:attr{ colspan = '10' }
					:css{ ['text-align'] = 'center' }
					:wikitext('unknown')
				:done()
			:END()
			
			:IF(item.hasSell)
				:wikitext(currency_cell(item.sell))
			:ELSE()
				:tag('td')
					:addClass('table-bg-grey')
					:attr{ colspan = '10' }
					:css{ ['text-align'] = 'center' }
					:wikitext('unknown')
				:done()
			:END()
				
			:IF(item.hasProfit)
				:wikitext(currency_cell(item.profit))
			:ELSE()
				:tag('td')
					:addClass('table-bg-grey')
					:attr{ colspan = '10' }
					:css{ ['text-align'] = 'center' }
					:wikitext('unknown')
				:done()
			:END()
			
			:IF(item.hasProfit and item.hasDuration)
				:wikitext(currency_cell(item.profitPerHour))
			:ELSE()
				:tag('td')
					:addClass('table-bg-grey')
					:attr{ colspan = '10' }
					:css{ ['text-align'] = 'center' }
					:wikitext('unknown')
				:done()
			:END()
			
			:tag('td')
				:IF(item.hasXP)
					:wikitext(lang:formatNum(tonumber(item.XP)))
				:ELSE()
					:addClass('table-bg-grey')
					:css{ ['text-align'] = 'center' }
					:wikitext('unknown')
				:END()
			:done()
			
			:tag('td')
				:IF(item.hasXP and item.hasDuration)
					:wikitext(lang:formatNum(tonumber(item.XPPerHour)))
				:ELSE()
					:addClass('table-bg-grey')
					:css{ ['text-align'] = 'center' }
					:wikitext('unknown')
				:END()
			:done()
			
			:IF(item.hasXP and item.hasProfit)
				:wikitext(currency_cell(item.profitPerXP))
			:ELSE()
				:tag('td')
					:addClass('table-bg-grey')
					:attr{ colspan = '10' }
					:css{ ['text-align'] = 'center' }
					:wikitext('unknown')
				:done()
			:END()
			
		:done()
		
	end
	
	return out
end

return p