Нет описания правки |
(Отмена правки 518514, сделанной Ruba159753 (обсуждение)) Метка: отмена |
||
Строка 1: | Строка 1: | ||
− | -- |
+ | -- ---------------------------------------------------------------------------- |
− | -- |
+ | -- Imports |
⚫ | |||
− | -- Module:Item acquisition |
||
⚫ | |||
− | -- This module implements Template:Item acquisition. |
||
⚫ | |||
− | require('Module:No globals') |
||
local getArgs = require('Module:Arguments').getArgs |
local getArgs = require('Module:Arguments').getArgs |
||
local m_util = require('Module:Util') |
local m_util = require('Module:Util') |
||
Строка 14: | Строка 10: | ||
local m_game = mw.loadData('Module:Game') |
local m_game = mw.loadData('Module:Game') |
||
⚫ | |||
− | -- Should we use the sandbox version of our submodules? |
||
+ | local f_message_box = require('Module:Message box').main |
||
− | local use_sandbox = m_util.misc.maybe_sandbox('Item acquisition') |
||
+ | -- ---------------------------------------------------------------------------- |
||
− | -- Lazy loading |
||
+ | -- Strings |
||
⚫ | |||
+ | -- ---------------------------------------------------------------------------- |
||
+ | -- This section contains strings used by this module. |
||
+ | -- Add new strings here instead of in-code directly, this will help other |
||
+ | -- people to correct spelling mistakes easier and help with translation to |
||
+ | -- other PoE wikis. |
||
⚫ | |||
+ | -- TODO: Maybe move this out to a separate sub-page module |
||
⚫ | |||
+ | acquisition = { |
||
+ | header = 'Получение предмета', |
||
+ | link = '[[File:Questionmark.png|right|24px|link=Path_of_Exile_Wiki:Как_редактировать_получение_предмета]]', |
||
⚫ | |||
+ | drop_leagues = 'После изменений [[Версия 3.14.0#Баланс уникальных предметов|версии 3.14.0]] неясно, какие именно [[Предметы с ограниченным доступом#Предметы, относящиеся к конкретной лиге|предметы, относящиеся к конкретной лиге]], были добавлены в основной список выпадающих предметов. Если этот предмет не существует в основном списке выпадающих предметов, он может выпадать только в областях с активным флагом лиги %s. Предметы, относящиеся к конкретной лиге, также могут быть приобретены [[Предметы с ограниченным доступом#Предметы, относящиеся к конкретной лиге|другими способами]].', |
||
+ | drop_disabled = 'Этот предмет не выпадает.', |
||
+ | area_header = 'Ограничения на получение в областях', |
||
+ | area_legacy_header = 'Ограничения на получение в устаревших областях', |
||
+ | area = 'Этот предмет можно получить в следующих областях:', |
||
+ | monster = 'Этот предмет может выпасть из следующих монстров:', |
||
+ | monster_header = 'Ограничения на получение из монстров', |
||
⚫ | |||
+ | upgraded_from_header = 'Способы получения', |
||
+ | upgraded_from = 'Этот предмет можно получить следующими способами:', |
||
⚫ | |||
+ | ingredient_header = 'Используется для получения', |
||
+ | ingredient = 'Этот предмет используется для получения следующих предметов:', |
||
⚫ | |||
⚫ | |||
+ | upgraded_from_table = { |
||
+ | outcome = 'Результат', |
||
+ | ingredient = 'Ингредиент', |
||
+ | ingredient_amount = 'Кол-во', |
||
+ | ingredient_notes = 'Примечания<br>по ингредиентам', |
||
+ | recipe_notes = 'Общие примечания', |
||
⚫ | |||
+ | automatic = m_util.html.abbr('Автоматически', 'Автоматически добавлено шаблоном на основе характеристик предмета.'), |
||
+ | manual = m_util.html.abbr('Вручную', 'Вручную добавлено на вики-страницу предмета.'), |
||
+ | old_data = m_util.html.abbr('Устаревшие данные', 'Устаревшие данные - пожалуйста, сделайте пустое редактирование вики-страницы предмета.'), |
||
⚫ | |||
⚫ | |||
+ | quest_reward = { |
||
+ | quest_rewards_header = 'Награда за задание', |
||
+ | quest_rewards_intro = 'Дается в качестве награды за следующие задания:', |
||
+ | vendor_rewards_header = 'Награда торговца', |
||
+ | vendor_rewards_intro = 'Можно приобрести у перечисленных торговцев после выполнения следующих заданий:', |
||
⚫ | |||
+ | } |
||
+ | -- ---------------------------------------------------------------------------- |
||
− | -- The cfg table contains all localisable strings and configuration, to make it |
||
+ | -- Globals |
||
− | -- easier to port this module to another wiki. |
||
+ | -- ---------------------------------------------------------------------------- |
||
− | local cfg = use_sandbox and mw.loadData('Module:Item acquisition/config/sandbox') or mw.loadData('Module:Item acquisition/config') |
||
− | local |
+ | local c = {} |
+ | |||
+ | c.MAX_ITEMS = 100 |
||
+ | c.COLLAPSE_TABLE = 30 |
||
-- ---------------------------------------------------------------------------- |
-- ---------------------------------------------------------------------------- |
||
Строка 31: | Строка 76: | ||
local h = {} |
local h = {} |
||
− | |||
− | -- Lazy loading for Module:Item link |
||
− | function h.item_link(args) |
||
− | if not f_item_link then |
||
− | f_item_link = require('Module:Item link').item_link |
||
⚫ | |||
− | return f_item_link(args) |
||
− | end |
||
− | |||
function h.head(str, level) |
function h.head(str, level) |
||
local head = mw.html.create('h' .. (level or 3)) |
local head = mw.html.create('h' .. (level or 3)) |
||
Строка 46: | Строка 82: | ||
end |
end |
||
− | function h. |
+ | function h.fetch_upgraded_from_sets(where_set, where_group) |
if where_set == "" or where_group == "" then |
if where_set == "" or where_group == "" then |
||
return {}, {} |
return {}, {} |
||
Строка 53: | Строка 89: | ||
local sets = {} |
local sets = {} |
||
local results = m_cargo.query( |
local results = m_cargo.query( |
||
− | {' |
+ | {'upgraded_from_sets'}, |
{ |
{ |
||
− | ' |
+ | 'upgraded_from_sets._pageName', |
− | ' |
+ | 'upgraded_from_sets.set_id', |
− | ' |
+ | 'upgraded_from_sets.text', |
− | ' |
+ | 'upgraded_from_sets.automatic', |
− | 'acquisition_recipes.automatic', |
||
}, |
}, |
||
{ |
{ |
||
Строка 68: | Строка 103: | ||
for _, row in ipairs(results) do |
for _, row in ipairs(results) do |
||
row.groups = {} |
row.groups = {} |
||
− | sets[row[' |
+ | sets[row['upgraded_from_sets._pageName'] .. tonumber(row['upgraded_from_sets.set_id'])] = row |
end |
end |
||
results = m_cargo.query( |
results = m_cargo.query( |
||
− | {' |
+ | {'upgraded_from_groups'}, |
{ |
{ |
||
− | ' |
+ | 'upgraded_from_groups._pageName', |
− | ' |
+ | 'upgraded_from_groups.set_id', |
− | ' |
+ | 'upgraded_from_groups.group_id', |
− | ' |
+ | 'upgraded_from_groups.notes', |
− | ' |
+ | 'upgraded_from_groups.amount', |
− | ' |
+ | 'upgraded_from_groups.item_name', |
− | ' |
+ | 'upgraded_from_groups.item_page', |
}, |
}, |
||
{ |
{ |
||
Строка 88: | Строка 123: | ||
for _, row in ipairs(results) do |
for _, row in ipairs(results) do |
||
− | sets[row[' |
+ | sets[row['upgraded_from_groups._pageName'] .. tonumber(row['upgraded_from_groups.set_id'])].groups[tonumber(row['upgraded_from_groups.group_id'])] = row |
end |
end |
||
Строка 97: | Строка 132: | ||
table.sort(sets_sort, function (a, b) |
table.sort(sets_sort, function (a, b) |
||
− | return tonumber(sets[a][' |
+ | return tonumber(sets[a]['upgraded_from_sets.set_id']) < tonumber(sets[b]['upgraded_from_sets.set_id']) |
end) |
end) |
||
Строка 103: | Строка 138: | ||
end |
end |
||
− | function h. |
+ | function h.upgraded_from_table(tpl_args, sets, set_order, data_type, out, item_pages) |
-- Count the number of item pages: |
-- Count the number of item pages: |
||
Строка 124: | Строка 159: | ||
end |
end |
||
local set = sets[set_key] |
local set = sets[set_key] |
||
− | if set[' |
+ | if set['upgraded_from_sets.text'] ~= nil then |
set_notes = true |
set_notes = true |
||
end |
end |
||
Строка 130: | Строка 165: | ||
if #set.groups > 0 then |
if #set.groups > 0 then |
||
for i, group in ipairs(set.groups) do |
for i, group in ipairs(set.groups) do |
||
− | if group[' |
+ | if group['upgraded_from_groups.notes'] ~= nil then |
group_notes = true |
group_notes = true |
||
break |
break |
||
Строка 142: | Строка 177: | ||
-- sorting will mess up the table because of the rowspawns |
-- sorting will mess up the table because of the rowspawns |
||
local table_class = 'wikitable mw-collapsible mw-expanded' |
local table_class = 'wikitable mw-collapsible mw-expanded' |
||
− | if item_pages_count > |
+ | if item_pages_count > c.COLLAPSE_TABLE then |
table_class = 'wikitable mw-collapsible mw-collapsed' |
table_class = 'wikitable mw-collapsible mw-collapsed' |
||
end |
end |
||
Строка 154: | Строка 189: | ||
tr |
tr |
||
:tag('th') |
:tag('th') |
||
− | :wikitext(i18n. |
+ | :wikitext(i18n.upgraded_from_table.outcome) |
end |
end |
||
tr |
tr |
||
:tag('th') |
:tag('th') |
||
− | :wikitext(i18n. |
+ | :wikitext(i18n.upgraded_from_table.ingredient_amount) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext(i18n. |
+ | :wikitext(i18n.upgraded_from_table.ingredient) |
:done() |
:done() |
||
if group_notes then |
if group_notes then |
||
tr |
tr |
||
:tag('th') |
:tag('th') |
||
− | :wikitext(i18n. |
+ | :wikitext(i18n.upgraded_from_table.ingredient_notes) |
:done() |
:done() |
||
end |
end |
||
Строка 173: | Строка 208: | ||
tr |
tr |
||
:tag('th') |
:tag('th') |
||
− | :wikitext(i18n. |
+ | :wikitext(i18n.upgraded_from_table.recipe_notes) |
:done() |
:done() |
||
end |
end |
||
tr |
tr |
||
:tag('th') |
:tag('th') |
||
− | :wikitext(i18n. |
+ | :wikitext(i18n.upgraded_from_table.type) |
:done() |
:done() |
||
-- |
-- |
||
Строка 193: | Строка 228: | ||
if data_type == 'ingredient' then |
if data_type == 'ingredient' then |
||
local str |
local str |
||
− | if tpl_args.no_link == nil and item_pages_count < |
+ | if tpl_args.no_link == nil and item_pages_count < c.MAX_ITEMS then |
− | local item_data = item_pages[set[' |
+ | local item_data = item_pages[set['upgraded_from_sets._pageName']][1] |
− | str = |
+ | str = f_item_link{page=set['upgraded_from_sets._pageName'], name=item_data['items.name'], inventory_icon=item_data['items.inventory_icon'] or '', html=item_data['items.html'] or '', skip_query=true} |
else |
else |
||
− | str = string.format('[[%s]]', set[' |
+ | str = string.format('[[%s]]', set['upgraded_from_sets._pageName']) |
end |
end |
||
Строка 215: | Строка 250: | ||
end |
end |
||
local str |
local str |
||
− | if tpl_args.no_link == nil and item_pages_count < |
+ | if tpl_args.no_link == nil and item_pages_count < c.MAX_ITEMS then |
− | local item_data = item_pages[group[' |
+ | local item_data = item_pages[group['upgraded_from_groups.item_page']][1] |
− | str = |
+ | str = f_item_link{ |
− | page=group[' |
+ | page=group['upgraded_from_groups.item_page'], |
name=item_data['items.name'], |
name=item_data['items.name'], |
||
inventory_icon=item_data['items.inventory_icon'] or '', |
inventory_icon=item_data['items.inventory_icon'] or '', |
||
Строка 225: | Строка 260: | ||
} |
} |
||
else |
else |
||
− | str = string.format('[[%s]]', group[' |
+ | str = string.format('[[%s]]', group['upgraded_from_groups.item_page']) |
end |
end |
||
Строка 231: | Строка 266: | ||
:tag('td') |
:tag('td') |
||
:attr('data-sort-type', 'number') |
:attr('data-sort-type', 'number') |
||
− | :wikitext(group[' |
+ | :wikitext(group['upgraded_from_groups.amount']) |
:done() |
:done() |
||
:tag('td') |
:tag('td') |
||
Строка 238: | Строка 273: | ||
if group_notes then |
if group_notes then |
||
− | if group[' |
+ | if group['upgraded_from_groups.notes'] then |
tr2 |
tr2 |
||
:tag('td') |
:tag('td') |
||
− | :wikitext(group[' |
+ | :wikitext(group['upgraded_from_groups.notes']) |
else |
else |
||
tr2:node(m_util.html.td.na{as_tag=true}) |
tr2:node(m_util.html.td.na{as_tag=true}) |
||
Строка 249: | Строка 284: | ||
if set_notes then |
if set_notes then |
||
− | if set[' |
+ | if set['upgraded_from_sets.text'] then |
tr |
tr |
||
:tag('td') |
:tag('td') |
||
:attr('rowspan', #set.groups) |
:attr('rowspan', #set.groups) |
||
− | :wikitext(set[' |
+ | :wikitext(set['upgraded_from_sets.text']) |
else |
else |
||
tr |
tr |
||
Строка 265: | Строка 300: | ||
local t |
local t |
||
− | if set[' |
+ | if set['upgraded_from_sets.automatic'] == nil then |
− | t = i18n. |
+ | t = i18n.upgraded_from_table.old_data |
− | elseif set[' |
+ | elseif set['upgraded_from_sets.automatic'] == '1' then |
− | t = i18n. |
+ | t = i18n.upgraded_from_table.automatic |
else |
else |
||
− | t = i18n. |
+ | t = i18n.upgraded_from_table.manual |
end |
end |
||
Строка 286: | Строка 321: | ||
if data_type == 'ingredient' then |
if data_type == 'ingredient' then |
||
− | out[#out+1] = h.head(i18n.acquisition. |
+ | out[#out+1] = h.head(i18n.acquisition.ingredient_header) |
− | out[#out+1] = |
+ | out[#out+1] = i18n.acquisition.ingredient |
else |
else |
||
− | out[#out+1] = h.head(i18n.acquisition. |
+ | out[#out+1] = h.head(i18n.acquisition.upgraded_from_header) |
− | out[#out+1] = |
+ | out[#out+1] = i18n.acquisition.upgraded_from |
end |
end |
||
out[#out+1] = '<br>' |
out[#out+1] = '<br>' |
||
Строка 366: | Строка 401: | ||
-- ---------------------------------------------------------------------------- |
-- ---------------------------------------------------------------------------- |
||
+ | -- Templates |
||
− | -- Exported functions |
||
-- ---------------------------------------------------------------------------- |
-- ---------------------------------------------------------------------------- |
||
Строка 383: | Строка 418: | ||
= p.item_acquisition{page='The Rite of Elements'} |
= p.item_acquisition{page='The Rite of Elements'} |
||
]] |
]] |
||
+ | |||
-- Get args |
-- Get args |
||
Строка 389: | Строка 425: | ||
}) |
}) |
||
frame = m_util.misc.get_frame(frame) |
frame = m_util.misc.get_frame(frame) |
||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
local out = {} |
local out = {} |
||
⚫ | |||
⚫ | |||
⚫ | |||
out[#out+1] = tpl_args.acquisition_insert |
out[#out+1] = tpl_args.acquisition_insert |
||
-- fetch general item drop information that is used in multiple places in a |
-- fetch general item drop information that is used in multiple places in a |
||
-- single query to reduce performance hit |
-- single query to reduce performance hit |
||
− | local |
+ | local item_data = m_cargo.query( |
− | + | {'items'}, |
|
− | + | { |
|
− | 'items. |
+ | 'items.drop_text', |
− | 'items. |
+ | 'items.drop_leagues', |
− | 'items. |
+ | 'items.drop_areas__full', |
− | 'items. |
+ | 'items.drop_monsters', |
− | 'items. |
+ | 'items.drop_enabled', |
− | + | }, |
|
− | + | { |
|
− | 'items. |
+ | where=string.format('items._pageName="%s"', tpl_args.page), |
⚫ | |||
⚫ | |||
− | + | } |
|
− | + | ) |
|
⚫ | |||
− | if tpl_args.page then |
||
− | -- Join with _pageData in order to check for page redirect |
||
⚫ | |||
− | fields[#fields+1] = '_pageData._pageNameOrRedirect' |
||
− | query.where = string.format( |
||
− | '_pageData._pageName="%s"', |
||
⚫ | |||
⚫ | |||
− | query.join = 'items._pageName = _pageData._pageNameOrRedirect' |
||
⚫ | |||
− | query.where = string.format( |
||
− | 'items._pageName="%s"', |
||
⚫ | |||
⚫ | |||
⚫ | |||
− | local item_data = m_cargo.query(tables, fields, query) |
||
if #item_data > 0 then |
if #item_data > 0 then |
||
item_data = item_data[1] |
item_data = item_data[1] |
||
Строка 431: | Строка 455: | ||
-- ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------ |
||
− | -- |
+ | -- Drop disabled item |
-- ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------ |
||
local drop_enabled = m_util.cast.boolean(item_data['items.drop_enabled']) |
local drop_enabled = m_util.cast.boolean(item_data['items.drop_enabled']) |
||
− | local drop_restricted = m_util.cast.boolean(item_data['items.is_drop_restricted']) |
||
− | local is_unique = item_data['items.rarity_id'] == 'unique' |
||
if not drop_enabled then |
if not drop_enabled then |
||
− | out[#out+1] = |
+ | out[#out+1] = i18n.acquisition.drop_disabled |
⚫ | |||
− | elseif drop_restricted then |
||
+ | end |
||
− | out[#out+1] = string.format(i18n.acquisition.drop_restricted, item_data['items.name']) |
||
− | if is_unique then |
||
⚫ | |||
− | out[#out+1] = i18n.acquisition.cannot_be_chanced |
||
⚫ | |||
⚫ | |||
⚫ | |||
− | out[#out+1] = string.format(i18n.acquisition.drop_anywhere, item_data['items.name']) |
||
⚫ | |||
− | if is_unique then |
||
⚫ | |||
− | out[#out+1] = i18n.acquisition.can_be_chanced |
||
− | end |
||
⚫ | |||
-- ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------ |
||
− | -- |
+ | -- Drop restrictions by league |
-- ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------ |
||
⚫ | |||
− | local acquisition_tags |
||
− | + | local text = string.format(i18n.acquisition.drop_leagues, item_data['items.drop_leagues']) |
|
+ | local mbox = f_message_box('ambox', { |
||
− | acquisition_tags = m_util.string.split(item_data['items.acquisition_tags'], ',') |
||
+ | type = 'notice', |
||
⚫ | |||
− | + | text = tostring(text), |
|
− | + | }) |
|
⚫ | |||
− | if m_util.table.contains(acquisition_tags, 'league-specific') and drop_enabled and is_unique then |
||
⚫ | |||
out[#out+1] = '\n\n' |
out[#out+1] = '\n\n' |
||
− | out[#out+1] = string.format(i18n.acquisition.league_specific_unique, item_data['items.name']) |
||
end |
end |
||
Строка 472: | Строка 481: | ||
-- ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------ |
||
if item_data['items.drop_text'] and drop_enabled then |
if item_data['items.drop_text'] and drop_enabled then |
||
⚫ | |||
out[#out+1] = item_data['items.drop_text'] |
out[#out+1] = item_data['items.drop_text'] |
||
end |
end |
||
Строка 546: | Строка 554: | ||
ul:tag('li') |
ul:tag('li') |
||
:wikitext(string.format('[[%s|%s]]', row['areas.main_page'] or row['areas._pageName'], row['areas.name'])) |
:wikitext(string.format('[[%s|%s]]', row['areas.main_page'] or row['areas._pageName'], row['areas.name'])) |
||
− | end |
+ | end |
out[#out+1] = h.head(query_set.header) |
out[#out+1] = h.head(query_set.header) |
||
out[#out+1] = i18n.acquisition.area |
out[#out+1] = i18n.acquisition.area |
||
Строка 592: | Строка 600: | ||
row['monsters.name'] |
row['monsters.name'] |
||
)) |
)) |
||
− | end |
+ | end |
out[#out+1] = h.head(i18n.acquisition.monster_header) |
out[#out+1] = h.head(i18n.acquisition.monster_header) |
||
out[#out+1] = i18n.acquisition.monster |
out[#out+1] = i18n.acquisition.monster |
||
Строка 601: | Строка 609: | ||
-- ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------ |
||
+ | -- Vendor recipes/upgrades handling |
||
− | -- Recipes section |
||
-- ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------ |
||
-- |
-- |
||
− | -- Query |
+ | -- Query set data |
-- |
-- |
||
− | local obtained_sets, obtained_sets_order = h. |
+ | local obtained_sets, obtained_sets_order = h.fetch_upgraded_from_sets( |
− | string.format(' |
+ | string.format('upgraded_from_sets._pageName="%s"', tpl_args.page), |
− | string.format(' |
+ | string.format('upgraded_from_groups._pageName="%s"', tpl_args.page) |
) |
) |
||
+ | results = m_cargo.query( |
||
− | -- Find recipes that item is used in |
||
+ | {'upgraded_from_groups'}, |
||
⚫ | |||
− | {'acquisition_recipe_parts'}, |
||
{ |
{ |
||
− | '_pageID', |
+ | 'upgraded_from_groups._pageID', |
− | ' |
+ | 'upgraded_from_groups.set_id', |
}, |
}, |
||
{ |
{ |
||
− | where |
+ | where=string.format('upgraded_from_groups.item_page="%s"', tpl_args.page), |
− | + | -- only need one result set for the where clause |
|
+ | groupBy='upgraded_from_groups._pageID, upgraded_from_groups.set_id', |
||
} |
} |
||
) |
) |
||
+ | local where = {sets={}, groups={}} |
||
− | |||
⚫ | |||
⚫ | |||
+ | for _, row in ipairs(results) do |
||
⚫ | |||
+ | data[#data+1] = string.format('upgraded_from_%s.set_id="%s" AND upgraded_from_%s._pageID="%s"', key, row['upgraded_from_groups.set_id'], key, row['upgraded_from_groups._pageID']) |
||
⚫ | |||
⚫ | |||
− | recipes[#recipes+1] = string.format('acquisition_recipes.recipe_id="%s" AND acquisition_recipes._pageID="%s"', row.recipe_id, row._pageID) |
||
⚫ | |||
− | parts[#parts+1] = string.format('acquisition_recipe_parts.recipe_id="%s" AND acquisition_recipe_parts._pageID="%s"', row.recipe_id, row._pageID) |
||
end |
end |
||
⚫ | |||
⚫ | |||
− | recipes = table.concat(recipes, ' OR ') |
||
− | |||
⚫ | |||
-- |
-- |
||
-- Query bulk item info for item linking |
-- Query bulk item info for item linking |
||
Строка 643: | Строка 648: | ||
local set = set_data[1][set_key] |
local set = set_data[1][set_key] |
||
for _, group in ipairs(set.groups) do |
for _, group in ipairs(set.groups) do |
||
− | item_pages.assoc[group[' |
+ | item_pages.assoc[group['upgraded_from_groups.item_page']] = true |
end |
end |
||
− | item_pages.assoc[set[' |
+ | item_pages.assoc[set['upgraded_from_sets._pageName']] = true |
end |
end |
||
end |
end |
||
Строка 653: | Строка 658: | ||
end |
end |
||
− | if #item_pages < |
+ | if #item_pages < c.MAX_ITEMS then |
item_pages = m_cargo.map_results_to_id{ |
item_pages = m_cargo.map_results_to_id{ |
||
results=m_cargo.array_query{ |
results=m_cargo.array_query{ |
||
Строка 673: | Строка 678: | ||
-- |
-- |
||
− | h. |
+ | h.upgraded_from_table(tpl_args, obtained_sets, obtained_sets_order, 'obtained', out, item_pages) |
-- |
-- |
||
Строка 679: | Строка 684: | ||
-- |
-- |
||
− | h. |
+ | h.upgraded_from_table(tpl_args, ingredient_sets, ingredient_sets_order, 'ingredient', out, item_pages) |
out[#out+1] = tpl_args.ingredient_append |
out[#out+1] = tpl_args.ingredient_append |
||
Строка 698: | Строка 703: | ||
}, |
}, |
||
{ |
{ |
||
− | where=string.format('quest_rewards._pageName="%s"', |
+ | where=string.format('quest_rewards._pageName="%s"', tpl_args.page), |
orderBy='quest_rewards.act ASC, quest_rewards.quest_id ASC', |
orderBy='quest_rewards.act ASC, quest_rewards.quest_id ASC', |
||
} |
} |
||
Строка 713: | Строка 718: | ||
}, |
}, |
||
{ |
{ |
||
− | where=string.format('vendor_rewards._pageName="%s"', |
+ | where=string.format('vendor_rewards._pageName="%s"', tpl_args.page), |
orderBy='vendor_rewards.act ASC, vendor_rewards.quest_id ASC', |
orderBy='vendor_rewards.act ASC, vendor_rewards.quest_id ASC', |
||
} |
} |
||
Строка 727: | Строка 732: | ||
return tostring(head) .. table.concat(out) |
return tostring(head) .. table.concat(out) |
||
end |
end |
||
+ | |||
+ | -- ---------------------------------------------------------------------------- |
||
+ | -- Return |
||
+ | -- ---------------------------------------------------------------------------- |
||
return p |
return p |
Версия от 15:44, 20 октября 2021
Этот модуль используется на очень большом количестве страниц. Чтобы избежать крупномасштабных сбоев и ненужной нагрузки на сервер, любые изменения в этом модуле должны быть сначала протестированы на его подстраницах /песочница или /testcases. Протестированные изменения могут быть добавлены на эту страницу за одну правку. Пожалуйста, обсудите любые изменения на странице обсуждения перед их внедрением. |
Этот модуль зависит от следующих других модулей: |
Предоставляет функциональные возможности для отображения получения предмета.
Описание
Шаблоны Item
Модуль:Item2
Все шаблоны, определенные в Модуль:Item2:
Модуль:Item table
Все шаблоны, определенные в Модуль:Item table:
- {{Item table}}
- {{Query base items}}
- {{Query unique items}}
- {{Item unique versions}}
- {{Area item drops}}
- {{Item table/skill gems}}
- {{Map item drops}}
- {{Prophecy description}}
- {{Simple item list}}
Модуль:Item link
Все шаблоны, определенные в Модуль:Item link:
- {{Item link}}
- {{Il}}
- {{Item icon link}}
Модуль:Item acquisition
Вышеприведенная документация извлекается из Модуль:Item acquisition/doc.
Редакторы могут экспериментировать в sandbox этого модуля и в testcases страницах.
Подстраницы этого модуля.
Редакторы могут экспериментировать в sandbox этого модуля и в testcases страницах.
Подстраницы этого модуля.
-- ----------------------------------------------------------------------------
-- Imports
-- ----------------------------------------------------------------------------
local getArgs = require('Module:Arguments').getArgs
local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')
local m_quest_reward = require('Module:Quest reward')._shared
local m_game = mw.loadData('Module:Game')
local f_item_link = require('Module:Item link').item_link
local f_message_box = require('Module:Message box').main
-- ----------------------------------------------------------------------------
-- Strings
-- ----------------------------------------------------------------------------
-- This section contains strings used by this module.
-- Add new strings here instead of in-code directly, this will help other
-- people to correct spelling mistakes easier and help with translation to
-- other PoE wikis.
--
-- TODO: Maybe move this out to a separate sub-page module
local i18n = {
acquisition = {
header = 'Получение предмета',
link = '[[File:Questionmark.png|right|24px|link=Path_of_Exile_Wiki:Как_редактировать_получение_предмета]]',
drop_leagues = 'После изменений [[Версия 3.14.0#Баланс уникальных предметов|версии 3.14.0]] неясно, какие именно [[Предметы с ограниченным доступом#Предметы, относящиеся к конкретной лиге|предметы, относящиеся к конкретной лиге]], были добавлены в основной список выпадающих предметов. Если этот предмет не существует в основном списке выпадающих предметов, он может выпадать только в областях с активным флагом лиги %s. Предметы, относящиеся к конкретной лиге, также могут быть приобретены [[Предметы с ограниченным доступом#Предметы, относящиеся к конкретной лиге|другими способами]].',
drop_disabled = 'Этот предмет не выпадает.',
area_header = 'Ограничения на получение в областях',
area_legacy_header = 'Ограничения на получение в устаревших областях',
area = 'Этот предмет можно получить в следующих областях:',
monster = 'Этот предмет может выпасть из следующих монстров:',
monster_header = 'Ограничения на получение из монстров',
upgraded_from_header = 'Способы получения',
upgraded_from = 'Этот предмет можно получить следующими способами:',
ingredient_header = 'Используется для получения',
ingredient = 'Этот предмет используется для получения следующих предметов:',
},
upgraded_from_table = {
outcome = 'Результат',
ingredient = 'Ингредиент',
ingredient_amount = 'Кол-во',
ingredient_notes = 'Примечания<br>по ингредиентам',
recipe_notes = 'Общие примечания',
type = 'Тип',
automatic = m_util.html.abbr('Автоматически', 'Автоматически добавлено шаблоном на основе характеристик предмета.'),
manual = m_util.html.abbr('Вручную', 'Вручную добавлено на вики-страницу предмета.'),
old_data = m_util.html.abbr('Устаревшие данные', 'Устаревшие данные - пожалуйста, сделайте пустое редактирование вики-страницы предмета.'),
},
quest_reward = {
quest_rewards_header = 'Награда за задание',
quest_rewards_intro = 'Дается в качестве награды за следующие задания:',
vendor_rewards_header = 'Награда торговца',
vendor_rewards_intro = 'Можно приобрести у перечисленных торговцев после выполнения следующих заданий:',
},
}
-- ----------------------------------------------------------------------------
-- Globals
-- ----------------------------------------------------------------------------
local c = {}
c.MAX_ITEMS = 100
c.COLLAPSE_TABLE = 30
-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------
local h = {}
function h.head(str, level)
local head = mw.html.create('h' .. (level or 3))
head:wikitext(str)
return tostring(head)
end
function h.fetch_upgraded_from_sets(where_set, where_group)
if where_set == "" or where_group == "" then
return {}, {}
end
local sets = {}
local results = m_cargo.query(
{'upgraded_from_sets'},
{
'upgraded_from_sets._pageName',
'upgraded_from_sets.set_id',
'upgraded_from_sets.text',
'upgraded_from_sets.automatic',
},
{
where=where_set,
}
)
for _, row in ipairs(results) do
row.groups = {}
sets[row['upgraded_from_sets._pageName'] .. tonumber(row['upgraded_from_sets.set_id'])] = row
end
results = m_cargo.query(
{'upgraded_from_groups'},
{
'upgraded_from_groups._pageName',
'upgraded_from_groups.set_id',
'upgraded_from_groups.group_id',
'upgraded_from_groups.notes',
'upgraded_from_groups.amount',
'upgraded_from_groups.item_name',
'upgraded_from_groups.item_page',
},
{
where=where_group,
}
)
for _, row in ipairs(results) do
sets[row['upgraded_from_groups._pageName'] .. tonumber(row['upgraded_from_groups.set_id'])].groups[tonumber(row['upgraded_from_groups.group_id'])] = row
end
local sets_sort = {}
for key, _ in pairs(sets) do
sets_sort[#sets_sort+1] = key
end
table.sort(sets_sort, function (a, b)
return tonumber(sets[a]['upgraded_from_sets.set_id']) < tonumber(sets[b]['upgraded_from_sets.set_id'])
end)
return sets, sets_sort
end
function h.upgraded_from_table(tpl_args, sets, set_order, data_type, out, item_pages)
-- Count the number of item pages:
local item_pages_count = 0
for _,__ in pairs(item_pages) do
item_pages_count = item_pages_count + 1
end
-- Avoid creating headers only when no data is given
if #set_order <= 0 then
return
end
-- Prevent showing either group or set notes when no rows have any to save a bit of vertical space
local set_notes = false
local group_notes = false
for _, set_key in ipairs(set_order) do
if set_notes and group_notes then
break
end
local set = sets[set_key]
if set['upgraded_from_sets.text'] ~= nil then
set_notes = true
end
if #set.groups > 0 then
for i, group in ipairs(set.groups) do
if group['upgraded_from_groups.notes'] ~= nil then
group_notes = true
break
end
end
end
end
local tbl = mw.html.create('table')
-- sorting will mess up the table because of the rowspawns
local table_class = 'wikitable mw-collapsible mw-expanded'
if item_pages_count > c.COLLAPSE_TABLE then
table_class = 'wikitable mw-collapsible mw-collapsed'
end
tbl:attr('class', table_class)
--
-- Header
--
local tr = tbl:tag('tr')
if data_type == 'ingredient' then
tr
:tag('th')
:wikitext(i18n.upgraded_from_table.outcome)
end
tr
:tag('th')
:wikitext(i18n.upgraded_from_table.ingredient_amount)
:done()
:tag('th')
:wikitext(i18n.upgraded_from_table.ingredient)
:done()
if group_notes then
tr
:tag('th')
:wikitext(i18n.upgraded_from_table.ingredient_notes)
:done()
end
if set_notes then
tr
:tag('th')
:wikitext(i18n.upgraded_from_table.recipe_notes)
:done()
end
tr
:tag('th')
:wikitext(i18n.upgraded_from_table.type)
:done()
--
-- Rows
--
for _, set_key in ipairs(set_order) do
local set = sets[set_key]
if #set.groups > 0 then
tr = tbl:tag('tr')
tr:attr('class', 'upgraded-from-set')
if data_type == 'ingredient' then
local str
if tpl_args.no_link == nil and item_pages_count < c.MAX_ITEMS then
local item_data = item_pages[set['upgraded_from_sets._pageName']][1]
str = f_item_link{page=set['upgraded_from_sets._pageName'], name=item_data['items.name'], inventory_icon=item_data['items.inventory_icon'] or '', html=item_data['items.html'] or '', skip_query=true}
else
str = string.format('[[%s]]', set['upgraded_from_sets._pageName'])
end
tr
:tag('td')
:attr('rowspan', #set.groups)
:wikitext(str)
:done()
end
local tr2
for i, group in ipairs(set.groups) do
if i <= 1 then
tr2 = tr
else
tr2 = tbl:tag('tr')
end
local str
if tpl_args.no_link == nil and item_pages_count < c.MAX_ITEMS then
local item_data = item_pages[group['upgraded_from_groups.item_page']][1]
str = f_item_link{
page=group['upgraded_from_groups.item_page'],
name=item_data['items.name'],
inventory_icon=item_data['items.inventory_icon'] or '',
html=item_data['items.html'] or '',
skip_query=true
}
else
str = string.format('[[%s]]', group['upgraded_from_groups.item_page'])
end
tr2
:tag('td')
:attr('data-sort-type', 'number')
:wikitext(group['upgraded_from_groups.amount'])
:done()
:tag('td')
:wikitext(str)
:done()
if group_notes then
if group['upgraded_from_groups.notes'] then
tr2
:tag('td')
:wikitext(group['upgraded_from_groups.notes'])
else
tr2:node(m_util.html.td.na{as_tag=true})
end
end
end
if set_notes then
if set['upgraded_from_sets.text'] then
tr
:tag('td')
:attr('rowspan', #set.groups)
:wikitext(set['upgraded_from_sets.text'])
else
tr
:tag('td')
:attr('class', 'table-na')
:attr('rowspan', #set.groups)
:wikitext('N/A')
:done()
end
end
local t
if set['upgraded_from_sets.automatic'] == nil then
t = i18n.upgraded_from_table.old_data
elseif set['upgraded_from_sets.automatic'] == '1' then
t = i18n.upgraded_from_table.automatic
else
t = i18n.upgraded_from_table.manual
end
tr
:tag('td')
:attr('rowspan', #set.groups)
:wikitext(t)
end
end
--
-- print
--
if data_type == 'ingredient' then
out[#out+1] = h.head(i18n.acquisition.ingredient_header)
out[#out+1] = i18n.acquisition.ingredient
else
out[#out+1] = h.head(i18n.acquisition.upgraded_from_header)
out[#out+1] = i18n.acquisition.upgraded_from
end
out[#out+1] = '<br>'
out[#out+1] = tostring(tbl)
end
function h.reward_table(data, rtbl)
if #data == 0 then
return
end
local tbl = m_quest_reward.reward_tbl_head()
for _, row in ipairs(data) do
local classes
if row[rtbl .. '.classes'] then
classes = {}
for _, class in ipairs(m_util.string.split(row[rtbl .. '.classes'], ',')) do
classes[class] = true
end
end
local tr = tbl:tag('tr')
m_quest_reward.reward_tbl_row_head(tr, rtbl, row)
local cell = {
[0] = {
value = '✗',
sort = 0,
class = 'table-cell-xmark',
},
[1] = {
value = '✓',
sort = 1,
class = 'table-cell-checkmark',
},
}
if rtbl == 'quest_rewards' then
local value = m_quest_reward.reward_tbl_extra_info(row)
-- If there isn't any extra information the checkmark will do
if value ~= '' then
cell[1].value = value
cell[1].class = nil
cell[1].css = 'text-align: center;'
end
end
if classes then
for _, class in ipairs(m_game.constants.characters_order) do
local cell_value
if classes[m_game.constants.characters[class].name] then
cell_value = cell[1]
else
cell_value = cell[0]
end
tr:tag('td')
:attr('class', cell_value.class or '')
:attr('style', cell_value.css or '')
:attr('table-sort-value', cell_value.sort)
:wikitext(cell_value.value)
end
else
tr:tag('td')
:attr('colspan', 7)
:attr('class', cell[1].class or '')
:attr('style', cell[1].css or '')
:attr('table-sort-value', cell[1].sort)
:wikitext(cell[1].value)
end
end
return h.head(i18n.quest_reward[rtbl .. '_header']) .. i18n.quest_reward[rtbl .. '_intro'] .. tostring(tbl)
end
-- ----------------------------------------------------------------------------
-- Templates
-- ----------------------------------------------------------------------------
local p = {}
--
-- Template: Item acquisition
--
function p.item_acquisition (frame)
--[[
Duplicates the information from the infobox in a more readable
manner on the page.
Example
-------
= p.item_acquisition{page='The Rite of Elements'}
]]
-- Get args
local tpl_args = getArgs(frame, {
parentFirst = true
})
frame = m_util.misc.get_frame(frame)
tpl_args.page = tpl_args.page or tostring(mw.title.getCurrentTitle())
local out = {}
local results
local query
out[#out+1] = tpl_args.acquisition_insert
-- fetch general item drop information that is used in multiple places in a
-- single query to reduce performance hit
local item_data = m_cargo.query(
{'items'},
{
'items.drop_text',
'items.drop_leagues',
'items.drop_areas__full',
'items.drop_monsters',
'items.drop_enabled',
},
{
where=string.format('items._pageName="%s"', tpl_args.page),
limit=1,
}
)
if #item_data > 0 then
item_data = item_data[1]
end
-- ------------------------------------------------------------------------
-- Drop disabled item
-- ------------------------------------------------------------------------
local drop_enabled = m_util.cast.boolean(item_data['items.drop_enabled'])
if not drop_enabled then
out[#out+1] = i18n.acquisition.drop_disabled
out[#out+1] = ' '
end
-- ------------------------------------------------------------------------
-- Drop restrictions by league
-- ------------------------------------------------------------------------
if item_data['items.drop_leagues'] and drop_enabled then
local text = string.format(i18n.acquisition.drop_leagues, item_data['items.drop_leagues'])
local mbox = f_message_box('ambox', {
type = 'notice',
text = tostring(text),
})
out[#out+1] = '\n\n'
out[#out+1] = mbox
out[#out+1] = '\n\n'
end
-- ------------------------------------------------------------------------
-- Drop restrictions by text
-- ------------------------------------------------------------------------
if item_data['items.drop_text'] and drop_enabled then
out[#out+1] = item_data['items.drop_text']
end
-- ------------------------------------------------------------------------
-- Drop restrictions by area
-- ------------------------------------------------------------------------
local area_ids
if item_data['items.drop_areas__full'] then
area_ids = m_util.string.split(item_data['items.drop_areas__full'], ',')
else
area_ids = {}
end
-- Handle legacy areas:
local legacy_area_ids = {
-- 'MapWar%',
'MapAtlas%',
'Map2%',
'MapTier%',
}
local condition_current = {}
local condition_legacy = {}
local order_legacy = {}
for i,v in ipairs(legacy_area_ids) do
condition_current[#condition_current+1] = string.format('areas.id NOT LIKE "%s"', v)
condition_legacy[#condition_legacy+1] = string.format('areas.id LIKE "%s"', v)
order_legacy[#order_legacy+1] = string.format('WHEN areas.id LIKE "%s" THEN %d', v,i)
end
local query_sets = {
{
header=i18n.acquisition.area_header,
condition=string.format('%s', table.concat(condition_current, ' AND ')),
order='areas.name ASC',
},
{
header=i18n.acquisition.area_legacy_header,
condition=string.format('%s', table.concat(condition_legacy, ' OR ')),
order=string.format([[
CASE
%s
ELSE %d
END ASC,
areas.name ASC
]],
table.concat(order_legacy, ' '),
#order_legacy+1
),
},
}
if #area_ids > 0 then
for _, query_set in ipairs(query_sets) do
local results = m_cargo.query(
{'areas'},
{
'areas._pageName',
'areas.id',
'areas.name',
'areas.main_page',
},
{
where=string.format('(%s) AND areas.id IN ("%s")', query_set.condition, table.concat(area_ids, '","')),
orderBy=query_set.order,
groupBy='areas.id',
}
)
if #results > 0 then
local ul = mw.html.create('ul')
for _, row in ipairs(results) do
ul:tag('li')
:wikitext(string.format('[[%s|%s]]', row['areas.main_page'] or row['areas._pageName'], row['areas.name']))
end
out[#out+1] = h.head(query_set.header)
out[#out+1] = i18n.acquisition.area
out[#out+1]= '<br>'
out[#out+1] = tostring(ul)
end
end
end
-- ------------------------------------------------------------------------
-- Drop restrictions by monster
-- ------------------------------------------------------------------------
local monster_metadata_ids = {}
if item_data['items.drop_monsters'] then
monster_metadata_ids = m_util.string.split(item_data['items.drop_monsters'], ',%s*')
end
if #monster_metadata_ids > 0 then
local results = m_cargo.query(
{'monsters', 'main_pages'},
{
'monsters._pageName',
'monsters.metadata_id',
'monsters.name',
-- 'monsters.main_page',
'main_pages._pageName',
},
{
join='monsters.metadata_id=main_pages.id',
where=string.format('monsters.metadata_id IN ("%s")', table.concat(monster_metadata_ids, '","')),
orderBy='monsters.name',
groupBy='monsters.metadata_id',
}
)
if #results > 0 then
local ul = mw.html.create('ul')
for _, row in ipairs(results) do
ul:tag('li')
:wikitext(string.format(
'[[%s|%s]]',
row['monsters.main_page']
or row['main_pages._pageName']
or row['monsters._pageName'],
row['monsters.name']
))
end
out[#out+1] = h.head(i18n.acquisition.monster_header)
out[#out+1] = i18n.acquisition.monster
out[#out+1]= '<br>'
out[#out+1] = tostring(ul)
end
end
-- ------------------------------------------------------------------------
-- Vendor recipes/upgrades handling
-- ------------------------------------------------------------------------
--
-- Query set data
--
local obtained_sets, obtained_sets_order = h.fetch_upgraded_from_sets(
string.format('upgraded_from_sets._pageName="%s"', tpl_args.page),
string.format('upgraded_from_groups._pageName="%s"', tpl_args.page)
)
results = m_cargo.query(
{'upgraded_from_groups'},
{
'upgraded_from_groups._pageID',
'upgraded_from_groups.set_id',
},
{
where=string.format('upgraded_from_groups.item_page="%s"', tpl_args.page),
-- only need one result set for the where clause
groupBy='upgraded_from_groups._pageID, upgraded_from_groups.set_id',
}
)
local where = {sets={}, groups={}}
for key, data in pairs(where) do
for _, row in ipairs(results) do
data[#data+1] = string.format('upgraded_from_%s.set_id="%s" AND upgraded_from_%s._pageID="%s"', key, row['upgraded_from_groups.set_id'], key, row['upgraded_from_groups._pageID'])
end
where[key] = table.concat(data, ' OR ')
end
local ingredient_sets, ingredient_sets_order = h.fetch_upgraded_from_sets(where.sets, where.groups)
--
-- Query bulk item info for item linking
--
local item_pages = {assoc={}}
for _, set_data in ipairs({{obtained_sets, obtained_sets_order}, {ingredient_sets, ingredient_sets_order}}) do
for _, set_key in ipairs(set_data[2]) do
local set = set_data[1][set_key]
for _, group in ipairs(set.groups) do
item_pages.assoc[group['upgraded_from_groups.item_page']] = true
end
item_pages.assoc[set['upgraded_from_sets._pageName']] = true
end
end
-- remove duplicates
for name, _ in pairs(item_pages.assoc) do
item_pages[#item_pages+1] = name
end
if #item_pages < c.MAX_ITEMS then
item_pages = m_cargo.map_results_to_id{
results=m_cargo.array_query{
tables={'items'},
fields={'items.name', 'items.inventory_icon', 'items.html'},
id_array = item_pages,
id_field = 'items._pageName',
query = {
limit=5000
},
},
field='items._pageName',
keep_id_field=true,
}
end
--
-- Output for being obtained via vendor recipe
--
h.upgraded_from_table(tpl_args, obtained_sets, obtained_sets_order, 'obtained', out, item_pages)
--
-- Ingredient of vendor recipes/upgrades
--
h.upgraded_from_table(tpl_args, ingredient_sets, ingredient_sets_order, 'ingredient', out, item_pages)
out[#out+1] = tpl_args.ingredient_append
-- ------------------------------------------------------------------------
-- Obtained via quest or vendor reward
-- ------------------------------------------------------------------------
local quest_rewards = m_cargo.query(
{'quest_rewards'},
{
'quest_rewards.quest',
'quest_rewards.act',
'quest_rewards.classes',
'quest_rewards.sockets',
'quest_rewards.item_level',
'quest_rewards.rarity',
},
{
where=string.format('quest_rewards._pageName="%s"', tpl_args.page),
orderBy='quest_rewards.act ASC, quest_rewards.quest_id ASC',
}
)
out[#out+1] = h.reward_table(quest_rewards, 'quest_rewards')
local vendor_rewards = m_cargo.query(
{'vendor_rewards'},
{
'vendor_rewards.quest',
'vendor_rewards.act',
'vendor_rewards.classes',
'vendor_rewards.npc',
},
{
where=string.format('vendor_rewards._pageName="%s"', tpl_args.page),
orderBy='vendor_rewards.act ASC, vendor_rewards.quest_id ASC',
}
)
out[#out+1] = h.reward_table(vendor_rewards, 'vendor_rewards')
-- ------------------------------------
-- output
-- ------------------------------------
local head = mw.html.create('h2')
head:wikitext(i18n.acquisition.header .. i18n.acquisition.link)
return tostring(head) .. table.concat(out)
end
-- ----------------------------------------------------------------------------
-- Return
-- ----------------------------------------------------------------------------
return p