Module:LeatherworkerList: Difference between revisions

offload much of the search, screen, and format functions to the new ProfessionList module, so they work the same for all table
(switch from using Infobox Recipe function _getTrueRawMaterials to a purpose built module RecipeTreeSearch designed for combining multi-stage recipes)
(offload much of the search, screen, and format functions to the new ProfessionList module, so they work the same for all table)
Line 1:
require('strict')
require('Module:Mw.html extension')
local search = require('Module:RecipeTreeSearch')
local param = require( 'Module:Paramtest' )
local currency = require('Module:Currency')
local discount = require('Module:MerchantHideDiscount')
local lang = mw.getContentLanguage()
local plist = require('Module:ProfessionList')
local rts = require('Module:RecipeTreeSearch')
local discount = require('Module:MerchantHideDiscount')
 
local p = {}
Line 12 ⟶ 11:
function p.main()
local queryString = '[[Category:Leatherworker]] AND [[Category:Pages with recipes]]'
-- main query returns only directly needed parameter needed for the row,
-- other parameters are determined by subqueries of chained pages
local query = {
'[[-Sold item.Sold by::Leather stall]]',
'[[Recipe JSON::~*]]', -- the stall sells scraps and we need to ignore those
'?Uses facility #- = facility',
'?Profession Level A = lvl',
'? #- = name',
'?Recipe JSON = recipeJSON',
'?Activity XP = XP',
'?Activity duration = duration',
'?Value = sell',
'?Activity coins = coins',
'sort = Profession Level A',
'limit = 500'
}
local results = mw.smw.ask(query)
local function screenFunction(item)
-- criterion for if an entry is a recipe, or a passive activity
local product = (item.output and item.output[1] and item.output[1].name) or ''
for _, item in ipairs(results) do
return string.find(product,'Leather') and (not item.passive)
item.passiveActivity = false -- no passives in this list
end
local results = plist.generate_recipe_table(queryString,screenFunction)
 
results = p.formatResults(results)
 
Line 42 ⟶ 27:
--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)
 
--simple check for nil results
if results ==nil or results[1] == nil then
return nil
end
-- iterate through products
for _, item in ipairs(results) do
-- sole hide material
-- New module for recipe searching
item.material = (item.materials and item.materials[1] and item.materials[1].name) or ''
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
-- list of all pages to edit, if edit is needed
-- discounted buy price is not included by the RecipeTreeSearch module, have to do it manually
item.buyDiscountallPageEdits = 0{ item.pageName }
for _, materialintermediate in ipairs(item.materialsintermediateMaterials) do
table.insert(item.allPageEdits,intermediate.name)
end
-- poles will show as making 1 and using 0.5 log, which doesnt match the look of planks or staves
--with the merchant discount, buy price is sell price
-- double them,
local shopPriceQuery = '[[:+]][[Sold item::' .. material.name .. ']]|?Shop sell price|mainlabel=' .. material.name
if item.pageName and string.find(item.pageName,'Pole') then
local shopPriceResult = mw.smw.ask(shopPriceQuery) or {}
item.output[1].quantity = item.output and item.output[1] and item.output[1].quantity and item.output[1].quantity * 2
local shopPrice = 0
item.buyPrice = item.buyPrice and item.buyPrice * 2
item.sellPrice = item.sellPrice and item.sellPrice * 2
item.profit = item.profit and item.profit * 2
item.xp = item.xp and item.xp * 2
item.duration = item.duration and item.duration * 2
for j,jtem in ipairs(item.materials) do
if shopPriceResult[1] and shopPriceResult[1]["Shop sell price"] then
jtem.quantity = jtem.quantity and jtem.quantity * 2
shopPrice = tonumber(shopPriceResult[1]["Shop sell price"]) or 0
else
item.buyDiscount = nil
end
 
item.buyDiscount = item.buyDiscount and item.buyDiscount + shopPrice * material.quantity
end
-- direct valuesprofitability
item.sellprofitPerXP = item.sellprofit and item.outputQuantityxp and item.sellprofit */ item.outputQuantityxp
item.profit = item.sell and item.buy and item.sell - item.buy
-- 40 seconds to buy new supplies and travel and deposit and everything, per 12 potions
item.profitDiscount = item.sell and item.buyDiscount and item.sell - item.buyDiscount
item.profitPerXP = item.profit and item.XP and math.floor(item.profit / item.XP * 100) / 100
item.profitPerXPDiscount = item.profitDiscount and item.XP and math.floor(item.profitDiscount / item.XP * 100) / 100
local hideName = string.gsub(item.name,'Leather','Hide')
item.discountLevel = discount[hideName]
 
-- a lot of downtime in leatherworker, but large batch sizes
-- 1min 40s to go from hide stall to tannery, run round the tannery, run to leather stall, then back to hide stall
local batchSize = 24
local downtime = 100
Line 108 ⟶ 74:
 
-- properties per hour
item.XPPerHourxpPerHour = item.XPxp and item.productPerHour and math.floor(item.XPxp * item.productPerHour)
item.profitPerHour = item.profit and item.productPerHour and math.floor(item.profit * item.productPerHour)
item.profitPerHourDiscount = item.profit and item.productPerHour and math.floor(item.profit * item.productPerHour)
 
-- discounted buy price is not provided by the search, have to do it manually
item.discountLevel = discount[item.material]
item.buyPriceDiscount = rts.getShopSellPrice(item.material)
item.profitDiscount = item.sellPrice and item.buyPriceDiscount and item.sellPrice - item.buyPriceDiscount
item.profitPerHourDiscount = item.profitDiscount and item.productPerHour and math.floor(item.profitDiscount * item.productPerHour)
end
 
Line 118 ⟶ 93:
-- make the table
function p.displayTable(results)
--simple check for nil results
if results ==nil or results[1] == nil then
return 'No data found for table'
end
local out = mw.html.create('table')
:addClass('wikitable sortable')
Line 126 ⟶ 107:
:tag('th')
:attr{ colspan = '3' }
:wikitext('ProductProducts')
:done()
:tag('th')
:attr{ colspan = '3' }
:wikitext('Materials')
:done()
Line 153 ⟶ 135:
: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)
--level
:IF(item.level)
:tag('td')
:css{ ['text-align'] = 'center' }
:wikitext(item.lvllevel)
:done()
:ELSE()
:node(plist.unknown_value_edit_cell(item.pageName,1))
: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()
-- recipe
:IF(not(item.passiveActivity))
:node(plist.three_column_image_text(item.product,1,'File:' .. item.product .. '.png',item.product,item.product))
 
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|30px|link=' .. item.materials[i].name .. ']] [[' .. item.materials[i].name .. ']]<br>')
end
-- materials
row
:node(plist.three_column_image_text(item.material,1,'File:' .. item.material .. '.png',item.material,item.material))
 
:ELSE()
:tag('td')
:addClass('table-na')
:attr{ colspan = '21' }
:wikitext('N/A')
:done()
:END()
:node(plist.currency_cell(item.profit))
:node(plist.currency_cell(item.profitprofitPerHour))
:node(currency_cell(item.profitPerHour))
:tag('td')
Line 211 ⟶ 162:
:wikitext(item.discountLevel)
:done()
:node(plist.currency_cell(item.profitPerHourDiscount))
 
:IF(item.-- XP)
:IF(item.xp)
:tag('td')
:wikitext(item.XPxp and lang:formatNum(tonumber(item.XPxp)))
:done()
:ELSE()
:node(plist.unknown_value_edit_cell(item.allPageEdits,1))
:node(unknown_value_cell)
:END()
 
-- XP per hour
:IF(item.XPPerHour)
:IF(item.xpPerHour)
:tag('td')
:wikitext(item.XPPerHourxpPerHour and lang:formatNum(tonumber(item.XPPerHourxpPerHour)))
:done()
:ELSE()
:node(plist.unknown_value_cell(1))
:END()
 
:done()
end
21,691

edits