Module:NPC Trades
Documentation for this module may be created at Module:NPC Trades/doc
local p = {}
local namespace = mw.title.getCurrentTitle().nsText
local sprite = require("Module:SpriteFile")
local tradeTable = require("Module:TradeTable")
local refUsed = false
local note_list = {} -- Track note names that have already been used, so we don't output them twice
function p.match_wanted(frame)
return p._main(frame:getParent().args, 'wanted_item')
end
function p.match_given(frame)
return p._main(frame:getParent().args, 'given_item')
end
function p.match_profession(frame)
return p._main(frame:getParent().args, 'profession', true)
end
local function makeTradeLine(data, hideProfession, professionRowspan, levelRowspan, hideXP, hideMulti)
local profession = data['profession']
local level = data['level']
local probability = data['probability']
local given_item = data['given_item']
local given_quant = data['given_quant']
local given_sprite = data['given_sprite']
local wanted_item = data['wanted_item']
local wanted_quant = data['wanted_quant']
local wanted_sprite = data['wanted_sprite']
local wanted_item_2 = data['wanted_item_2']
local wanted_quant_2 = data['wanted_quant_2']
local wanted_sprite_2 = data['wanted_sprite_2']
local given_note = data['given_note']
local given_note_text = data['given_note_text']
local wanted_note = data['wanted_note']
local wanted_note_text = data['wanted_note_text']
local price_multiplier = data['price_multiplier']
local max_trades = data['max_trades']
local villager_xp_gain = data['villager_xp_gain']
if not profession then
mw.log("Error empty profession")
mw.logObject(data)
return nil
end
local ret = mw.html.create('tr'):css('text-align', 'center')
local level_sort_key = 0
if level == 'Novice' then level_sort_key = 1 end
if level == 'Apprentice' then level_sort_key = 2 end
if level == 'Journeyman' then level_sort_key = 3 end
if level == 'Expert' then level_sort_key = 4 end
if level == 'Master' then level_sort_key = 5 end
if not hideProfession and professionRowspan > 0 then
ret:tag('td'):css('text-align', 'left')
:attr('rowspan', professionRowspan)
:wikitext(sprite.link({profession, name='EntitySprite'}))
end
if levelRowspan > 0 then
local level_cell = ret:tag(hideProfession and 'th' or 'td')
:css('text-align', hideProfession and 'center' or 'left')
:attr('rowspan', levelRowspan)
:attr('data-sort-value', level_sort_key)
level_cell:wikitext(level)
end
ret:tag('td'):wikitext(java_probability)
ret:tag('td'):wikitext(bedrock_probability)
local wanted = ret:tag('td')
wanted:wikitext(tradeTable.formatItemOutput(wanted_item, wanted_quant, wanted_item_2, wanted_quant_2, wanted_sprite, wanted_sprite_2))
if wanted_note_text then
refUsed = true -- Used to set references at footer
if wanted_note ~= nil and note_list[wanted_note] == nil then
note_list[wanted_note] = wanted_note_text
end
wanted:wikitext(mw.getCurrentFrame():extensionTag{ name='ref', content=wanted_note_text, args = {name=wanted_note, group='t'}})
end
local given = ret:tag('td'):wikitext(tradeTable.formatItemOutput(given_item, given_quant, nil, nil, given_sprite))
if given_note_text then
refUsed = true -- Used to set references at footer
if given_note ~= nil and note_list[given_note] == nil then
note_list[given_note] = given_note_text
end
given:wikitext(mw.getCurrentFrame():extensionTag{ name='ref', content=given_note_text, args = {name=given_note, group='t'}})
end
ret:tag('td'):wikitext(max_trades or '—')
if not hideXP then
ret:tag('td'):wikitext(villager_xp_gain or '—')
end
if not hideMulti then
ret:tag('td'):wikitext(price_multiplier or '—')
end
return ret:done()
end
function p._main(args, primary, hideProfession)
-- Get the trading data from bucket
local b = bucket('trade')
.select('json')
local hideXP = (args.hide_xp and true) or false
local hideMulti = (args.hide_multiplier and true) or false
local wheres = {}
if args.name then
table.insert(wheres, {primary, args.name})
elseif not args[1] then
table.insert(wheres, {primary, mw.title.getCurrentTitle().text})
else
for _,arg in ipairs(args) do
table.insert(wheres, {primary, arg})
end
end
b.where(bucket.Or(wheres))
local data = b.run()
for i,bucketRow in ipairs(data) do
data[i] = mw.text.jsonDecode(bucketRow.json or '{}')
end
-- Create the html table to display results
local tradeTable = mw.html.create('table'):addClass('wikitable sortable autosort=1,a'):css('text-align', 'center')
-- Generate the table header
header = tradeTable
:tag('tr')
:tag('th'):wikitext(hideProfession and 'Level' or 'Villager'):attr('rowspan', 2):attr('colspan', hideProfession and 1 or 2)
:tag('th'):wikitext('Probability'):attr('colspan', 2)
:tag('th'):wikitext('Villager wants'):attr('rowspan', 2)
:tag('th'):wikitext('Player receives'):attr('rowspan', 2)
:tag('th'):wikitext('Trades in<br>stock'):attr('rowspan', 2)
if not hideXP then
header:tag('th'):wikitext('Villager<br>experience'):attr('rowspan', 2)
end
if not hideMulti then
header:tag('th'):wikitext('Price<br>multiplier'):attr('rowspan', 2)
end
tradeTable
:tag('tr')
:tag('th'):wikitext("''[[JE]]''")
:tag('th'):wikitext("''[[BE]]''")
-- If there are no results, add an error category
if #data == 0 and namespace == '' then
tradeTable:node():wikitext('[[Category:Empty trade info]]')
end
-- Merge rows in the first two cells if appropriate:
-- Traverse the list in reverse to set the rowspans for each row
local rowspansProfession = {}
local rowspansLevel = {}
for i = 1,#data do
local j = #data + 1 - i
if j > 1 then
if data[j-1]['profession'] == data[j]['profession'] then
rowspansProfession[j-1] = (rowspansProfession[j] or 1) + 1
rowspansProfession[j] = 0
if data[j-1]['level'] == data[j]['level'] then
rowspansLevel[j-1] = (rowspansLevel[j] or 1) + 1
rowspansLevel[j] = 0
end
end
end
end
-- Generate all the table rows and insert them into the table
for i,tradeData in ipairs(data) do
local professionRowspan = hideProfession and 0 or rowspansProfession[i] or 1
local levelRowspan = rowspansLevel[i] or 1
local row = makeTradeLine(tradeData, hideProfession, professionRowspan, levelRowspan, hideXP, hideMulti)
tradeTable:node(row)
end
return mw.html.create():wikitext(tostring(tradeTable) .. mw.getCurrentFrame():extensionTag{name="references", args = {group='t'}})
end
return p