Module:Quest reward

-- -- Module for bestiary templates --

local m_game = require('Module:Game') local m_util = require('Module:Util') local f_item_link = require('Module:Item link').item_link local getArgs = require('Module:Arguments').getArgs local m_cargo = require('Module:Cargo')

local p = {} p._shared = {}

-- -- Strings --

local i18n = { errors = { invalid_table = 'Invalid table selected. Valid choices are either quest or vendor', invalid_type = 'type must be either quest_rewards or vendor_rewards', },   messages = { storage = 'Attempted to store rows %s to %s in "%s_rewards" table', },   quest_reward = { character_class = 'Class →', quest = 'Quest ↓', row_header = '%s Act %s', item_level = 'iLvl %s', links = '%s-linked', }, }

-- -- Cargo --

local tables = {}

-- -- Helper functions and globals --

local h = {}

-- -- Page functions --

function p._shared.reward_tbl_head local tbl = mw.html.create('table') tbl:attr('class', 'wikitable sortable') local tr = tbl:tag('tr') tr       :tag('th') :attr('class', 'unsortable') :wikitext(i18n.quest_reward.character_class) for _, class in ipairs(m_game.constants.characters_order) do       tr:tag('th') :attr('rowspan', 2) :wikitext(string.format('%s', m_game.constants.characters[class].name)) end

tbl :tag('tr') :tag('th') :wikitext(i18n.quest_reward.quest) return tbl end

function p._shared.reward_tbl_row_head(tr, rtbl, row) local npc = '' if row[rtbl .. '.npc'] then npc = string.format(' %s', row[rtbl .. '.npc']) end

tr       :tag('th') :wikitext(string.format(i18n.quest_reward.row_header, row[rtbl .. '.quest'], row[rtbl .. '.act'])) :wikitext(npc) end

function p._shared.reward_tbl_extra_info(row) local value = {} if row['quest_rewards.item_level'] then value[#value+1] = string.format(i18n.quest_reward.item_level, row['quest_rewards.item_level']) end -- TODO: i18n rarity name? if row['quest_rewards.rarity'] then value[#value+1] = m_util.html.poe_color(string.lower(row['quest_rewards.rarity']), row['quest_rewards.rarity']) end if row['quest_rewards.sockets'] then value[#value+1] = string.format(i18n.quest_reward.links, row['quest_rewards.sockets']) end

return table.concat(value, ', ') end

function p.quest_reward_table(frame) --[[   Displays a table of quest rewards from a certain quest.

Examples = p.quest_reward_table{type='vendor_rewards', q_where='quest="A Fixture of Fate"'} ]]

-- Get args tpl_args = getArgs(frame, {       parentFirst = true    }) frame = m_util.misc.get_frame(frame) local q_where = tpl_args.q_where if tpl_args.item_link then tpl_args.item_link = m_util.cast.boolean(tpl_args.item_link) else tpl_args.item_link = true end

local data if tpl_args.type == 'quest_rewards' then data = m_cargo.query(           {'quest_rewards'},            {                'quest_rewards.quest',                'quest_rewards.act',                'quest_rewards.classes',                'quest_rewards.sockets',                'quest_rewards.item_level',                'quest_rewards.rarity',                'quest_rewards._pageName',            },            {                where=q_where,                orderBy='quest_rewards.act ASC, quest_rewards.quest_id ASC, quest_rewards._pageName ASC',                limit=5000,            }        ) elseif tpl_args.type == 'vendor_rewards' then data = m_cargo.query(           {'vendor_rewards'},            {                'vendor_rewards.quest',                'vendor_rewards.act',                'vendor_rewards.classes',                'vendor_rewards.npc',                'vendor_rewards._pageName',            },            {                where=q_where,                orderBy='vendor_rewards.act ASC, vendor_rewards.quest_id ASC, vendor_rewards._pageName ASC',                limit=5000,            }        ) else error(i18n.errors.invalid_type, tpl_args.type) end

--    -- Build output table --    local tbl = p._shared.reward_tbl_head

if #data == 0 then return tostring(tbl) end

local quest_order = {} local quests = {} local pages = {}

--   -- remap data to quests[questid].classes[class] --   for _, row in ipairs(data) do        local classes = quests[row[tpl_args.type .. '.quest']] if classes == nil then table.insert(quest_order, row[tpl_args.type .. '.quest']) classes = {} quests[row[tpl_args.type .. '.quest']] = classes end

if row[tpl_args.type .. '.classes'] then classes[-1] = {} for _, class in ipairs(m_util.string.split(row[tpl_args.type .. '.classes'], ',')) do               if classes[class] == nil then classes[class] = {} end table.insert(classes[class], row) end else if classes[0] == nil then classes[0] = {} end table.insert(classes[0], row) end

pages[row[tpl_args.type .. '._pageName']] = true end --   -- Cache item data --   local item_data if tpl_args.item_link then local pages_array = {} for page, _ in pairs(pages) do           pages_array[#pages_array+1] = page end

local fields = { 'items.name', 'items.inventory_icon', }

if m_util.cast.boolean(tpl_args.no_html) ~= true then fields[#fields+1] = 'items.html' end

item_data = m_cargo.map_results_to_id{ results=m_cargo.array_query{ tables={'items'}, fields=fields, id_field='items._pageName', id_array=pages_array, query={ limit=5000, },           },            field='items._pageName', }   end --   -- Output rows --

function element(rows) if rows == nil then return '' end local out = {} for _, row in ipairs(rows) do           local reward = row[tpl_args.type .. '._pageName'] if tpl_args.item_link then local idata = item_data[reward][1] reward = f_item_link{page=reward, name=idata['items.name'], inventory_icon=idata['items.inventory_icon'] or , html=idata['items.html'] or , skip_query=true} else reward = string.format('%s', reward) end local info = p._shared.reward_tbl_extra_info(row) if info ~= '' then out[#out+1] = string.format('%s (%s)', reward, info) else out[#out+1] = reward end end return table.concat(out, ' ') end

for _, quest_key in ipairs(quest_order) do       local classes = quests[quest_key]

if classes[0] then local tr = tbl:tag('tr') for _, class in pairs(classes) do               if class[1] then p._shared.reward_tbl_row_head(tr, tpl_args.type, class[1]) break end end tr:tag('td') :attr('colspan', 7) :attr('style', 'text-align: center;') :wikitext(element(classes[0])) end if classes[-1] then local tr = tbl:tag('tr') for _, class in pairs(classes) do               if class[1] then p._shared.reward_tbl_row_head(tr, tpl_args.type, class[1]) break end end for _, class in ipairs(m_game.constants.characters_order) do                tr:tag('td') :wikitext(element(classes[m_game.constants.characters[class].name])) end end end

return tostring(tbl) end

-- -- End --

return p