Borderlands Wiki
Advertisement
Borderlands Wiki
8066
страниц

Для документации этого модуля может быть создана страница Модуль:Element/doc

-- модуль выдачи стихийных шаблонов. см [[template:стихия]]
-- <pre>
local p = {}

-- data
local d = {
    -- список игр
    games = {
        ['borderlands'] = 'borderlands',
        ['borderlands 2'] = 'borderlands 2',
        ['borderlands: the pre-sequel'] = 'borderlands: the pre-sequel',
        ['borderlands 3'] = 'borderlands 3'
    },
    -- список стихий
    elements = {
        ['без стихии'] = 'без стихии',
        ['взрыв'] = 'взрыв',
        ['коррозия'] = 'коррозия',
        ['огонь'] = 'огонь',
        ['радиация'] = 'радиация',
        ['холод'] = 'холод',
        ['шлак'] = 'шлак',
        ['шок'] = 'шок',
        ['любая'] = 'любая',
        ['любая или без стихии'] = 'любая или без стихии',
        -- запятые будут удалены
        ['любая кроме взрыва'] = 'любая кроме взрыва',
        ['любая кроме взрыва или без стихии'] = 'любая кроме взрыва или без стихии'
    },
    -- данные по играм
    borderlands = {
        elements = {
            ['без стихии'] = 'без стихии',
            ['взрыв'] = 'взрыв',
            ['коррозия'] = 'коррозия',
            ['огонь'] = 'огонь',
            ['шок'] = 'шок',
            ['любая'] = { 'взрыв', 'коррозия', 'огонь', 'шок' },
            ['любая или без стихии'] = { 'без стихии', 'взрыв', 'коррозия', 'огонь', 'шок' },
            ['любая кроме взрыва'] = { 'коррозия', 'огонь', 'шок' },
            ['любая кроме взрыва или без стихии'] = { 'без стихии', 'коррозия', 'огонь', 'шок' }
        }
    },
    ['borderlands 2'] = {
        elements = {
            ['без стихии'] = 'без стихии',
            ['взрыв'] = 'взрыв',
            ['коррозия'] = 'коррозия',
            ['огонь'] = 'огонь',
            ['шок'] = 'шок',
            ['шлак'] = 'шлак',
            ['любая'] = { 'взрыв', 'коррозия', 'огонь', 'шок', 'шлак' },
            ['любая или без стихии'] = { 'без стихии', 'взрыв', 'коррозия', 'огонь', 'шок', 'шлак' },
            ['любая кроме взрыва'] = { 'коррозия', 'огонь', 'шок', 'шлак' },
            ['любая кроме взрыва или без стихии'] = { 'без стихии', 'коррозия', 'огонь', 'шок', 'шлак' },
            -- альтернативные стихии для разных игр
            -- игры обычно перечислены в порядке выхода
            --  теперь это должен быть единственно верный порядок
            ['шлак.borderlands: the pre-sequel'] = 'холод',
            ['шлак.borderlands 3'] = { 'холод', 'радиация' }
        },
        -- запрещённые элементы для типов снаряжения (нет щитов от шлака в бл2 и тп)
        -- массивы значений допускаются
        forbiddenElements = {
            ['щиты'] = 'шлак'
        }
    },
    ['borderlands: the pre-sequel'] = {
        elements = {
            ['без стихии'] = 'без стихии',
            ['взрыв'] = 'взрыв',
            ['коррозия'] = 'коррозия',
            ['огонь'] = 'огонь',
            ['шок'] = 'шок',
            ['холод'] = 'холод',
            ['любая'] = { 'взрыв', 'коррозия', 'огонь', 'шок', 'холод' },
            ['любая или без стихии'] = { 'без стихии', 'взрыв', 'коррозия', 'огонь', 'шок', 'холод' },
            ['любая кроме взрыва'] = { 'коррозия', 'огонь', 'шок', 'холод' },
            ['любая кроме взрыва или без стихии'] = { 'без стихии', 'коррозия', 'огонь', 'шок', 'холод' },
            -- альтернативные стихии для разных игр
            ['холод.borderlands 2'] = 'шлак',-- не должно быть использовано, тк поглощено на этапе бл2
            ['холод.borderlands 3'] = { 'холод', 'радиация' }
        }
    },
    ['borderlands 3'] = {
        elements = {
            ['без стихии'] = 'без стихии',
            ['взрыв'] = 'взрыв',
            ['коррозия'] = 'коррозия',
            ['огонь'] = 'огонь',
            ['шок'] = 'шок',
            ['холод'] = 'холод',
            ['радиация'] = 'радиация',
            ['любая'] = { 'взрыв', 'коррозия', 'огонь', 'шок', 'холод', 'радиация' },
            ['любая или без стихии'] = { 'без стихии', 'взрыв', 'коррозия', 'огонь', 'шок', 'холод', 'радиация' },
            ['любая кроме взрыва'] = { 'коррозия', 'огонь', 'шок', 'холод', 'радиация' },
            ['любая кроме взрыва или без стихии'] = { 'без стихии', 'коррозия', 'огонь', 'шок', 'холод', 'радиация' },
            -- альтернативные стихии для разных игр
            -- тк игры перечисляются в порядке выхода
            --  следующие привязки не должны быть использованы
            --  тк они уже должны быть обработаны предыдущими версиями (бл2 и тпс)
            --'холод.borderlands 2' = 'шлак',-- приведёт к двойному шлаку при холод + радиация
            ['радиация.borderlands 2'] = 'шлак',
            ['радиация.borderlands the pre-sequel'] = 'холод'
        }
    }
}

function getArgs(frame)
    -- собирает и нормализует аргументы
    -- возвращает таблицу вида {el: стихия, mainGame: основная игра, additionalGames: {игры}, t: тип}
    -- страховка для запуска из консоли (для отладки)
    if not frame.getParent then
        frame.getParent = function()end
    end
    local parent = frame:getParent() and frame:getParent() or frame
    local args = parent.args
    local ret = {}
    -- стихия
    ret.el = mw.ustring.lower(args['1'] or args[1] or '')
    -- удаление запятых из стихии
    ret.el = table.concat(mw.text.split(mw.text.trim(ret.el), ','))
    if #mw.text.trim(ret.el) == 0 then
        -- стихию не прислали
        ret.el = nil
    end
    -- основная игра (первая в списке параметров)
    ret.mainGame = mw.ustring.lower(args['2'] or args[2] or '')
    ret.mainGame = (#ret.mainGame > 0) and ret.mainGame or nil
    -- тип предмета
    ret.t = args['тип'] or ''
    ret.t = (#ret.t > 0) and ret.t or nil
    -- есть ли ещё параметры?
    if args['3'] or args[3] then
        ret.additionalGames = {}
        for i = 3, 10 do
            local game = mw.ustring.lower(args[tostring(i)] or args[i] or '')
            game = (#game > 0) and game or nil
            -- если параметр есть и совпадает с именем игры, то добавить его в список игр
            if game then
                -- копия аргументов для передачи в dpl для полного default'a
                --  эти аргументы не должны перебираться через ipairs, так непоследовательны
                --  номера элементов унаследованы от шаблона
                ret[i] = game
                if d.games[game] then-- это точно игра, добавить в корзину
                    table.insert(ret.additionalGames, game)
                end
            end
        end
    end
    return ret
end-- getArgs

function unique(t)
    -- удаляет из таблицы повторяющиеся записи
    local ret = {}
    local cache = {}
    for _, v in ipairs(t) do
        if not cache[v] then
            cache[v] = 1
            table.insert(ret, v)
        end
    end
    return ret
end-- unique

function p.isElementForbidden(element, typ, game)
    -- проверяет запрет стихии для типа предмета
    if (not element) or (not typ) or (not game) then
        return false
    end
    local fe = d[game].forbiddenElements[typ]
    if not fe then
        return false
    end
    fe = type(fe) == 'table' and fe or { fe }
    mw.log(element, typ, game, d[game].forbiddenElements)
    --if 1 then return end
    for _, el in pairs(fe) do
        if el == element then
            return true
        end
    end
    return false
end-- isElementForbidden

function p.t(name)
    -- возвращает {{name}}
    local ret = {}
    table.insert(ret, '{{')
    table.insert(ret, name)
    table.insert(ret, '}}')
    return table.concat(ret)
end-- t

function p.main(frame)
    local args = getArgs(frame)
    -- args.el: стихия
    -- args.mainGame: первая в списке игра
    -- args.additionalGames: список остальных игр (вторая и тд)
    -- args.t: тип предмета (щиты и тп)
    -- args[3] - args[10]: копия параметров для формирования умолчаний
    
    -- если стихии нет в списке стихий или не указана игра, то вывалиться в дефолт
    if (not d.elements[args.el or '']) or (not args.mainGame) then
        local default = {}
        table.insert(default, '{{#dpl:debug=0|allowcachedresults=1|mode=userformat|ordermethod=titlewithoutnamespace')
        table.insert(default, '|includesubpages=false|count=1|namespace={{!}}10{{!}}14|title=')
        table.insert(default, args.el or 'без стихии')
        table.insert(default, '|format=,{{:%PAGE%{{!}}')
        table.insert(default, args[5] or '')-- номера аргументов унаследованы от шаблона; зобыл, что они значат и где
        table.insert(default, '{{!}}')
        table.insert(default, args[6] or '')
        table.insert(default, '{{!}}')
        table.insert(default, args[7] or '')
        table.insert(default, ',|noresultsheader=')
        table.insert(default, args.el or '')
        table.insert(default, '}}')
        default = table.concat(default)
        return frame.preprocess and frame:preprocess(default) or default
    end-- default
    
    -- взять список стихий из d[игра].elements[стихия]
    -- пройтись по списку стихий
    --  подставить стихии, в том числе из других игр (с1 / с2),
    --      проверяя заигноренность (с учётом игры) типа* после того, как всё заработает
    --      подстановка стихий через отдельную таблицу
    --      вычистить повторы и собрать таблицу
    -- собрать вывод
    local ret = {}-- ret values
    
    local elements = d[args.mainGame].elements-- таблица стихий основной игры
    local element = elements[args.el]-- запрошенный элемент
    -- элемент может быть и списком элементов
    element = type(element) == 'table' and element or { element }
    -- пройтись по списку элементов и собрать их в кучу
    for _, elem in ipairs(element) do
        local elems = {}-- промежуточный список стихий
        -- если стихия разрешена в этой игре для этого типа предметов, то можно добавлять
        if not p.isElementForbidden(elem, args.t, args.mainGame) then
            elems = { p.t(elem) }
        end
        -- добавить стихии из других игр
        for _, game in ipairs(args.additionalGames or {}) do
            local e = elements[ elem .. '.' .. game ]-- замещающие стихии (холод для шлака и тп)
            if e then
                e = type(e) == 'table' and e or { e }
                -- добавить доп стихии
                for _, v in ipairs(e) do
                    -- добавлять только те стихии, что не запрещены
                    if not p.isElementForbidden(v, args.t, game) then
                        table.insert(elems,  p.t(v))-- здесь стихия превращается в шаблон
                    end
                end
            end
        end-- additionalGames
        -- убрать дубли (шлак+холод+радиация+холод)
        elems = unique(elems)
        -- если здесь много стихий из разных игр, то отформатировать: ( стихия / стихия )
        if #elems > 1 then
            elems = '( ' .. table.concat(elems, ' / ') .. ' )'
        else
            -- массив стихий может быть пустым, если стихия запрещена
            elems = #elems == 1 and elems[1] or ''
        end
        -- добавить стихию в выходной массив
        table.insert(ret, elems)
    end-- element
    ret = table.concat(ret, ' ')
    return frame.preprocess and frame:preprocess(ret) or ret
end-- main

return p
Advertisement