Path of Exile Wiki

Please consider helping keep the wiki up to date. Check the to-do list of updates needed for version 3.14.0.

Game data exports will becoming later as the technical changes in addition to regular changes take some more time.

READ MORE

Path of Exile Wiki
Advertisement
Template info icon Module documentation[view] [edit] [history] [purge]

--
-- Module for bestiary templates
--

local m_util = require('Module:Util')
local getArgs = require('Module:Arguments').getArgs
local f_infocard = require('Module:Infocard')._main

local p = {}

-- ----------------------------------------------------------------------------
-- Strings
-- ----------------------------------------------------------------------------

local i18n = {
    icon_name = 'File:%s passive skill icon.png',
    
    cats = {
        data = 'Passive skill data',
    },
    
    passive_box = {
        ascendancy = 'Ascendancy',
        keystone = 'Keystone',
        notable = 'Notable Passive Skill',
        passive = 'Passive Skill',
    },
    errors = {
        no_passives_found = 'No passive skills with the given name found',
    },
}

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

local tables = {}

tables.passive_skills = {
    table = 'passive_skills',
    order = {'id', 'int_id', 'name', 'flavour_text', 'reminder_text', 'buff_id', 'skill_points', 'icon', 'ascendancy_class', 'is_keystone', 'is_notable', 'is_multiple_choice_option', 'is_multiple_choice', 'is_icon_only', 'is_jewel_socket', 'is_ascendancy_starting_node', 'stat_text', 'stat_text_raw', 'connections',},
    fields = {
        id = {
            field = 'id',
            type = 'String(unique)',
            required = true,
        },
        int_id = {
            field = 'int_id',
            type = 'Integer(unique)',
            required = true,
        },
        name = {
            field = 'name',
            type = 'String',
        },
        flavour_text = {
            field = 'flavour_text',
            type = 'Text',
        },
        reminder_text = {
            field = 'id',
            type = 'Text',
        },
        buff_id = {
            field = 'id',
            type = 'String',
        },
        -- TODO: Other buff stuff 
        skill_points = {
            field = 'skill_points',
            type = 'Integer',
            default = 0,
        },
        icon = {
            field = 'icon',
            type = 'Page',
            func = function(tpl_args, frame, value)
                if value then
                    return string.format(i18n.icon_name, value)
                end
            end
        },
        ascendancy_class = {
            field = 'ascendancy_class',
            type = 'String',
        },
        is_keystone = {
            field = 'is_keystone',
            type = 'Boolean',
            default = false,
        },
        is_notable = {
            field = 'is_notable',
            type = 'Boolean',
            default = false,
        },
        is_multiple_choice_option = {
            field = 'is_multiple_choice_option',
            type = 'Boolean',
            default = false,
        },
        is_multiple_choice = {
            field = 'is_multiple_choice',
            type = 'Boolean',
            default = false,
        },
        is_icon_only = {
            field = 'is_icon_only',
            type = 'Boolean',
            default = false,
        },
        is_jewel_socket = {
            field = 'is_jewel_socket',
            type = 'Boolean',
            default = false,
        },
        is_ascendancy_starting_node = {
            field = 'is_ascendancy_starting_node',
            type = 'Boolean',
            default = false,
        },
        stat_text = {
            field = 'stat_text',
            type = 'Text',
        },
        stat_text_raw = {
            field = 'stat_text',
            type = 'Text',
            func = function (tpl_args, frame)
                if tpl_args.stat_text then
                    tpl_args.stat_text_raw = string.gsub(
                        -- [[x]] -> x
                        string.gsub(
                            tpl_args.stat_text, '%[%[([^%]|]+)%]%]', '%1'
                        ), 
                        -- [[x|y]] -> y
                        '%[%[[^|]+|([^%]|]+)%]%]', '%1'
                    )
                end
                return tpl_args.stat_text_raw
            end
        },
        -- from the graph file:
        connections = {
            field = 'connections',
            type = 'List (,) of String',
        },
    }
}

tables.passive_skill_stats = {
    table = 'passive_skill_stats',
    fields = {
        id = {
            field = 'id',
            type = 'String',
        },
        value = {
            field = 'value',
            type = 'Integer',
        },
    }
}

-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------

local h = {}

function h.format_passive_icon(passive)
    if passive['passive_skills.icon'] == nil then
        return ''
    end
    
    local cls
    if passive['passive_skills.is_keystone'] == 1 then
        cls = 'keystone'
    elseif passive['passive_skills.is_notable'] == 1 then
        cls = 'notable'
    else
        cls = 'basic'
    end
    
    if passive['passive_skills.ascendancy_class'] ~= nil then
        cls = 'ascendancy_' .. cls
    end
    cls = string.format('passive-icon-type__%s', cls)
    
    div = mw.html.create('div')
    div:addClass('passive-icon-container')
    div:addClass(cls)
    div:tag('div')
        :addClass('passive-icon-frame')
        :done()
    div:wikitext(string.format('[[%s]]', passive['passive_skills.icon']))
    
    return tostring(div)
end

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

local p = {}

p.table_passive_skills = m_util.cargo.declare_factory{data=tables.passive_skills}
p.table_passive_skill_stats = m_util.cargo.declare_factory{data=tables.passive_skill_stats}

function p.passive_skill(frame)
    -- Get args
    tpl_args = getArgs(frame, {
        parentFirst = true
    })
    frame = m_util.misc.get_frame(frame)
    -- parse 
    m_util.args.from_cargo_map{
        tpl_args=tpl_args,
        frame=frame,
        table_map=tables.passive_skills,
    }
    
    -- parse stats
    m_util.args.stats(tpl_args, {})
    for _, stat in ipairs(tpl_args.stats) do
        stat._table = tables.passive_skill_stats.table
        m_util.cargo.store(frame, stat)
    end
    
    cats = {
        i18n.cats.data,
    }
    
    return m_util.misc.add_category(cats)
end

function p.passive_skill_box(frame)
    -- Get args
    tpl_args = getArgs(frame, {
        parentFirst = true
    })
    frame = m_util.misc.get_frame(frame)
    
    tpl_args.name = tpl_args.name or tpl_args[1]
    
    if not tpl_args.q_where and tpl_args.name then
        tpl_args.q_where = string.format('passive_skills.name="%s"', tpl_args.name)
    elseif not (tpl_args.q_where and not tpl_args.name) then
        error('q_where or name must be specified')
    end
    
    tpl_args.q_where = tpl_args.q_where .. ' AND passive_skills.stat_text IS NOT NULL'
    
    local results = m_util.cargo.query(
        {'passive_skills'},
        {
            'passive_skills._pageName', 
            'passive_skills.stat_text',
            -- TODO: only really need these once, maybe put in extra query
            'passive_skills.flavour_text',
            'passive_skills.stat_text',
            'passive_skills.icon',
            'passive_skills.is_keystone',
            'passive_skills.is_notable',
            'passive_skills.ascendancy_class',
        }, 
        {
            where=tpl_args.q_where,
            orderBy='passive_skills.stat_text',
        }
    )
    
    if #results == 0 then
        error(i18n.errors.no_passives_found)
    end
    
    local stats = {}
    local stat_order = {}
    for _, row in ipairs(results) do 
        local stat = row['passive_skills.stat_text']
        -- Can't show results here that don't have a stat line
        if stat then
            if stats[stat] == nil then
                stats[stat] = {row['passive_skills._pageName']}
                table.insert(stat_order, stat)
            else
                table.insert(stats[stat], row['passive_skills._pageName'])
            end
        end
    end
    
    local passive = results[1]
    
    local infocard_args = {}
    infocard_args.header = tpl_args.name
    if passive['passive_skills.is_keystone'] == 1 then
        infocard_args.subheader = i18n.passive_box.keystone
    elseif passive['passive_skills.is_notable'] == 1 then
        infocard_args.subheader = i18n.passive_box.notable
    else
        infocard_args.subheader = i18n.passive_box.passive
    end
    
    if passive['passive_skills.ascendancy_class'] ~= nil then
        infocard_args.subheader = i18n.passive_box.ascendancy .. ' ' .. infocard_args.subheader
    end
    
    infocard_args[1] = h.format_passive_icon(passive)
    
    local out = {}
    for i, stat_text in ipairs(stat_order) do
        local links = {}
        for j, page in ipairs(stats[stat_text]) do
            links[#links+1] = string.format('[[%s|[%s]]]', page, j)
        end
        
        out[i] = string.format('<span class="passive-line">%s <span class="passive-hover">%s</span></span>', stat_text, table.concat(links, ' '))
    end
    
    infocard_args[2] = table.concat(out, '<hr>')
    
    return f_infocard(infocard_args)
end

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

return p
Advertisement