Module:Incursion/sandbox: Difference between revisions

From Path of Exile Wiki
Jump to navigation Jump to search
(parity with current version)
No edit summary
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
--
-------------------------------------------------------------------------------
-- Module for incursion related templates
--  
--
--                           Module:Incursion
--
-- This module implements Template:Incursion room and
-- Template:Incursion room progression
-------------------------------------------------------------------------------


require('Module:No globals')
local m_util = require('Module:Util')
local m_util = require('Module:Util')
local f_infocard = require('Module:Infocard')._main
local getArgs = require('Module:Arguments').getArgs
local m_cargo = require('Module:Cargo')
local m_cargo = require('Module:Cargo')
local p = {}


-- ----------------------------------------------------------------------------
-- Should we use the sandbox version of our submodules?
-- Strings
local use_sandbox = m_util.misc.maybe_sandbox('Incursion')
-- ----------------------------------------------------------------------------
 
-- Lazy loading
local f_infocard -- require('Module:Infocard')._main
 
-- The cfg table contains all localisable strings and configuration, to make it
-- easier to port this module to another wiki.
local cfg = use_sandbox and mw.loadData('Module:Incursion/config/sandbox') or mw.loadData('Module:Incursion/config')


local i18n = {
local i18n = cfg.i18n
    icon_format = 'File:%s incursion room icon.png',
   
    headers = {
        id = 'Id',
        tier = 'Tier',
        upgrade_room_id = 'Upgrades to',
        min_level = 'Min. Level',
        max_level = 'Max. Level',
        weight = 'Weight',
        architect = 'Architect',
        modifier_ids = 'Modifiers',
    },
}


-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
Line 44: Line 39:
                 required = true,
                 required = true,
                  
                  
                 header = i18n.headers.id,
                 header = i18n.headings.id,
             },
             },
             name = {
             name = {
Line 53: Line 48:
                 field = 'description',
                 field = 'description',
                 type = 'Text',
                 type = 'Text',
                 display = function (tpl_args, frame)
                 display = function (tpl_args)
                     return m_util.html.poe_color('mod', tpl_args.description)
                     return m_util.html.poe_color('mod', tpl_args.description)
                 end
                 end
Line 60: Line 55:
                 field = 'flavour_text',
                 field = 'flavour_text',
                 type = 'Text',
                 type = 'Text',
                 display = function (tpl_args, frame)
                 display = function (tpl_args)
                     return m_util.html.poe_color('flavour', tpl_args.flavour_text)
                     return m_util.html.poe_color('flavour', tpl_args.flavour_text)
                 end
                 end
Line 68: Line 63:
                 type = 'Integer',
                 type = 'Integer',
                  
                  
                 header = i18n.headers.tier,
                 header = i18n.headings.tier,
             },
             },
             upgrade_room_id = {
             upgrade_room_id = {
                 field = 'upgrade_room_id',
                 field = 'upgrade_room_id',
                 type = 'String',
                 type = 'String',
                 func = function (tpl_args, frame, value)
                 func = function (tpl_args, value)
                     if value == nil then
                     if value == nil then
                         return
                         return
Line 92: Line 87:
                 end,
                 end,
                  
                  
                 header = i18n.headers.upgrade_room_id,
                 header = i18n.headings.upgrade_room_id,
                 display = function(tpl_args, frame)
                 display = function(tpl_args)
                     if tpl_args.upgrade_room == nil then
                     if tpl_args.upgrade_room == nil then
                         if tpl_args.upgrade_room_id == nil then
                         if tpl_args.upgrade_room_id == nil then
Line 107: Line 102:
                 field = 'icon',
                 field = 'icon',
                 type = 'Page',
                 type = 'Page',
                 func = function (tpl_args, frame, value)
                 func = function (tpl_args, value)
                     if value == nil then
                     if value == nil then
                         return
                         return
                     end
                     end
                      
                      
                     return string.format(i18n.icon_format, value)
                     return string.format(i18n.files.icon_format, value)
                 end,
                 end,
                  
                  
                 display = function (tpl_args, frame)
                 display = function (tpl_args)
                     return string.format('[[%s]]', tpl_args.icon)
                     return string.format('[[%s]]', tpl_args.icon)
                 end,
                 end,
Line 124: Line 119:
                 default = 0,
                 default = 0,
                  
                  
                 header = i18n.headers.min_level,
                 header = i18n.headings.min_level,
             },
             },
             -- architect_name is temporary until monsters are added to the wiki
             -- architect_name is temporary until monsters are added to the wiki
Line 134: Line 129:
                 field = 'architect_name',
                 field = 'architect_name',
                 type = 'String',
                 type = 'String',
                 header = i18n.headers.architect,
                 header = i18n.headings.architect,
                 display = function (tpl_args, frame)
                 display = function (tpl_args)
                     return string.format('[[%s]]', tpl_args.architect_name)
                     return string.format('[[%s]]', tpl_args.architect_name)
                 end,
                 end,
Line 142: Line 137:
                 field = 'modifier_ids',
                 field = 'modifier_ids',
                 type = 'List (,) of String',
                 type = 'List (,) of String',
                 func = function (tpl_args, frame, value)
                 func = function (tpl_args, value)
                     if value == nil then
                     if value == nil then
                         return
                         return
Line 156: Line 151:
                 end,
                 end,
                  
                  
                 header = i18n.headers.modifier_ids,
                 header = i18n.headings.modifier_ids,
             },
             },
             stat_text = {
             stat_text = {
                 field = 'stat_text',
                 field = 'stat_text',
                 type = 'Text',
                 type = 'Text',
                 func = function (tpl_args, frame)
                 func = function (tpl_args, value)
                     if tpl_args.mods == nil then
                     if tpl_args.mods == nil then
                         return
                         return
Line 179: Line 174:


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


local h = {}
local h = {}
function h.check_args(tpl_args, frame, key, data)
 
function h.check_args(tpl_args, key, data)
     local value = tpl_args[key]
     local value = tpl_args[key]
     if value == nil then
     if value == nil then
Line 194: Line 190:
      
      
     return true
     return true
end
-- Lazy loading for Module:Infocard
function h.infocard(args)
    if not f_infocard then
        f_infocard = require('Module:Infocard')._main
    end
    return f_infocard(args)
end
-- Query room
function h.query_room(args)
    if not m_util.table.has_any_key(args, {'id', 'page'}) then
        error(i18n.errors.missing_search_term)
    end
    local tables = {'incursion_rooms'}
    local fields = {
        'incursion_rooms._pageName=_pageName',
        'incursion_rooms.id=id',
        'incursion_rooms.architect_metadata_id=architect_metadata_id',
    }
    local query = {
        groupBy = 'incursion_rooms._pageID',
    }
    local search_param
    if args.id then
        query.where = string.format(
            'incursion_rooms.id = "%s"',
            args.id
        )
        search_param = 'id'
    else
        query.where = string.format(
            'incursion_rooms._pageName = "%s"',
            args.page
        )
        search_param = 'page'
    end
    local results = m_cargo.query(tables, fields, query)
    local err
    if #results == 0 then
        -- No results found
        err = m_util.Error{
            message = string.format(
                i18n.errors.no_results_found,
                search_param,
                args[search_param]
            ),
            code = 'no_results_found',
        }
    end
    if err then
        return {error = err}
    end
    return results[1]
end
end


-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
-- Page functions
-- Main functions
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------


p.table_incursion_rooms = m_cargo.declare_factory{data=tables.incursion_rooms}
local function _incursion_room(tpl_args)
 
function p.incursion_room(frame)
     --[[
     --[[
     Stores cargo data for incursion rooms and displays it in a infobox.
     Stores cargo data for incursion rooms and displays it in a infobox.
Line 221: Line 270:
      
      
     ]]
     ]]
   
   
    -- Get args
    tpl_args = getArgs(frame, {
        parentFirst = true
    })
    frame = m_util.misc.get_frame(frame)
      
      
     m_util.args.from_cargo_map{
     m_util.args.from_cargo_map{
         tpl_args=tpl_args,
         tpl_args=tpl_args,
        frame=frame,
         table_map=tables.incursion_rooms,
         table_map=tables.incursion_rooms,
     }
     }
Line 241: Line 282:
     infocard_args.header = tpl_args.name
     infocard_args.header = tpl_args.name
      
      
     function display (value, data)
     local function display (value, data)
         if data.display then
         if data.display then
             return data.display(tpl_args, frame) or ''
             return data.display(tpl_args) or ''
         end
         end
          
          
Line 258: Line 299:
     for _, key in ipairs(tables.incursion_rooms.display_table_order) do
     for _, key in ipairs(tables.incursion_rooms.display_table_order) do
         local data = tables.incursion_rooms.fields[key]
         local data = tables.incursion_rooms.fields[key]
         if h.check_args(tpl_args, frame, key, data) then
         if h.check_args(tpl_args, key, data) then
             tbl
             tbl
                 :tag('tr')
                 :tag('tr')
Line 276: Line 317:
     for _, key in ipairs(tables.incursion_rooms.display_list_order) do
     for _, key in ipairs(tables.incursion_rooms.display_list_order) do
         local data = tables.incursion_rooms.fields[key]
         local data = tables.incursion_rooms.fields[key]
         if h.check_args(tpl_args, frame, key, data) then
         if h.check_args(tpl_args, key, data) then
             infocard_args[i] = display(tpl_args[key], data)
             infocard_args[i] = display(tpl_args[key], data)
             i = i + 1
             i = i + 1
Line 289: Line 330:
         'Incursion rooms',
         'Incursion rooms',
     }
     }
    -- Attach to table
    mw.getCurrentFrame():expandTemplate{title = 'Template:Incursion room/cargo/incursion_rooms/attach'}
      
      
     --
     --
Line 294: Line 338:
     --
     --
      
      
     return f_infocard(infocard_args) .. m_util.misc.add_category(cats)
     return h.infocard(infocard_args) .. m_util.misc.add_category(cats)
end
 
local function _room_progression(args)
    --[[
    Displays a succession box of the rooms for one architect
    --]]
 
    args.page = args.page or mw.title.getCurrentTitle().prefixedText
 
    -- Query room
    local room = h.query_room(args)
    if room.error then
        room.error:throw()
    end
 
    -- Query room progression
    local results = m_cargo.query(
        {
            'incursion_rooms',
        },
        {
            'incursion_rooms._pageName=_pageName',
            'incursion_rooms.name=name',
            'incursion_rooms.tier=tier',
            'incursion_rooms.icon=icon',
            'incursion_rooms.architect_name=architect_name',
        },
        {
            where = string.format(
                'incursion_rooms.architect_metadata_id = "%s" AND incursion_rooms.tier > 0',
                room.architect_metadata_id
            ),
            groupBy = 'incursion_rooms._pageID',
            orderBy = 'incursion_rooms.tier ASC',
            limit = cfg.tier_max,
        }
    )
    if #results == 0 then
        error(i18n.errors.no_progression)
    end
 
    -- Build succession box
    local html = mw.html.create('table')
        :addClass('wikitable successionbox')
        :tag('tr')
            :tag('th')
                :attr('colspan', #results)
                :wikitext( m_util.html.wikilink(results[1].architect_name) )
                :done()
            :done()
    local row = html:tag('tr')
    for _, v in ipairs(results) do
        row:tag('td')
            :cssText('width: 33.3%')
            :wikitext(
                string.format(
                    '[[%s|160px|link=%s]] <br> %s. %s',
                    v.icon,
                    v._pageName,
                    i18n.tiers_roman[tonumber(v.tier)],
                    m_util.html.wikilink(v._pageName, v.name)
                )
            )
    end
 
    return tostring(html)
end
end


-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
-- End
-- Exported functions
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
local p = {}
p.table_incursion_rooms = m_cargo.declare_factory{data=tables.incursion_rooms}
--
-- Template:Incursion room
--
p.incursion_room = m_util.misc.invoker_factory(_incursion_room, {
    wrappers = cfg.wrappers.incursion_room,
})
--
-- Template:Incursion room progression
--
p.room_progression = m_util.misc.invoker_factory(_room_progression, {
    wrappers = cfg.wrappers.room_progression,
})


return p
return p

Latest revision as of 16:11, 30 April 2023

This is the module sandbox page for Module:Incursion (diff).

Module documentation[view] [edit] [history] [purge]


Handles various incursion related templates:


-------------------------------------------------------------------------------
-- 
--                            Module:Incursion
-- 
-- This module implements Template:Incursion room and 
-- Template:Incursion room progression
-------------------------------------------------------------------------------

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

-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Incursion')

-- Lazy loading
local f_infocard -- require('Module:Infocard')._main

-- The cfg table contains all localisable strings and configuration, to make it
-- easier to port this module to another wiki.
local cfg = use_sandbox and mw.loadData('Module:Incursion/config/sandbox') or mw.loadData('Module:Incursion/config')

local i18n = cfg.i18n

-- ----------------------------------------------------------------------------
-- Tables
-- ----------------------------------------------------------------------------

local tables = {
    incursion_rooms = {
        table = 'incursion_rooms',
        order = {'id', 'name', 'description', 'flavour_text', 'tier', 'upgrade_room_id', 'icon', 'min_level', 'architect_metadata_id', 'architect_name', 'modifier_ids', 'stat_text'},
        display_table_order = {'id', 'tier', 'upgrade_room_id', 'min_level', 'architect_name'},
        display_list_order = {'description', 'stat_text', 'icon', 'flavour_text',},
        fields = {
            id = {
                field = 'id',
                type = 'String(size=100; unique)',
                required = true,
                
                header = i18n.headings.id,
            },
            name = {
                field = 'name',
                type = 'String',
            },
            description = {
                field = 'description',
                type = 'Text',
                display = function (tpl_args)
                    return m_util.html.poe_color('mod', tpl_args.description)
                end
            },
            flavour_text = {
                field = 'flavour_text',
                type = 'Text',
                display = function (tpl_args)
                    return m_util.html.poe_color('flavour', tpl_args.flavour_text)
                end
            },
            tier = {
                field = 'tier',
                type = 'Integer',
                
                header = i18n.headings.tier,
            },
            upgrade_room_id = {
                field = 'upgrade_room_id',
                type = 'String',
                func = function (tpl_args, value)
                    if value == nil then
                        return
                    end
                    local results = m_cargo.query(
                        {'incursion_rooms'},
                        {'incursion_rooms._pageName', 'incursion_rooms.name'},
                        {
                            where=string.format('incursion_rooms.id="%s"', value)
                        }
                    )
                    if #results == 0 then
                        return
                    end
                    -- Save the upgrade room to tpl_args so we can make a link for it in the display
                    tpl_args.upgrade_room = results[1]
                    return value
                end,
                
                header = i18n.headings.upgrade_room_id,
                display = function(tpl_args)
                    if tpl_args.upgrade_room == nil then
                        if tpl_args.upgrade_room_id == nil then
                            return
                        else
                            return tpl_args.upgrade_room_id
                        end
                    end
                    return string.format('[[%s|%s]]', tpl_args.upgrade_room['incursion_rooms._pageName'], tpl_args.upgrade_room['incursion_rooms.name'])
                end
            },
            icon = {
                field = 'icon',
                type = 'Page',
                func = function (tpl_args, value)
                    if value == nil then
                        return
                    end
                    
                    return string.format(i18n.files.icon_format, value)
                end,
                
                display = function (tpl_args)
                    return string.format('[[%s]]', tpl_args.icon)
                end,
            },
            min_level = {
                field = 'min_level',
                type = 'Integer',
                default = 0,
                
                header = i18n.headings.min_level,
            },
            -- architect_name is temporary until monsters are added to the wiki
            architect_metadata_id = {
                field = 'architect_metadata_id',
                type = 'String',
            },
            architect_name = {
                field = 'architect_name',
                type = 'String',
                header = i18n.headings.architect,
                display = function (tpl_args)
                    return string.format('[[%s]]', tpl_args.architect_name)
                end,
            },
            modifier_ids = {
                field = 'modifier_ids',
                type = 'List (,) of String',
                func = function (tpl_args, value)
                    if value == nil then
                        return
                    end
                    tpl_args.mods = m_cargo.array_query{
                        tables={'mods'},
                        fields={'mods.stat_text'},
                        id_field='mods.id',
                        id_array=value
                    }
                    
                    return value
                end,
                
                header = i18n.headings.modifier_ids,
            },
            stat_text = {
                field = 'stat_text',
                type = 'Text',
                func = function (tpl_args, value)
                    if tpl_args.mods == nil then
                        return
                    end
                    local text = {}
                    for page, row in pairs(tpl_args.mods) do
                        if row['mods.stat_text'] then
                            text[#text+1] = row['mods.stat_text']
                        end
                    end
                    return table.concat(text, '<br>')
                end,
            },
        },
    },
}

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

local h = {}

function h.check_args(tpl_args, key, data)
    local value = tpl_args[key]
    if value == nil then
        return false
    end
    
    if data.default == value then
        return false
    end
    
    return true
end

-- Lazy loading for Module:Infocard
function h.infocard(args)
    if not f_infocard then
        f_infocard = require('Module:Infocard')._main
    end
    return f_infocard(args)
end

-- Query room
function h.query_room(args)
    if not m_util.table.has_any_key(args, {'id', 'page'}) then
        error(i18n.errors.missing_search_term)
    end
    local tables = {'incursion_rooms'}
    local fields = {
        'incursion_rooms._pageName=_pageName',
        'incursion_rooms.id=id',
        'incursion_rooms.architect_metadata_id=architect_metadata_id',
    }
    local query = {
        groupBy = 'incursion_rooms._pageID',
    }
    local search_param
    if args.id then
        query.where = string.format(
            'incursion_rooms.id = "%s"',
            args.id
        )
        search_param = 'id'
    else
        query.where = string.format(
            'incursion_rooms._pageName = "%s"',
            args.page
        )
        search_param = 'page'
    end
    local results = m_cargo.query(tables, fields, query)
    local err
    if #results == 0 then
        -- No results found
        err = m_util.Error{
            message = string.format(
                i18n.errors.no_results_found,
                search_param,
                args[search_param]
            ),
            code = 'no_results_found',
        }
    end
    if err then
        return {error = err}
    end
    return results[1]
end

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

local function _incursion_room(tpl_args)
    --[[
    Stores cargo data for incursion rooms and displays it in a infobox.
    
    Examples
    --------
    = p.incursion_room{
        id = 'CorruptionRoomIII',
        name = 'Locus of Corruption',
        description = 'Reduces player maximum resistances throughout the Temple.<br />Contains an Altar of Corruption.',
        flavour_text = 'Darkness coalesces, imbues, and blesses.',
        tier = '3',
        icon = 'CorruptionRoom3',
        modifier_ids = 'MapPlayerMaxResists3__',
        architect_metadata_id = 'Metadata/Monsters/VaalArchitect/VaalArchitect8',
        architect_name = 'Paquate, Architect of Corruption',
    }
    
    ]]
    
    m_util.args.from_cargo_map{
        tpl_args=tpl_args,
        table_map=tables.incursion_rooms,
    }
    
    --
    -- infobox
    -- 
    local infocard_args = {}
    infocard_args.header = tpl_args.name
    
    local function display (value, data)
        if data.display then
            return data.display(tpl_args) or ''
        end
        
        if type(value) == 'table' then
            return table.concat(value, ', ')
        end
        
        return value or ''
    end
    
    -- Main sections, loop through
    local tbl = mw.html.create('table')
    tbl:attr('style', 'width: 100%;')
    for _, key in ipairs(tables.incursion_rooms.display_table_order) do
        local data = tables.incursion_rooms.fields[key]
        if h.check_args(tpl_args, key, data) then
            tbl
                :tag('tr')
                    :tag('th')
                        :wikitext(data.header or '')
                        :done()
                    :tag('td')
                        :wikitext(display(tpl_args[key], data))
                        :done()
                    :done()
        end
    end
    
    infocard_args[1] = tostring(tbl)
    
    local i = 2
    for _, key in ipairs(tables.incursion_rooms.display_list_order) do
        local data = tables.incursion_rooms.fields[key]
        if h.check_args(tpl_args, key, data) then
            infocard_args[i] = display(tpl_args[key], data)
            i = i + 1
        end
    end
    
    --
    -- Categories
    -- 
    
    local cats = {
        'Incursion rooms',
    }

    -- Attach to table
    mw.getCurrentFrame():expandTemplate{title = 'Template:Incursion room/cargo/incursion_rooms/attach'}
    
    --
    -- Done - output
    --
    
    return h.infocard(infocard_args) .. m_util.misc.add_category(cats)
end

local function _room_progression(args)
    --[[
    Displays a succession box of the rooms for one architect
    --]]

    args.page = args.page or mw.title.getCurrentTitle().prefixedText

    -- Query room
    local room = h.query_room(args)
    if room.error then
        room.error:throw()
    end

    -- Query room progression
    local results = m_cargo.query(
        {
            'incursion_rooms',
        },
        {
            'incursion_rooms._pageName=_pageName',
            'incursion_rooms.name=name',
            'incursion_rooms.tier=tier',
            'incursion_rooms.icon=icon',
            'incursion_rooms.architect_name=architect_name',
        },
        {
            where = string.format(
                'incursion_rooms.architect_metadata_id = "%s" AND incursion_rooms.tier > 0',
                room.architect_metadata_id
            ),
            groupBy = 'incursion_rooms._pageID',
            orderBy = 'incursion_rooms.tier ASC',
            limit = cfg.tier_max,
        }
    )
    if #results == 0 then
        error(i18n.errors.no_progression)
    end

    -- Build succession box
    local html = mw.html.create('table')
        :addClass('wikitable successionbox')
        :tag('tr')
            :tag('th')
                :attr('colspan', #results)
                :wikitext( m_util.html.wikilink(results[1].architect_name) )
                :done()
            :done()
    local row = html:tag('tr')
    for _, v in ipairs(results) do
        row:tag('td')
            :cssText('width: 33.3%')
            :wikitext(
                string.format(
                    '[[%s|160px|link=%s]] <br> %s. %s',
                    v.icon,
                    v._pageName,
                    i18n.tiers_roman[tonumber(v.tier)],
                    m_util.html.wikilink(v._pageName, v.name)
                )
            )
    end

    return tostring(html)
end

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

local p = {}

p.table_incursion_rooms = m_cargo.declare_factory{data=tables.incursion_rooms}

--
-- Template:Incursion room
-- 
p.incursion_room = m_util.misc.invoker_factory(_incursion_room, {
    wrappers = cfg.wrappers.incursion_room,
})

--
-- Template:Incursion room progression
-- 
p.room_progression = m_util.misc.invoker_factory(_room_progression, {
    wrappers = cfg.wrappers.room_progression,
})

return p