Module:WoodcutterPassiveList: Difference between revisions

From Brighter Shores Wiki
Jump to navigation Jump to search
Content added Content deleted
(all done apart from sorting it properly)
(switch to sorting after the SMW query)
 
Line 12: Line 12:
-- returns only directly needed parameter needed for the row,
-- returns only directly needed parameter needed for the row,
-- other parameters are determined by subqueries of chained pages
-- other parameters are determined by subqueries of chained pages
-- Woodcutter cannot sort by any parameter, as Branches use Profession B but Split Wood uses profession A
local query = {
local query = {
'[[Variant of::~*Tree||~Split Wood for*]]',
'[[Variant of::~*Tree||~Split Wood for*]]',
'?Profession Level B = lvl',
'? #- = name',
'? #- = name',
'?Image #- = Image',
'?Image #- = Image',
'?Activity JSON = activityJSON',
'?Activity JSON = activityJSON',
'?Activity coins = coins',
'?Activity coins = coins',
-- 'sort = Profession Level B',
'limit = 500'
'limit = 500'
}
}
Line 77: Line 76:
end
end
-- sort the results by recipe level
table.sort(resultsScreened, function(item1, item2)
local lvl1 = item1.lvl
local lvl2 = item2.lvl
if (lvl1 == nil) ~= (lvl2 == nil) then --one of two are empty
return lvl2 == nil -- true if lvl2 is nil but not lvl1, false if lvl1 is nil but not lvl2
end
if lvl1 == nil then
return false -- Both empty, equivalent
end
return lvl1 < lvl2 -- normal comparison
end)

return resultsScreened
return resultsScreened



Latest revision as of 12:26, 16 December 2024

Module documentation
This documentation is transcluded from Module:WoodcutterPassiveList/doc. [edit] [history] [purge]
This module does not have any documentation. Please consider adding documentation at Module:WoodcutterPassiveList/doc. [edit]
Module:WoodcutterPassiveList's function main is invoked by Template:WoodcutterPassiveList.
Module:WoodcutterPassiveList requires Module:Currency.
Module:WoodcutterPassiveList requires Module:Mw.html extension.
Module:WoodcutterPassiveList requires Module:Paramtest.
Module:WoodcutterPassiveList requires strict.

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

local p = {}

-- non dynamic module, no inputs
function p.main()
	
	-- returns only directly needed parameter needed for the row,
	-- other parameters are determined by subqueries of chained pages
	-- Woodcutter cannot sort by any parameter, as Branches use Profession B but Split Wood uses profession A
	local query = {
		'[[Variant of::~*Tree||~Split Wood for*]]',
		'? #- = name',
		'?Image #- = Image',
		'?Activity JSON = activityJSON',
		'?Activity coins = coins',
		'limit = 500'
	}
	local results = mw.smw.ask(query)
	
	results = p.screenResults(results)

	results = p.formatResults(results)

	return p.displayTable(results)
	
	--for debugging
	--return '<pre>'..mw.text.jsonEncode(results, mw.text.JSON_PRETTY)..'</pre>'

end

-- makes the html for the cells containing currency directly
-- Replaces nil with an "unknown" cell
local function currency_cell(amount)
	if not amount then
		return mw.html.create('td')
			:addClass('table-bg-gray')
			:css{ ['text-align'] = 'center' }
			:attr{ colspan = '10' }
			:wikitext("''unknown''")
		:done()
	end
	return currency._cell(amount, { html = 'yes' })
end

-- goes through a list of results and culls the ones which are not needed for this table
function p.screenResults(results)
	local resultsScreened = {}
	
	-- iterate through products
	for _, item in ipairs(results) do
		
		-- if theres only one activity, wrap in table
		if type(item.activityJSON)=='string' then
			item.activityJSON = { item.activityJSON }
		end
		
		for j,json in ipairs(item.activityJSON) do
		
			if string.find(json,'Branches') or string.find(json,'Split') then
				
				local activityJSON = mw.text.jsonDecode(json)
				
				item.XP = activityJSON.xp
				item.lvl = activityJSON.level
				item.duration = activityJSON.duration and tonumber(activityJSON.duration)
				item.product = activityJSON.output[1].name
				item.activityJSON = json
				table.insert(resultsScreened,item)
			end
		end
	end
	
	-- sort the results by recipe level
	table.sort(resultsScreened, function(item1, item2)
		local lvl1 = item1.lvl
		local lvl2 = item2.lvl
		if (lvl1 == nil) ~= (lvl2 == nil) then --one of two are empty
			return lvl2 == nil -- true if lvl2 is nil but not lvl1, false if lvl1 is nil but not lvl2
		end
		if lvl1 == nil then
			return false  -- Both empty, equivalent
		end
		return lvl1 < lvl2 -- normal comparison
	end)

	return resultsScreened

end

-- do calculations and determine strings to go in cells
function p.formatResults(results)
	
	-- iterate through products
	for _, item in ipairs(results) do
			
		item.givesCoins = string.find(item.product,'Split')

		-- profit from selling the items
		if not item.givesCoins then
			
			-- protection against missing parameters
			item.product = item.product or ''
			
			-- query is: there is a shop object page that has this item AND has buy price cannot be "N/A"
			local query = mw.smw.ask('[[Sold item::' .. item.product .. ']][[Shop sell price::!~N/A]]|?Shop sell price=data|mainlabel=-')
			if type(query)=='table' then
				-- price is returned as a number
				item.coins = tonumber(query[1].data)*0.005 or 0
			else
				-- will return nil if the item is not in a shop, or if it is in a shop but can only be sold to the shop
				item.coins =  0
			end
			
		end
		
		-- no downtime for passives
		item.productPerHour = item.duration and 1 / item.duration * 3600

		-- properties per hour
		item.XPPerHour = item.XP and item.productPerHour and math.floor(item.XP * item.productPerHour)
		item.coinsPerHour = item.coins and item.productPerHour and math.floor(item.coins * item.productPerHour)
	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:Woodcutter small icon.png|15px]]  Level')
			:done()
			:tag('th')
				:attr{ colspan = '2' }
				:wikitext('Woodcutter node')
			:done()
			:tag('th')
				:attr{ colspan = '3' }
				:wikitext('Product')
			:done()
			:tag('th')
				:wikitext('Quantity/hr')
			:done()
			:tag('th')
				:attr{ colspan = '10' }
				:wikitext('Profit/hr')
			:done()
			:tag('th')
				:wikitext('XP')
			:done()
			:tag('th')
				:wikitext('XP/hr')
			:done()
		:done()

	local unknown_value_cell = mw.html.create('td')
		:addClass('table-bg-gray')
		:css{ ['text-align'] = 'center' }
		:wikitext("''unknown''")

	for i, item in ipairs(results) do
		local row = out:tag('tr')
		
			--level
			:IF(item.lvl)
				:tag('td')
					:css{ ['text-align'] = 'center' }
					:wikitext(item.lvl)
				:done()
			:ELSE()
				:node(unknown_value_cell)
			:END()
			
			-- activity
			:tag('td')
				:css{ ['border-right'] = '0', ['text-align'] = 'right' }
				:addClass('plinkt-link no-border')
				:attr{ ['data-sort-value'] = item.name }
				:wikitext(' [[' .. item.Image .. '|link=' .. item.name .. '|30x30px]]')
			:done()
			:tag('td')
				:addClass('plinkt-link no-border')
				:wikitext('[[' .. item.name .. ']]')
			:done()
			
			-- products (coins or items)
			:IF(item.givesCoins)
				:IF(item.coins)
					:tag('td')
						:css{ ['border-right'] = '0', ['text-align'] = 'right' }
						:addClass('plinkt-link no-border')
						:attr{ ['data-sort-value'] = item.product }
						:wikitext(item.coins)
					:done()
				:ELSE()
					:node(unknown_value_cell)
				:END()
				:tag('td')
					:css{ ['border-right'] = '0', ['text-align'] = 'center' }
					:addClass('plinkt-link no-border')
					:wikitext('[[File:Copper coin.png|20x20px]]')
				:done()
				:tag('td')
					:addClass('plinkt-link no-border')
					:wikitext('Coins')
				:done()
			:ELSE()
				:tag('td')
					:css{ ['border-right'] = '0', ['text-align'] = 'right' }
					:addClass('plinkt-link no-border')
					:attr{ ['data-sort-value'] = item.product }
					:wikitext('0.005 &times; ')
				:done()
				:tag('td')
					:css{ ['border-right'] = '0', ['text-align'] = 'center' }
					:addClass('plinkt-link no-border')
					:wikitext('[[File:' .. item.product .. '.png|link=' .. item.product .. '|30x30px]]')
				:done()
				:tag('td')
					:addClass('plinkt-link no-border')
					:wikitext('[[' .. item.product .. ']]')
				:done()
			:END()
			
			-- products per hour (items)
			:IF(item.givesCoins)
				:tag('td')
					:addClass('table-na')
					:wikitext('N/A')
				:done()
			:ELSE()
				:tag('td')
					:css{ ['text-align'] = 'right' }
					:wikitext('0.9 &times; [[File:' .. item.product .. '.png|link=' .. item.product .. '|30x30px]]')
				:done()
			:END()
			
			-- profit per hour (coins)
			:node(currency_cell(item.coinsPerHour))

			-- XP
			:IF(item.XP)
				:tag('td')
					:wikitext(item.XP and lang:formatNum(tonumber(item.XP)))
				:done()
			:ELSE()
				:node(unknown_value_cell)
			:END()
			
			-- XP per hour
			:IF(item.XPPerHour)
				:tag('td')
					:wikitext(item.XPPerHour and lang:formatNum(tonumber(item.XPPerHour)))
				:done()
			:ELSE()
				:node(unknown_value_cell)
			:END()

		:done()
	end

	return out
end

return p