Module:Sandbox/User:Alsang/NodeDescriptionChecker

From Brighter Shores Wiki
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Module:Sandbox/User:Alsang/NodeDescriptionChecker/doc. [edit] [history] [purge]
This module does not have any documentation. Please consider adding documentation at Module:Sandbox/User:Alsang/NodeDescriptionChecker/doc. [edit]
Module:Sandbox/User:Alsang/NodeDescriptionChecker's function main is invoked by Template:Sandbox/User:Alsang/NodeDescriptionChecker.
Module:Sandbox/User:Alsang/NodeDescriptionChecker requires Module:Currency.
Module:Sandbox/User:Alsang/NodeDescriptionChecker requires Module:Mw.html extension.
Module:Sandbox/User:Alsang/NodeDescriptionChecker requires Module:Paramtest.
Module:Sandbox/User:Alsang/NodeDescriptionChecker requires Module:RecipeTreeSearch.
Module:Sandbox/User:Alsang/NodeDescriptionChecker requires strict.

require('strict')
require('Module:Mw.html extension')
local search = require('Module:RecipeTreeSearch')
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
	local query = {
		--'[[Uses facility::One Handed Range (bonewright)||One Handed Melee Workbench (bonewright)||Two Handed Range Workbench (bonewright)||Two Handed Melee Workbench (bonewright)||Shield Vice]', -- bonewright active
		'[[Uses facility::One Handed Ranged Workbench (stonemason)||One Handed Melee Workbench (stonemason)||Two Handed Ranged Workbench (stonemason)||Two Handed Melee Workbench (stonemason)||Shield Work Rock]]', -- stonemason active 
		--'[[Uses facility::Goblin Forge||Gnome Forge (skill node)]]', -- blacksmith active
		'?Profession Level A = lvlLow',
		'?Profession Level A High = lvlHigh',
		'?Uses facility = facility',
		'? #- = name',
		'?Recipe JSON = recipeJSON',
		'?Activity XP = XP',
		'?Activity duration = duration',
		'?Value = sell',
		'sort = Activity level',
		'limit = 500'
	}
	local results = mw.smw.ask(query)

	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

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

	-- iterate through products
	for _, item in ipairs(results) do
		
		-- New module for recipe searching
		local fullRecipe = search.main(item.name)
		item.materials = fullRecipe.materials
		item.outputQuantity = fullRecipe.output[1].quantity
		item.buy = fullRecipe.buyPrice
		item.XP = fullRecipe.xp
		item.duration = fullRecipe.duration
		
		-- specific to weapon crafting, where properties are a bit different
		item.lvl = fullRecipe.level
		
		-- iterate through materials, keep track of how many materials are needed from each shop
		item.poleShopTrips = 0
		item.stoneShopTrips = 0
		for _, material in ipairs(item.materials) do
		
			-- query which shop sold it, add to running total
			local shopNameQuery = '[[:+]][[Sold item::' .. material.name .. ']]|?Sold by #-|mainlabel=' .. material.name
			local shopNameResult = mw.smw.ask(shopNameQuery) or {}
			local shopName = ''

			if shopNameResult[1] and shopNameResult[1]["Sold by"] then
				shopName = shopNameResult[1]["Sold by"] or ''
			end
			
			if shopName=="Timber Merchant Shop" then
				item.poleShopTrips = item.poleShopTrips + material.quantity
			elseif shopName=="Poffit's Interesting Rocks" then
				item.stoneShopTrips = item.stoneShopTrips + material.quantity
			end

		end
		
		-- direct values
		item.sell = item.sell and item.outputQuantity and item.sell * item.outputQuantity
		item.costPerXP = item.buy and item.XP and math.floor(item.buy / item.XP * 100) / 100
		item.XPPerStone = item.XP and not(item.stoneShopTrips==0) and math.floor(item.XP / item.stoneShopTrips * 100) / 100
		item.XPPerSpace = item.XPPerStone and item.poleShopTrips and math.floor(item.XP / (item.stoneShopTrips + item.poleShopTrips) * 100) / 100

		-- there will be extra time spent buying and selling items, and moving between stations
		-- assume make enough trips to buy 24 of each material from each shop, per batch of 24 weapons
		local batchSize = 24
		-- 120 seconds moving between stations and selling items per 24 made
		-- 40 seconds per trip to the pole shop
		-- 40 seconds per trip to the stone shop
		-- are these results optimal? no. are they approximate? yes
		local downtime = 120 + item.poleShopTrips * 40 + item.stoneShopTrips * 40
		item.duration = item.duration and item.duration + downtime/batchSize
		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)
	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:Stonemason small icon.png|15px]]  Level')
			:done()
			:tag('th')
				:wikitext('[[File:Hammermage small icon.png|15px]] Levels')
			:done()
			:tag('th')
				:attr{ colspan = '3' }
				:wikitext('Products')
			:done()
			:tag('th')
				:wikitext('Materials')
			:done()
			:tag('th')
				:attr{ colspan = '10' }
				:wikitext('Buy Value')
			:done()
			:tag('th')
				:wikitext('XP<br>(per item)')
			:done()
			:tag('th')
				:wikitext('XP<br>(per stome)')
			:done()
			:tag('th')
				:wikitext('XP<br>(per space)')
			:done()
			:tag('th')
				:wikitext('XP/hr')
			:done()
			:tag('th')
				:attr{ colspan = '10' }
				:wikitext('Coins/XP')
			: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')
			:IF(item.lvl)
				:tag('td')
					:css{ ['text-align'] = 'center' }
					:wikitext(item.lvl)
				:done()
			:ELSE()
				:node(unknown_value_cell)
			:END()
			:IF(item.lvlHigh and item.lvlLow)
				:tag('td')
					:css{ ['text-align'] = 'center' }
					:wikitext(item.lvlLow)
					:wikitext(' – ')
					:wikitext(item.lvlHigh)
				:done()
			:ELSE()
				:node(unknown_value_cell)
			:END()

			:tag('td')
				:css{ ['border-right'] = '0', ['padding-right'] = '0', ['text-align'] = 'right' }
				:attr{ ['data-sort-value'] = item.name }
				:wikitext(item.outputQuantity .. ' &times;')
			:done()
			:tag('td')
				:addClass('plinkt-image no-border')
				:css{ ['border-left'] = '0', ['padding-left'] = '0' }
				:wikitext('[[File:' .. item.name .. '.png|link=' .. item.name .. '|30px]]')
			:done()
			:tag('td')
				:addClass('plinkt-link no-border')
				:wikitext('[[' .. item.name .. ']]')
			:done()

		local materialCell = row:tag('td')

		for i, _ in ipairs(item.materials) do
			materialCell:wikitext(item.materials[i].quantity .. '&times; [[File:' .. item.materials[i].name .. '.png|18px|link=' .. item.materials[i].name .. ']] [[' .. item.materials[i].name .. ']]<br>')
		end
		
		row
			:node(currency_cell(item.buy))

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

			:IF(item.XPPerStone)
				:tag('td')
					:wikitext(item.XPPerStone and lang:formatNum(tonumber(item.XPPerStone)))
				:done()
			:ELSE()
				:node(unknown_value_cell)
			:END()

			:IF(item.XPPerSpace)
				:tag('td')
					:wikitext(item.XPPerSpace and lang:formatNum(tonumber(item.XPPerSpace)))
				:done()
			:ELSE()
				:node(unknown_value_cell)
			:END()

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

			:node(currency_cell(item.costPerXP))

		:done()
	end

	return out
end

return p