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

(reorder columns)
(rename the SMW properties "Recipe XP", "Recipe KP", and "Recipe duration" to "Activity XP", "Activity KP", and "Activity duration" so they can generate the same fields as Template:Profession info)
 
(3 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 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',
'?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,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 = lang:formatNum(item.xp) -- format to include commas
if param.has_content(item.brewXP) and param.has_content(item.prepXP) then
item.XPString = '|| {{formatnum:' .. item.XP .. '}}'
item.XP = item.XP -- format to include commas
else
else
item.XPString = '|| Unknown'
item.XP = '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 = 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 = 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 = item.KPPerHour -- want 2 decimal places
else
else
item.KPPerHourString = '|| Unknown'
item.KPPerHour = 'Unknown'
end
end
Line 156: Line 145:
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()
--: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 )
:css{ ['text-align'] = 'center' }
table.insert(itemRow, item.profitPerHourString )
table.insert(itemRow, item.XPString )
:wikitext(item.lvl)
:done()
table.insert(itemRow, item.XPPerHourString )
:tag('td')
table.insert(itemRow, item.profitPerXPString )
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']] [[' .. item.name .. ']]')
table.insert(itemRow, item.KPString )
:done()
table.insert(itemRow, item.KPPerHourString )
: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)
: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



Latest revision as of 19:12, 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',
		'?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,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 = lang:formatNum(item.xp) -- format to include commas
			item.XP = item.XP -- format to include commas
		else
    		item.XP = 'Unknown'
		end
		
		if item.hasKP  then 
    		item.KP = item.KP .. '%' -- want 1 decimal place
    	else
    		item.KP = 'Unknown'
		end
		
		if item.hasXP and item.hasDuration then 
    		item.XPPerHour = item.XPPerHour -- format to include commas
    	else
    		item.XPPerHour = 'Unknown'
		end
		
		if item.hasKP and item.hasDuration then 
    		item.KPPerHour =  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('[[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()
			--: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')
				:css{ ['text-align'] = 'center' }
				:wikitext(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)
			: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