Module:Mastery effect

From Path of Exile Wiki
Jump to navigation Jump to search
Module documentation[view] [edit] [history] [purge]


This module is for specifying the mastery effects of one option from a passive mastery

Lua logo

This module depends on the following other modules:

-------------------------------------------------------------------------------
-- 
--                            Module:Mastery effect
-- 
-- This module implements Template:Mastery effect
-------------------------------------------------------------------------------

local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')

local f_infocard = require('Module:Infocard')._main

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

local i18n = {
    cats = {
        effect = 'Mastery Effect',
        data = 'Mastery Effects',
        
        keystone = 'Keystone passive skills',
        notable = 'Notable passive skills',
        basic = 'Small passive skills',
        ascendancy_notable = 'Ascendancy notable passive skills',
        ascendancy_basic = 'Ascendancy small passive skills',
    },
    
    mastery_effct_box = {
        title = 'Mastery Effect',
    },
    
    intro = {
        text = "'''%s''' is the internal id for the a [[Passive Mastery|Mastery Effect]]. ",
    },
    
    mastery_effct_box_table = {
        id = 'Id',
        int_id = 'Integer Id',
        flavour_text = 'Flavour Text',
        reminder_text = 'Reminder Text',
        skill_points = 'Skill Points Granted',
        ascendancy_class = 'Ascendancy Class',
        connections = 'Connections',
    },
    
    passive_table = {
        ascendancy_class = 'Ascendancy<br>Class',
        name = 'Name',
        stats = 'Stats',
    },
    
    errors = {
        no_passives_found = 'No passive skills with the given name found',
    },
}

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

local tables = {}

tables.mastery_effects = {
    table = 'mastery_effects',
    order = {'id', 'main_page', 'stat_text', 'stat_text_raw',},
    fields = {
        id = {
            field = 'id',
            type = 'String',
            required = true,
        },
        main_page = {
            field = 'main_page',
            type = 'Page',
        },
        stat_text = {
            field = 'stat_text',
            type = 'Text',
        },
        stat_text_raw = {
            field = 'stat_text',
            type = 'Text',
            func = function (tpl_args, value)
                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
        },
    }
}

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

local display = {}
display.map_to_property = {'id'}
display.tbl = {
    {
        key = 'id',
        header = i18n.mastery_effct_box_table.id,
        display = nil,
    },
}

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

local h = {}

-- function h.format_passive_icon(passive, passive_type)
--     if passive['passive_skills.icon'] == nil then
--         return ''
--     end
    
--     local cls = string.format('passive-icon-type__%s', passive_type)
--     local main_page = passive['passive_skills.main_page'] or passive['main_pages._pageName'] or passive['passive_skills.name'] or passive['passive_skills.icon']
--     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|link=%s]]', 
--             passive['passive_skills.icon'], 
--             main_page
--         )
--     )
    
--     return tostring(div)
-- end

-- function h.make_stat_order(results)
--     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}
--                 table.insert(stat_order, stat)
--             else
--                 table.insert(stats[stat], row)
--             end
--         end
--     end
    
--     return stats, stat_order
-- end

-- function h.stat_page_links(stat_order, stats)
--     local out = {}
--     for i, key in ipairs(stat_order) do
--         local links = {}
--         for j, row in ipairs(stats[key]) do
--             links[#links+1] = string.format('[[%s|&#91;%s&#93;]]', row['passive_skills._pageName'], j)
--         end
--         out[i] = string.format('<span class="passive-line">%s <span class="passive-hover">%s</span></span>', key, table.concat(links, ' '))
--     end
    
--     return table.concat(out, '<hr>')
-- end

-- h.type_order = {'basic', 'notable', 'keystone', 'ascendancy_basic', 'ascendancy_notable'}
-- function h.get_type(passive)
--     local key
--     if tonumber(passive['passive_skills.is_keystone']) == 1 then
--         key = 'keystone'
--     elseif tonumber(passive['passive_skills.is_notable']) == 1 then
--         key = 'notable'
--     else
--         key = 'basic'
--     end
    
--     if passive['passive_skills.ascendancy_class'] ~= nil then
--         key = 'ascendancy_' .. key
--     end
    
--     return key
-- end

-- function h.sort_by_type(results)
--     local new = {}
--     for _, key in ipairs(h.type_order) do
--         new[key] = {}
--     end
    
--     for _, passive in ipairs(results) do
--         table.insert(new[h.get_type(passive)], passive)
--     end
    
--     return new
-- end

function h.intro_text(tpl_args)
    --[[
    Display an introductory text about the passive skill.
    ]]
    local out = {}
    if mw.ustring.find(tpl_args['id'], '_') then
        out[#out+1] = mw.getCurrentFrame():expandTemplate{
            title='Incorrect title', 
            args = {title=tpl_args['id']} 
        }
    end
    
    out[#out+1] = string.format(
        i18n.intro.text, 
        tpl_args['id']
    )
    
    return table.concat(out)
end

function h.stat_box(tpl_args)
    --[[
    Display the stat box.
    ]]
    local container = mw.html.create('div')
    container
        :attr('class', 'modbox floatright')
        
    -- stat table 
    local tbl = container:tag('table')
    tbl
        :attr('class', 'wikitable sortable')
        -- :attr('style', 'style="width: 100%;"')
        :tag('tr')
            :tag('th')
                :attr('colspan', 3)
                :wikitext('Stats')
                :done()
            :done()
        :tag('tr')
            :tag('th')
                :wikitext('#')
                :done()
            :tag('th')
                :wikitext('Stat Id')
                :done()
            :tag('th')
                :wikitext('Value')
                :done()
            :done()
            :done()
        :done()
        
    local i = 0
    local value = nil
    repeat
        i = i + 1
        value = {
            id = tpl_args[string.format('stat%s_id', i)],
            value = tpl_args[string.format('stat%s_value', i)],
        }
        
        if value.id then
            tbl
                :tag('tr')
                    :tag('td')
                        :wikitext(i)
                        :done()
                    :tag('td')
                        :wikitext(value.id)
                        :done()
                    :tag('td')
                        :wikitext(value.value)
                        :done()
                    :done()
                :done()
        end
    until value.id == nil
    
    return tostring(container)
end

-- ----------------------------------------------------------------------------
-- Main functions
-- ----------------------------------------------------------------------------

local function _mastery_effect(tpl_args)
    --[[
    Stores data and displays a infobox about the passive skill.
    
    Examples
    --------
    = p.mastery_effect{
        id = 'Resistance6',
        stat1_id = 'base_resist_all_elements_%',
        stat1_value = '12',
        stat2_id = 'base_chaos_damage_resistance_%',
        stat2_value = '7',
        stat_text = '+12% to all Elemental Resistance<br>+7% to Chaos Resistance',
    }
    
    ]]

    -- parse and store mastery effect into cargo table
    m_util.args.from_cargo_map{
        tpl_args=tpl_args,
        table_map=tables.mastery_effects,
    }
    
    -- parse stats and store them into cargo table
    m_util.args.stats(tpl_args, {})
    for _, stat in ipairs(tpl_args.stats) do
        stat._table = tables.mastery_effect_stats.table
        m_cargo.store(stat)
    end
    
    -- Attach to tables
    mw.getCurrentFrame():expandTemplate{title = 'Template:Mastery effect/cargo/mastery effects/attach'}
    mw.getCurrentFrame():expandTemplate{title = 'Template:Mastery effect/cargo/mastery effect stats/attach'}

    --
    -- Infobox
    --
    local passive = {}
    for _, key in ipairs(display.map_to_property) do
        local v = tpl_args[key]
        passive[string.format('%s.%s', tables.mastery_effects.table, tables.mastery_effects.fields[key].field)] = v
    end

    local infocard_args = {}
    infocard_args.header = tpl_args.id
    infocard_args.subheader = i18n.mastery_effct_box['title']
    
    local tbl = mw.html.create('table')
    for _, data in ipairs(display.tbl) do
        local value = tpl_args[data.key]
        -- if default is nil, this will be compared against nil which is what we want, so value ~= nil isn't needed
        if value ~= tables.mastery_effects.fields[data.key].default then
            local dsp
            if data.display then
                dsp = data.display(tpl_args, value)
            else
                dsp = value
            end
            tbl
                :tag('tr')
                    :tag('th')
                        :wikitext(data.header)
                        :done()
                    :tag('td')
                        :attr('class', data.css)
                        :wikitext(dsp)
                        :done()
                    :done()
        end
    end
    
    infocard_args[1] = tostring(tbl)
    infocard_args[2] = tpl_args.stat_text

    local out = {
        f_infocard(infocard_args),
        h.intro_text(tpl_args),
        h.stat_box(tpl_args),
    }
    
    local cats = {
        i18n.cats.data,
    }

    return table.concat(out) .. m_util.misc.add_category(cats)
end

-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------

local p = {}

-- Declare cargo tables:
p.table_mastery_effects = m_cargo.declare_factory{data=tables.mastery_effects}
p.table_mastery_effect_stats = m_cargo.declare_factory{data=tables.mastery_effect_stats}

--
-- Template:Mastery effect
-- 
p.mastery_effect = m_util.misc.invoker_factory(_mastery_effect, {
    wrappers = 'Template:Mastery effect',
})

return p