Path of Exile Wiki

Wiki поддерживается сообществом, поэтому подумайте над тем, чтобы внести свой вклад.

ПОДРОБНЕЕ

Path of Exile Wiki
Нет описания правки
Нет описания правки
Строка 194: Строка 194:
 
end
 
end
 
 
return table.concat(value, ', ')
+
return table.concat(value, '<br>')
 
end
 
end
   

Версия от 16:58, 6 ноября 2018

Template info icon Документация модуля[просмотр] [править] [история] [очистить]

Модуль для обработки данных, связанных с наградой за выполнение заданий.

Подстраницы

--
-- 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 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 = 'Класс →',
        quest = 'Задание ↓',
        row_header = '[[%s]]<br>Акт %s',
        item_level = 'iLvl %s',
        links = '%s соединения',
    },
}

-- ----------------------------------------------------------------------------
-- Cargo
-- ----------------------------------------------------------------------------

local tables = {}

tables.quest_rewards = {
    table = 'quest_rewards',
    fields = {
        quest = {
            field = 'quest',
            type = 'String',
        },
        quest_id = {
            field = 'quest_id',
            type = 'Integer',
        },
        -- still needed?
        act = {
            field = 'act',
            type = 'Integer',
        },
        classes = {
            field = 'classes',
            type = 'String',
        },
        sockets = {
            field = 'sockets',
            type = 'Integer',
        },
        item_level = {
            field = 'item_level',
            type = 'Integer',
        },
        rarity = {
            field = 'rarity',
            type = 'String',
        },
        reward = {
            field = 'reward',
            type = 'Page',
        },
    },
}

tables.vendor_rewards = {
    table = 'vendor_rewards',
    fields = {
        quest = {
            field = 'quest',
            type = 'String',
        },
        quest_id = {
            field = 'quest_id',
            type = 'Integer',
        },
        act = {
            field = 'act',
            type = 'Integer',
        },
        reward = {
            field = 'reward',
            type = 'Page',
        },
        npc = {
            field = 'npc',
            type = 'String',
        },
        classes = {
            field = 'classes',
            type = 'String',
        },
    }
}

-- ----------------------------------------------------------------------------
-- Helper functions and globals
-- ----------------------------------------------------------------------------

local h = {}

-- ----------------------------------------------------------------------------
-- Page functions
-- ----------------------------------------------------------------------------

p.table_quest_rewards = m_util.cargo.declare_factory{data=tables.quest_rewards}
p.table_vendor_rewards = m_util.cargo.declare_factory{data=tables.vendor_rewards}

function p.store_data(frame)
    -- Get args
    tpl_args = getArgs(frame, {
        parentFirst = true
    })
    frame = m_util.misc.get_frame(frame)
    
    if tables[tpl_args.tbl .. '_rewards'] == nil then
        error(i18n.errors.invalid_table)
    end
    
    -- mw.loadData has some problems...
    local data = require(string.format('Module:Quest reward/data/%s', tpl_args.tbl))
    local imin = tpl_args.index_start or 1
    local imax = tpl_args.index_end or #data 
    for i=imin, imax or #data do 
        local row = data[i]
        if row == nil then
            break
        end
        -- get full table name
        row._table = tables[tpl_args.tbl .. '_rewards'].table
        m_util.cargo.store(frame, row)
    end
    
    return string.format(i18n.messages.storage, imin, imax, tpl_args.tbl)
end

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]]', class))
    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'] 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, '<br>')
end

function p.quest_reward_table(frame)
    -- 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_util.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.reward',
            },
            {
                where=q_where,
                orderBy='quest_rewards.act ASC, quest_rewards.quest_id ASC, quest_rewards.reward ASC',
                limit=5000,
            }
        )
    elseif tpl_args.type == 'vendor_rewards' then
        data = m_util.cargo.query(
            {'vendor_rewards'},
            {
                'vendor_rewards.quest',
                'vendor_rewards.act',
                'vendor_rewards.classes',
                'vendor_rewards.npc',
                'vendor_rewards.reward',
            },
            {
                where=q_where,
                orderBy='vendor_rewards.act ASC, vendor_rewards.quest_id ASC, vendor_rewards.reward 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
            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 .. '.reward']] = 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_util.cargo.map_results_to_id{
            results=m_util.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 .. '.reward']
            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 tr = tbl:tag('tr')
        
        local classes = quests[quest_key]
        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
        
        if classes[0] then
            tr:tag('td')
                :attr('colspan', 7)
                :attr('style', 'text-align: center;')
                :wikitext(element(classes[0]))
        else
            for _, class in ipairs(m_game.constants.characters_order) do
                tr:tag('td')
                    :wikitext(element(classes[class]))
            end
        end
    end
    
    return tostring(tbl)
end

-- ----------------------------------------------------------------------------
-- End
-- ----------------------------------------------------------------------------

return p