Для документации этого модуля может быть создана страница Модуль: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