м (Страница «Модуль:UniverseData» защищена: популярная страница ([edit=autoconfirmed] (истекает 21:12, февраля 6, 2021 (UTC)) [move=autoconfirmed] (истекает 21:12, февраля 6, 2) |
(getCategories: Исправлены ошибки) |
||
Строка 81: | Строка 81: | ||
-- Выдает категории, соответствующие данному представителю лора игры |
-- Выдает категории, соответствующие данному представителю лора игры |
||
+ | -- Изменения в этой функции полноценное не обновляются на страницах |
||
+ | -- Для подтверждения изменений необходимо сделать нулевую правку с помощью бота |
||
function p.getCategories(frame) |
function p.getCategories(frame) |
||
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end |
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end |
||
local cData = require("Модуль:ChampionData") |
local cData = require("Модуль:ChampionData") |
||
⚫ | |||
− | local |
+ | local lorePiece = loreData[name] |
⚫ | |||
− | local t = loreData[args[1]] or loreData["Что-то пошло не так"] |
||
+ | return userError( |
||
− | local loretype = t.loretype or "Недостаточно информации" |
||
+ | 'Указанный объект лора не найден в Модуль:UniverseData/data', |
||
⚫ | |||
+ | 'LuaError') |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | local loretype = lorePiece.loretype |
||
⚫ | |||
⚫ | |||
⚫ | |||
+ | return userError( |
||
⚫ | |||
+ | 'Не указан тип лора для ' .. name .. 'Модуль:UniverseData/data', |
||
⚫ | |||
− | + | 'LuaError') |
|
+ | end |
||
− | s = s .. "[[Категория:Видеоролики АВ]]" |
||
+ | |||
⚫ | |||
⚫ | |||
+ | local count = 0 -- Счетчик для числа участвующих/упомянутых чемпионов (length не работает) |
||
+ | |||
+ | |||
+ | -- Костыль: Lua не воспринимает таблицы от loadData за последовательности, даже если они являются таковыми |
||
+ | local loreRegions = {} |
||
+ | if lorePiece.region then |
||
⚫ | |||
+ | table.insert(loreRegions, v) |
||
+ | end |
||
+ | end |
||
+ | |||
+ | -- Заносит названия категорий в таблицу, а в конце собирает её в строку |
||
+ | local categoryList = {} |
||
⚫ | |||
+ | |||
+ | -- Устаревший лор |
||
⚫ | |||
+ | table.insert(categoryList, "Устаревший лор") |
||
⚫ | |||
⚫ | |||
+ | -- Альтернативные вселенные |
||
⚫ | |||
+ | if loretype ~= "Вселенная" then |
||
+ | table.insert(categoryList, mw.ustring.format( |
||
+ | "%s альтернативных вселенных", |
||
⚫ | |||
+ | ) |
||
else |
else |
||
⚫ | |||
⚫ | |||
end |
end |
||
+ | table.insert(categoryList, lorePiece.au) |
||
else |
else |
||
+ | -- Если указан регион (только для основной вселенной) |
||
⚫ | |||
− | + | if #loreRegions > 0 then |
|
− | + | for i, region in ipairs(loreRegions) do |
|
+ | table.insert(categoryList, "Лор " .. _regionGenitive(region)) |
||
end |
end |
||
else |
else |
||
− | + | table.insert(categoryList, "Лор Рунтерры") |
|
end |
end |
||
− | + | -- Категория по типу лора |
|
+ | table.insert(categoryList, _loretypePlural(loretype)) |
||
⚫ | |||
end |
end |
||
+ | -- Чемпионы |
||
for i, champion in pairs(starring) do |
for i, champion in pairs(starring) do |
||
− | + | table.insert(categoryList, "Лор " .. cData.get{champion, "genitive"}) |
|
count = count + 1 |
count = count + 1 |
||
end |
end |
||
for i, champion in pairs(mentioned) do |
for i, champion in pairs(mentioned) do |
||
− | + | table.insert(categoryList, "Лор " .. cData.get{champion, "genitive"}) |
|
end |
end |
||
if count == 0 then |
if count == 0 then |
||
− | + | table.insert(categoryList, "Лор без чемпионов") |
|
end |
end |
||
end |
end |
||
− | + | for i, v in ipairs(categoryList) do |
|
⚫ | |||
+ | end |
||
+ | |||
+ | result = result .. table.concat(categoryList, "\r\n") |
||
+ | |||
+ | return result |
||
end |
end |
||
Строка 910: | Строка 950: | ||
end |
end |
||
− | -- Выдает множественное число из списка, |
+ | -- Выдает множественное число из списка, иначе просто возвращает аргумент |
-- В Lua нет switch/case!!! |
-- В Lua нет switch/case!!! |
||
function _loretypePlural(ltype) |
function _loretypePlural(ltype) |
||
⚫ | |||
local loretypePlurals = { |
local loretypePlurals = { |
||
− | + | ['Биография'] = "Биографии", |
|
− | + | ['Видео'] = "Видеоролики", |
|
− | + | ['Комикс'] = "Комиксы", |
|
− | + | ['Рассказ'] = "Рассказы", |
|
− | + | ['Территории']= "Территории", |
|
− | + | ['Фракция'] = "Фракции", |
|
− | + | ['Клип'] = "Клипы", |
|
+ | ['Вселенная'] = "Альтернативная вселенная", |
||
− | {"Music Video", "Клипы"}, |
||
⚫ | |||
} |
} |
||
+ | |||
⚫ | |||
− | + | if loretypePlurals[ltype] then |
|
+ | return loretypePlurals[ltype] |
||
end |
end |
||
Версия от 12:27, 7 августа 2020
Данный набор модулей используется для хранения и выдачи информации о лоре League of Legends и альтернативных вселенных.
Список модулей
- Модуль:UniverseData - основные функции обработки
- Модуль:UniverseData/data - список произведений по вселенной (рассказы, комиксы, видео и т.д.)
- Модуль:UniverseData/getter - геттер данных
- Модуль:UniverseData/skinlines - список линеек образов
- Модуль:UniverseData/au - список альтернативных вселенных игры
-- <pre>
local p = {}
local loreData = mw.loadData('Модуль:UniverseData/data')
local lib = require('Модуль:Feature')
local FN = require('Модуль:Filename')
local IL = require('Модуль:ImageLink')
local skinData = require('Модуль:SkinData/data')
local userError = require('Dev:User error')
function p.get(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local get = require ('Module:UniverseData/getter')
local champname = args['champname'] or args[1]
local datatype = args['datatype'] or args[2]
local output = args['output'] or args[3] or nil
local result = get[datatype](champname)
if output ~= nil and type(result) == "table" then
if output == "csv" then
return lib.tbl_concat{result}
elseif output == "custom" then
return frame:preprocess(lib.tbl_concat({result, prepend = args['prepend'], append = args['append'], separator = args['separator'], index = args["index"]}))
elseif output == "template" then
return frame:preprocess(lib.tbl_concat{result, prepend = "{{" .. args['t_name'] .. "|", append = "}}", separator = args['separator']})
end
elseif result == nil then
return ""
else
return result
end
end
function p.loreTemplate()
local loreList = mw.html.create('ul')
local lore = {}
for x in pairs(loreData) do
table.insert(lore, x)
end
table.sort(lore)
for _, piece in pairs(lore) do
local t = loreData[piece]
local link = piece
local name = piece
local loretype = t.loretype or "N/A"
local starring = t.starring
local entry = ''
if starring then
entry = '[[' .. link .. '|' .. name .. ']] <small>('.. getChampions(starring) ..')</small>'
else
entry = '[[' .. link .. '|' .. name .. ']]'
end
if loretype == "Рассказ" then
loreList
:tag('li')
:tag('div')
:wikitext(entry)
:done()
:done()
:newline()
end
end
return loreList
end
function p.getBanner(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
return _bannerNew(args[1])
end
-- Выдает категории, соответствующие данному представителю лора игры
-- Изменения в этой функции полноценное не обновляются на страницах
-- Для подтверждения изменений необходимо сделать нулевую правку с помощью бота
function p.getCategories(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local cData = require("Модуль:ChampionData")
local name = args['lore'] or args[1]
local lorePiece = loreData[name]
if lorePiece == nil then
return userError(
'Указанный объект лора не найден в Модуль:UniverseData/data',
'LuaError')
end
local loretype = lorePiece.loretype
if loretype == nil then
return userError(
'Не указан тип лора для ' .. name .. 'Модуль:UniverseData/data',
'LuaError')
end
local starring = lorePiece.starring or {}
local mentioned = lorePiece.mentioned or {}
local count = 0 -- Счетчик для числа участвующих/упомянутых чемпионов (length не работает)
-- Костыль: Lua не воспринимает таблицы от loadData за последовательности, даже если они являются таковыми
local loreRegions = {}
if lorePiece.region then
for k, v in pairs(lorePiece.region) do
table.insert(loreRegions, v)
end
end
-- Заносит названия категорий в таблицу, а в конце собирает её в строку
local categoryList = {}
local result = ""
-- Устаревший лор
if lorePiece.outdated then
table.insert(categoryList, "Устаревший лор")
result = result .. "{{Устаревший лор}}"
else
-- Альтернативные вселенные
if lorePiece.au then
if loretype ~= "Вселенная" then
table.insert(categoryList, mw.ustring.format(
"%s альтернативных вселенных",
_loretypePlural(loretype))
)
else
table.insert(categoryList, "Альтернативная вселенная")
end
table.insert(categoryList, lorePiece.au)
else
-- Если указан регион (только для основной вселенной)
if #loreRegions > 0 then
for i, region in ipairs(loreRegions) do
table.insert(categoryList, "Лор " .. _regionGenitive(region))
end
else
table.insert(categoryList, "Лор Рунтерры")
end
-- Категория по типу лора
table.insert(categoryList, _loretypePlural(loretype))
end
-- Чемпионы
for i, champion in pairs(starring) do
table.insert(categoryList, "Лор " .. cData.get{champion, "genitive"})
count = count + 1
end
for i, champion in pairs(mentioned) do
table.insert(categoryList, "Лор " .. cData.get{champion, "genitive"})
end
if count == 0 then
table.insert(categoryList, "Лор без чемпионов")
end
end
for i, v in ipairs(categoryList) do
categoryList[i] = mw.ustring.format("[[Категория:%s]]", v)
end
result = result .. table.concat(categoryList, "\r\n")
return result
end
function p.getAuthor(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
return loreData[args[1]].author or "Неизвестен"
end
function p.getAuthorlist(frame)
local authors = {}
local hash = {}
local authorList = mw.html.create('ul')
authorList:newline()
for _, x in pairs(loreData) do
if x.author ~= nil then
if type(x.author) == "table" then
for _, value in pairs(x.author) do
if (not hash[value]) then
table.insert(authors, value)
hash[value] = true
end
end
else
if (not hash[x.author]) then
table.insert(authors, x.author)
hash[x.author] = true
end
end
end
end
table.sort(authors)
for _, author in pairs(authors) do
authorList
:tag('li')
:wikitext('[[' .. author .. ']]')
:done()
:done()
:newline()
end
return authorList
end
function p.getLorelist(frame)
local loreList = mw.html.create('ul')
local lore = {}
for x in pairs(loreData) do
table.insert(lore, x)
end
table.sort(lore)
for _, piece in pairs(lore) do
local t = loreData[piece]
local link = piece
local name = piece
local loretype = t.loretype or "N/A"
if loretype == "Biography" or loretype == "Биография" then
link = t.starring[1]
end
loreList
:tag('li')
:tag('div')
:wikitext('[[' .. link .. '|' .. name .. ']] ('.. loretype ..')')
:done()
:done()
:newline()
end
return loreList
end
-- Выдает в форме баннеров объекты лора, связанные с указанным чемпионом/персонажем
function p.getMore(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local champion = args[1]
local loreList = ""
local mentionedList = ""
local auList = ""
local lore = {}
for x in pairs(loreData) do
table.insert(lore, x)
end
table.sort(lore)
loreList = loreList .. "<h3>Подробнее о чемпионе</h3>"
for _, piece in pairs(lore) do
local hit = false
local t = loreData[piece]
if t.starring ~= nil and t.loretype ~= "Биография" and t.loretype ~= "Фракция" and t.loretype ~= "Территория" and t.outdated ~= true then
for _, substarring in pairs(t.starring) do
if substarring == champion then
hit = true
end
end
end
if hit == true then
if not(t.au) then
loreList = loreList .. _bannerNew(piece)
else
auList = auList .. _bannerNew(piece)
end
end
end
for _, piece in pairs(lore) do
local hit = false
local t = loreData[piece]
if t.mentioned ~= nil then
for _, submentioned in pairs(t.mentioned) do
if submentioned == champion then
hit = true
end
end
end
if hit == true then
if not(t.au) then
mentionedList = mentionedList .. _bannerNew(piece)
else
auList = auList .. _bannerNew(piece)
end
end
end
if mentionedList ~= "" then
loreList = loreList .. "\n<div class='va-collapsible-content mw-collapsible mw-collapsed' data-expandtext='Показать' data-collapsetext='Скрыть'><h3>Упоминается</h3><div class='va-collapsible-content mw-collapsible-content'>" .. mentionedList .. "</div>"
end
if auList ~= "" then
loreList = loreList .. "\n<div class='va-collapsible-content mw-collapsible mw-collapsed' data-expandtext='Показать' data-collapsetext='Скрыть'><h3>Альтернативная вселенная</h3><div class='va-collapsible-content mw-collapsible-content'>" .. auList .. "</div>"
end
return loreList
end
function p.getRegionlore(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local loreList = ""
local lore = {}
local result = false
for x in pairs(loreData) do
table.insert(lore, x)
end
table.sort(lore)
for _, piece in pairs(lore) do
local hit = false
local t = loreData[piece]
if (t.region ~= nil) then
if type(t.region) == "table" then
for _, subregion in pairs(t.region) do
if subregion == args[1] then
hit = true
result = true
end
end
else
if t.region == args[1] then
hit = true
result = true
end
end
else
if args[1] == "Рунтерра" then
hit = true
result = true
end
end
if hit == true then
loreList = loreList .. _bannerNew(piece, t)
end
end
if result == false then
loreList = "No match found for " .. args[1] .. "."
end
return loreList .. "[[Category:Test]]"
end
-- Выдает галерею загрузочных иллюстраций чемпионов, принадлежащик к указанной фракции
function p.getRegionExhibition(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local IL = require('Модуль:ImageLink')
local isList = args['islist'] or "false"
local result = ""
if(isList ~= "false") then
local championList = args['list'] or args[1]
championList = mw.text.split(championList, '[,;]%s*')
for i, v in ipairs(championList) do
result = result .. tostring(IL.loading({
['champion'] = v,
['display'] = 'inline-grid',
['labelstyle'] = "background-color:black; text-align:center; padding:2px 0;"
}))
end
return result
end
local region = args['region'] or args[1]
local champions = loreData[region].starring
table.sort(champions)
for _, v in pairs(champions) do
result = result .. tostring(IL.loading({
['champion'] = v,
['display'] = 'inline-grid',
['labelstyle'] = "background-color:black; text-align:center; padding:2px 0;"
}))
end
return result
end
function p.getSkinlineBanner(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local skinlines = mw.loadData('Модуль:UniverseData/skinlines')
local sLineName = args['skinline'] or args[1]
local sLine = skinlines[sLineName]
-- Если линейки нет
if sLine == nil then
return userError('Линейка образов не найдена', 'LuaError')
end
-- Костыль: Lua не считает таблицы, переданные через mw.loadData за последовательности, даже если они считаются таковыми
local authorTable = {}
if(sLine.author) then
for i, v in pairs(sLine.author) do
table.insert(authorTable, v)
end
end
-- Контейнер баннера
local bannerNode = mw.html.create('div')
bannerNode
:attr('id', 'champinfo-container')
:cssText("width:100%; min-height: 290px; overflow:hidden; position:relative; font-size:14px; color: #dddddd; display:flex")
:done()
-- Блок изображения
local imageNode = mw.html.create('div')
imageNode
:addClass('FillImage')
:cssText("width:100%; height:100%; position:absolute; top: 0; left:0; opacity:0.2; z-index: -1")
:wikitext(mw.ustring.format("[[File:%s|link=]]", sLine.artwork))
:newline()
-- Ссылки на редактирование
local editNode = mw.html.create('div')
editNode
:cssText("position: absolute; top: 0.1em; right: 1em; font-size:85%;")
:tag('span')
:addClass('plainlinks')
:wikitext("[https://leagueoflegends.fandom.com/ru/wiki/Модуль:UniverseData/skinlines?action=edit Ред.]")
:done()
:wikitext(" • [[:File:" .. sLine.artwork .. "|Изобр.]]")
:done()
if(sLine.reference) then
editNode:wikitext(" • [" .. sLine.reference.. " Ссылка]")
end
editNode:newline()
-- Блок ID
local idNode = mw.html.create('div')
if(sLine.id) then
idNode
:cssText("position: absolute; left: 1em; top:0.1em; font-size:70%;")
:wikitext(sLine.id)
:done()
bannerNode:node(idNode)
end
-- Текст
local contentNode = mw.html.create('div')
contentNode
:cssText("text-align:center; width: 500px; margin:auto")
:newline()
local titleNode = mw.html.create('div')
-- Текст: общий заголовок
titleNode
:css('margin', '3em 0')
:tag('p')
:css('margin-top', '1em')
:wikitext('Набор образов')
:done()
:tag('p')
:attr('id', 'title')
:cssText("font-size:250%; line-height:100%; margin:0;color:#c9aa71")
:wikitext("[[" .. sLineName .. "]]")
:done()
:newline()
-- Текст: Является частью альтернативной вселенной?
if(sLine.au) then
titleNode
:tag('p')
:css('margin-top', '1em')
:wikitext(mw.ustring.format("Вселенная: [[%s]]", sLine.au))
:done()
:newline()
end
-- Текст: Авторы
if(sLine.author) then
titleNode
:tag('p')
:css('margin-top', '-1em')
:wikitext(mw.ustring.format("%s: %s",
lib.ternary(#authorTable == 1, "Автор", "Авторы"),
mw.text.listToText(authorTable, ", ")
))
:done()
:done()
end
-- Текст: Представленные чемпионы
titleNode
:tag('p')
:attr('id', 'featured')
:css('margin-top', '1em')
:wikitext("Представители: " .. getChampions(sLine.starring))
:done()
:newline()
contentNode:node(titleNode)
-- Сборка
bannerNode
:node(imageNode)
:node(editNode)
:node(contentNode)
return tostring(bannerNode)
end
function p.getSkinlineCategories(frame)
-- TODO
end
function p.getSkinlineDescription(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local champion = args['champion'] or args[1]
champion = lib.validateName(champion)
local skin = args['skin'] or args[2] or "Классический"
local isListItem = args['li']
if(champion == nil) then
return userError('Не указан чемпион', 'LuaError')
end
if(skin == "Классический" or skin == "Классическая") then return end
local skinlineData = mw.loadData('Модуль:UniverseData/skinlines')
local auData = mw.loadData('Модуль:UniverseData/au')
local setName = skinData[champion]['skins'][skin]['set']
if(setName == nil) then return end
if(skinlineData[setName[1]] == nil) then
return userError(
'Линейка образов ' .. setName[1] .. ' не найдена в Модуль:UniverseData/skinlines',
'LuaError')
end
-- Построение фразы типа:
-- "Этот образ в ходит в линейку образов K/DA, которая является частью вселенной Музыкальные образы"
local s = mw.ustring.format("Этот образ входит в линейку образов [[%s]]", setName[1])
if(skinlineData[setName[1]].au) then
s = s .. " из вселенной [[" .. skinlineData[setName[1]].au .. "]]"
end
s = s .. "."
-- Все остальные чемпионы из этой линейки
local skinlineChampions = {}
for i, v in pairs(skinlineData[setName[1]].starring) do
table.insert(skinlineChampions, v)
end
-- Список пар чемпион-образ из этой линейки
local csPairs = {} -- csPairs = champion-skin pairs
for i, slChampion in ipairs(skinlineChampions) do
-- Найти все входящие в линейку пары "чемпион-образ"
local currentPairs = _findSkinforSet(slChampion, setName[1])
-- исключить добавление пустой пары
if(#currentPairs > 0) then
for j, pairValue in ipairs(currentPairs) do
if(slChampion ~= champion or pairValue[2] ~= skin) then
table.insert(csPairs, pairValue)
end
end
end
end
s = s .. " В эту линейку также входят:"
local listNode = mw.html.create('ul')
if(#csPairs > 5) then -- Если больше 5 образов, то разбить на колонки
listNode
:addClass('columntemplate')
:cssText("-moz-column-count:2; -webkit-column-count:2; column-count:2")
end
for i, v in ipairs(csPairs) do
listNode
:tag('li')
:wikitext(tostring(IL.skin{
["champion"] = v[1],
["skin"] = v[2],
["link"] = v[1] .. "/Образы",
["circle"] = "true"
}))
:newline()
:done()
end
-- Если нужно сделать частью общего маркированного списка
local textNode = mw.html.create('ul')
if(isListItem) then
textNode
:tag('li')
:wikitext(s)
:newline()
:node(listNode)
:done()
:done()
return tostring(textNode)
end
return s .. tostring(listNode)
end
-- local functions
function _banner(name)
local piece = loreData[name] or loreData["Что-то пошло не так"]
local s = ""
local lang = mw.language.new("ru")
local bName = piece.displayname or name
local artwork = piece.artwork or "Bard promo 2.jpg"
local author = piece.author or "неизвестен"
local reference = piece.reference or "https://universe.leagueoflegends.com/ru_RU/"
local link = name
local region = "Рунтерра"
local duration = piece.duration or "0"
local starring = "N/A"
local mentioned = "N/A"
local canon = piece.outdated or ""
local loretype = piece.loretype or ""
local description = piece.description or ""
if loretype == "Биография" then link = piece.starring[1] end
if piece.region ~= nil then region = piece.region[1] end
if piece.starring ~= nil then starring = getChampions(piece.starring) end
if piece.mentioned ~= nil then mentioned = getChampions(piece.mentioned) end
s = s .. "<div id='champinfo-container' style='width:100%; min-height: 290px; overflow:hidden; position:relative; font-size:14px; color: #dddddd; display:flex;'>"
--image
s = s .. "<div class='FillImage' style='width:100%; height:100%; position:absolute; top: 0; left:0; opacity:0.2; z-index: -1;'>[[File:" .. artwork .."|link=]]</div>"
--/image
--edit
s = s .. "<sup style='position: absolute; top: 1em; right: 1em;'><span class='plainlinks'>[https://leagueoflegends.fandom.com/ru/wiki/Модуль:UniverseData/data?action=edit Ред.]</span> • [[:File:" .. artwork .."|Изобр.]] • [" .. reference.. " Ссылка]</sup>"
--/edit
--content
s = s .. "<div style='text-align:center; width: 500px; margin:auto;'><div style='margin:3em 0'>"
s = s .. "<p id='title' style='margin:1em 0 1em 0;'>[[File:" .. region .. " Герб иконка.png|x56px|link=" .. region .."]]</p>"
if loretype == "Рассказ" then
if duration == "0" then
s = s .. "<p id='duration' style='margin:1em 0 0 0;'> Рассказ </p>"
else
s = s .. "<p id='duration' style='margin:1em 0 0 0;'> Рассказ • На " .. duration .. " " .. lang:convertPlural(duration, 'минута', 'минуты', 'минут') .. " </p>"
end
else
s = s .. "<p id='duration' style='margin:1em 0 0 0;'>" .. loretype .. "</p>"
end
if piece.previous ~= nil then
s = s .. "<div style='position: absolute; top: 50%; left:1em; font-size:3em;'>[[" .. piece.previous .. "|◄]]</div>"
end
s = s .. "<p id='title' style='font-size:250%; line-height:100%; margin:0;color:#c9aa71;'>[[" .. link .. "|" .. bName .."]]</p>"
if loretype ~= "Видео" then
s = s .. "<p id='duration' style='margin:0 0 1em 0;'> "
if type(author) == "table" then
s = s .. "Авторы: "
for i, value in ipairs(author) do
if i ~= 1 then
s = s .. ", "
end
s = s .. value
end
else
s = s .. "Автор: " .. author
end
s = s .. "</p>"
end
if piece.following ~= nil then
s = s .. "<div style='position: absolute; top: 50%; right: 1em; font-size:3em;'>[[" .. piece.following .. "|►]]</div>"
end
if loretype ~= "Биография" then
s = s .. "<p id='blurb' style='margin:1em 0 1em 0; font-size: 89%; text-transform: initial;'>" .. description:gsub("//n", "<br/>") .."</p>"
end
if starring ~= nil and loretype ~= "Биография" then
s = s .. "<p id='featured' style='margin:0 0 1em 0;'>"
if loretype == "Фракция" or loretype == "Территория" then
s = s .. "Представители: "
else
s = s .. "Действующие лица: "
end
s = s .. starring .. "</p>"
end
if mentioned ~= "N/A" then
s = s .. "<p id='featured' style='margin:0 0 1em 0;'>Упоминаются: " .. mentioned .. "</p>"
end
s = s .. "</div></div>"
--/content
s = s .. "</div>"
return s
end
function _bannerNew(name)
local lorePiece = loreData[name] or loreData["Что-то пошло не так"]
local lang = mw.language.new('ru')
local bName = lorePiece.displayname or name
local artwork = lorePiece.artwork or "Bard promo 2.jpg"
local author = lorePiece.author or {"неизвестен"}
local reference = lorePiece.reference or "https://universe.leagueoflegends.com/ru_RU/"
local link = name
local region = "Рунтерра"
local duration = lorePiece.duration or "0"
local starring = "N/A"
local mentioned = "N/A"
local canon = lorePiece.outdated or ""
local loretype = lorePiece.loretype or ""
local description = lorePiece.description or ""
local au = lorePiece.au or "Рунтерра"
if loretype == "Биография" then link = lorePiece.starring[1] end
if type(author) == "string" then author = {author} end
if lorePiece.region ~= nil then region = lorePiece.region[1] end
if lorePiece.starring ~= nil then
starring = getChampions(lorePiece.starring)
elseif au ~= "Рунтерра" then
starring = getChampions(_mergeSkinlines(au))
end
if lorePiece.mentioned ~= nil then mentioned = getChampions(lorePiece.mentioned) end
--flag tables - для более быстрого поиска совпадений
local restrictAuthors = { -- Не показывать блок "Авторы"
["Видео"] = true,
["Вселенная"] = true,
["Аудиоспектакль"] = true,
["Территория"] = true,
["Фракция"] = true,
}
local starringTable = { -- Не "Действующие лица" для некоторых типов лора
["Вселенная"] = "Представители",
["Территория"] = "Представители",
["Фракция"] = "Представители",
}
local bannerNode = mw.html.create('div')
bannerNode
:attr('id', 'champinfo-container')
:cssText("width:100%; min-height: 290px; overflow:hidden; position:relative; font-size:14px; color: #dddddd; display:flex")
:newline()
:done()
-- Блок изображения
local imageNode = mw.html.create('div')
imageNode
:addClass('FillImage')
:cssText("width:100%; height:100%; position:absolute; top: 0; left:0; opacity:0.2; z-index: -1")
:wikitext(mw.ustring.format("[[File:%s|link=]]", artwork))
:newline()
-- Ссылки на редактирование
local editNode = mw.html.create('div')
editNode
:cssText("position: absolute; top: 0.1em; right: 1em; font-size:85%;")
:tag('span')
:addClass('plainlinks')
:wikitext("[https://leagueoflegends.fandom.com/ru/wiki/Модуль:UniverseData/data?action=edit Ред.]")
:done()
:wikitext(mw.ustring.format(
" • [[:File:%s|Изобр.]] • [%s Ссылка]",
artwork,
reference))
:newline()
:done()
-- Текст
local contentNode = mw.html.create('div')
contentNode
:cssText("text-align:center; width: 500px; margin:auto")
:newline()
:done()
local titleNode = mw.html.create('div')
-- Текст: иконка региона
titleNode
:css('margin', '3em 0')
:tag('p')
:attr('id', 'title')
:css('margin', '1em 0')
:wikitext(mw.ustring.format(
"[[File:%s|x56px|link=%s]]",
FN.faction{['faction'] = region},
region))
:done()
:newline()
-- Текст: Типа лора (для рассказа - указать длительность)
if(loretype == "Рассказ" and duration ~= "0") then
titleNode
:tag('p')
:attr('id', 'duration')
:css('margin-top', '1em')
:wikitext(mw.ustring.format(
"Рассказ • На %d %s",
duration,
lang:convertPlural(duration, 'минута', 'минуты', 'минут')))
:done()
:newline()
else
titleNode
:tag('p')
:attr('id', 'duration')
:css('margin-top', '1em')
:wikitext(loretype)
:done()
:newline()
end
-- Текст: Название лора
titleNode
:tag('p')
:attr('id', 'title')
:cssText("font-size:250%; line-height:100%; margin:0; color:#c9aa71")
:wikitext("[[" .. bName .. "]]")
:done()
:newline()
-- Текст: Вселенная
if(au ~= "Рунтерра" and loretype ~= "Вселенная") then
titleNode
:tag('p')
:css('margin-top', '1em')
:wikitext(mw.ustring.format("Вселенная: [[%s]]", au))
:done()
:newline()
end
-- Текст: Авторы
if(not(restrictAuthors[loretype])) then
if(author[1] == "Numerous creators") then
titleNode
:tag('p')
:css('margin-top', '-1em')
:wikitext("Несколько авторов")
:done()
:done()
else
titleNode
:tag('p')
:css('margin-top', '1em')
:wikitext(mw.ustring.format("%s: %s",
lib.ternary(#author == 1, "Автор", "Авторы"),
mw.text.listToText(author, ", ")
))
:done()
:done()
end
end
-- Текст: Представленные чемпионы
if(starring ~= "N/A") then
titleNode
:tag('p')
:attr('id', 'featured')
:css('margin-top', '1em')
:wikitext(
mw.ustring.format("%s: %s",
lib.ternary(starringTable[loretype], "Представители", "Действующие лица"),
starring))
:done()
:newline()
end
-- Текст: Упоминаемые чемпионы
if(mentioned ~= "N/A") then
titleNode
:tag('p')
:attr('id', 'featured')
:css('margin-top', '1em')
:wikitext(
mw.ustring.format("%s: %s",
"Упоминаются",
mentioned))
:done()
:newline()
end
contentNode:node(titleNode)
-- Стрелки
local previousNode
if(lorePiece.previous) then
previousNode = mw.html.create('div')
previousNode
:cssText("position: absolute; top: 50%; left:1em; font-size:3em;")
:wikitext("[[" .. lorePiece.previous .. "|◄]]")
:newline()
:done()
bannerNode:node(previousNode)
end
local followingNode
if(lorePiece.following) then
followingNode = mw.html.create('div')
followingNode
:cssText("position: absolute; top: 50%; right: 1em; font-size:3em;")
:wikitext("[[" .. lorePiece.following .. "|►]]")
:newline()
:done()
bannerNode:node(followingNode)
end
-- Сборка
bannerNode
:node(imageNode)
:node(editNode)
:node(contentNode)
:done()
return tostring(bannerNode)
end
--[[
========================
Приватные функции модуля
========================
]]
function getChampions(t)
local s = ""
local championtable = {}
for i, champion in pairs(t) do
table.insert(championtable, champion)
end
table.sort(championtable)
for i, champion in pairs(championtable) do
if i ~= 1 then
s = s .. ", "
end
s = s .. "<span style='white-space:nowrap'>[[File:" .. champion .. " OriginalSquare.png|20px|link=" .. champion .. "]] [[" .. champion .. "]]</span>"
end
return s
end
-- Выдает множественное число из списка, иначе просто возвращает аргумент
-- В Lua нет switch/case!!!
function _loretypePlural(ltype)
local loretypePlurals = {
['Биография'] = "Биографии",
['Видео'] = "Видеоролики",
['Комикс'] = "Комиксы",
['Рассказ'] = "Рассказы",
['Территории']= "Территории",
['Фракция'] = "Фракции",
['Клип'] = "Клипы",
['Вселенная'] = "Альтернативная вселенная",
}
if loretypePlurals[ltype] then
return loretypePlurals[ltype]
end
return ltype
end
-- Возвращает название региона в родительном падеже
function _regionGenitive(region)
if region == "Бандл сити" then
return region
elseif region == "Сумрачные острова" then
return "Сумрачных островов"
end
local lastLetter = mw.ustring.sub(region, -1)
if lastLetter == "я" then
return mw.ustring.sub(region, 0, -2) .. "и" -- Демасия - Демасии
elseif lastLetter == "а" then
return mw.ustring.sub(region, 0, -2) .. "ы" -- Бездна - Бездны
elseif lastLetter == "ь" then
return mw.ustring.sub(region, 0, -2) .. "я" -- Ишталь - Ишталя
end
return region .. "а"
end
-- Находит образ чемпиона, принадлежащий указанной линейке (если есть)
-- Принимает на вход имя чемпиона и название линейки образов
-- На выходе дает таблицу всех подходящих образов (в т.ч. Престижные и парные)
function _findSkinforSet(champion, set)
if(skinData[champion] == nil) then return {} end
local allSkins = skinData[champion].skins
local result = {}
for skinKey, skinValue in pairs(allSkins) do
if(skinValue.set) then
if(type(skinValue.set) == "table") then
for setKey, setValue in pairs(skinValue.set) do
if(setValue == set) then
table.insert(result, {champion, skinKey})
end
end
elseif(type(skinValue.set) == "string") then
if(skinValue.set == set) then
table.insert(result, {champion, skinKey})
end
end
end
end
return result
end
-- Собирает в одну последовательность всех чемпионов из одной вселенной
-- (если эта вселенная содержит несколько линеек образов)
function _mergeSkinlines(universe)
local auData = mw.loadData('Модуль:UniverseData/au')
local slData = mw.loadData('Модуль:UniverseData/skinlines')
local fetchedLines = auData[universe]
if(fetchedLines == nil) then
return userError([[
Ошибка при соединении линеек образов. Проверьте, дано ли соответсвие "Вселенная"-"линейки образов" в Модуль:UniverseData/au для
]] .. universe, 'LuaError')
end
-- Костыль: Lua не воспринимает таблицы из mw.loadData за последовательности, даже если они являются таковыми
local skinlines = {}
for k, v in pairs(fetchedLines) do
table.insert(skinlines, v)
end
local championsOfUniverse = {}
for i, skinline in ipairs(skinlines) do
local champions = slData[skinline].starring
for k, champOfSkinline in pairs(champions) do
if(lib.find(championsOfUniverse, champOfSkinline) == -1) then
table.insert(championsOfUniverse, champOfSkinline)
end
end
end
return championsOfUniverse
end
return p
-- </pre>
-- [[Category:Lua]]