Module:Quest reward: Difference between revisions
Jump to navigation
Jump to search
>OmegaK2 m (OmegaK2 moved page Module:Quest rewards to Module:Quest reward without leaving a redirect: Consistency with other module names (singular)) |
m (25 revisions imported) |
||
(22 intermediate revisions by 5 users not shown) | |||
Line 3: | Line 3: | ||
-- | -- | ||
local m_game = require('Module:Game') | |||
local m_util = require('Module:Util') | local m_util = require('Module:Util') | ||
local f_item_link = require('Module:Item link').item_link | |||
local getArgs = require('Module:Arguments').getArgs | local getArgs = require('Module:Arguments').getArgs | ||
local m_cargo = require('Module:Cargo') | |||
local p = {} | local p = {} | ||
p._shared = {} | |||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
Line 15: | Line 19: | ||
errors = { | errors = { | ||
invalid_table = 'Invalid table selected. Valid choices are either quest or vendor', | invalid_table = 'Invalid table selected. Valid choices are either quest or vendor', | ||
invalid_type = 'type must be either quest_rewards or vendor_rewards', | |||
}, | }, | ||
messages = { | messages = { | ||
storage = ' | storage = 'Attempted to store rows %s to %s in "%s_rewards" table', | ||
}, | |||
quest_reward = { | |||
character_class = 'Class →', | |||
quest = 'Quest ↓', | |||
row_header = '[[%s]]<br>Act %s', | |||
item_level = 'iLvl %s', | |||
links = '%s-linked', | |||
}, | }, | ||
} | } | ||
Line 26: | Line 38: | ||
local tables = {} | local tables = {} | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
-- Helper functions and globals | -- Helper functions and globals | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
local h = {} | |||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
Line 106: | Line 49: | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
local p = {} | 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('<br>[[%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'] and row['quest_rewards.item_level'] ~= 0 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'] and row['quest_rewards.sockets'] ~= 0 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. | |||
p. | Examples | ||
-------- | |||
= p.quest_reward_table{type='vendor_rewards', q_where='quest="A Fixture of Fate"'} | |||
]] | |||
-- Get args | -- Get args | ||
tpl_args = getArgs(frame, { | local tpl_args = getArgs(frame, { | ||
parentFirst = true | parentFirst = true | ||
}) | }) | ||
frame = m_util.misc.get_frame(frame) | frame = m_util.misc.get_frame(frame) | ||
local q_where = tpl_args.q_where | |||
if | 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 | end | ||
local data | |||
if tpl_args.type == 'quest_rewards' then | |||
for | data = m_cargo.query( | ||
local | {'quest_rewards'}, | ||
if | { | ||
'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 | |||
-- | |||
local function element(rows) | |||
if rows == nil then | |||
return '' | |||
end | end | ||
local out = {} | |||
row | 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, '<br>') | |||
end | 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 | ||
Latest revision as of 06:01, 30 September 2024
Module for handling quest reward related data.
Subpages
The above documentation is transcluded from Module:Quest reward/doc.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
--
-- 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]]<br>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('<br>[[%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'] and row['quest_rewards.item_level'] ~= 0 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'] and row['quest_rewards.sockets'] ~= 0 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
local 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
--
local 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, '<br>')
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