Модуль:Участник:BabylonAS/Nova/Инвентарный слот

В данном тестовом модуле проводится попытка бэкпортирования части функционала новой версии модуля Инвентарный слот в код старой версии. Это совершается с целью упрощения перехода на новую версию модуля.

------------------------------------------------------------------- --- Модуль для отображения инвентарных слотов в Minecraft Wiki. ------------------------------------------------------------------- local p = {} -- Список приставок к названиям, обрабатываемых другими модулями. -- Так будет легче, например, убирать их из целей ссылок. -- ВНИМАНИЕ: указывайте все варианты склонения по родам и числам. p.prefixes = { 'Любой', 'Любая', 'Любое', 'Любые', 'Повреждённый', 'Повреждённая', 'Повреждённое', 'Повреждённые' -- использование Ё обязательно } p.modAliases = mw.loadData("Модуль:Модификации") -- Служебная функция: Разбор строки, разделённой точками с запятой function p.splitOnUnenclosedSemicolons(text) local semicolon, lbrace, rbrace = (";[]"):byte(1, 3) local nesting = false local splitStart = 1 local frameIndex = 1 local frames = {} for index = 1, text:len() do local byte = text:byte(index) if byte == semicolon and not nesting then frames[frameIndex] = text:sub(splitStart, index - 1) frameIndex = frameIndex + 1 splitStart = index + 1 elseif byte == lbrace then assert(not nesting, "Ошибка синтаксиса: чрезмерные квадратные скобки") nesting = true elseif byte == rbrace then assert(nesting, "Ошибка синтаксиса: несбалансированные квадратные скобки") nesting = false end end assert(not nesting, "Ошибка синтаксиса: несбалансированные квадратные скобки") frames[frameIndex] = text:sub(splitStart, text:len()) for index = 1, #frames do frames[index] = (frames[index]:gsub("^%s+", ""):gsub("%s+$", "")) -- faster mw.text.trim end return frames end --- Создание слота function p.slot(f) --- Получение аргументов local args = f.args or f if f == mw.getCurrentFrame() and args[1] == nil then args = f:getParent().args end -- Первый аргумент args[1] = mw.text.trim(args[1] or '') --- Псевдонимы оригинальной игры local aliases = mw.loadData('Модуль:Инвентарный слот/Псевдонимы') --- Проверка и замена всех фреймов на псевдонимы local frames = {} for _, frame in ipairs(p.splitOnUnenclosedSemicolons(args[1])) do local frameParts = p.getParts( frame, args["мод"] ) local id = frameParts.name -- if frameParts.mod then --id = frameParts.mod .. ':' .. id -- end --- Загрузка списка псевдонимов к модам local modAliases if frameParts.mod then if mw.title.new('Модуль:ИнвСпрайт/' .. frameParts.mod).exists then modAliases = mw.loadData('Модуль:ИнвСпрайт/' .. frameParts.mod)["настройки"]["модпсевдонимы"] if modAliases and mw.title.new('Модуль:' .. modAliases).exists then modAliases = mw.loadData('Модуль:' .. modAliases) end end end local alias = nil if frameParts.mod then if modAliases and modAliases[id] then --- псевдонимы следует прописывать в модуле в формате ['имя'] = '[титл]:имя[доп. текст]', титл и доп.текст необязательно указывать local title = mw.ustring.match ( modAliases[id], '^%[([^%]]+)%]' ) if title then local aaa = mw.ustring.match ( modAliases[id], '^%[[^%]]+%](.+)$' ) if aaa then alias = '[' .. title .. ']' .. frameParts.mod .. ':' .. aaa else alias = '[' .. title .. ']' .. frameParts.mod .. ':' .. frameParts.name end else alias = frameParts.mod .. ':' .. modAliases[id] end end elseif aliases and aliases[id] then alias = aliases[id] end if alias then table.insert( frames, p.expandAlias( frameParts, alias ) ) else table.insert( frames, frame ) end end args[1] = table.concat( frames, ';' ) --- Проверка и замена всех фреймов на псевдонимы (конец) --- Построение спрайта -- Параметры local sprite local ids = mw.loadData([[Модуль:ИнвСпрайт]])["IDы"] local modIds = {} local back_modData = {} local param local animated = mw.ustring.find(args[1], ';') local pageName = mw.title.getCurrentTitle().text local imgClass = args["классизобр"] local imgStyle = args["стильизобр"] local numStyle = args["стильцифр"] local scale = args["масштаб"] or '1' local imgSize = 32 * scale local valign local body = mw.html.create('span') -- Для повышения эффективности сборки CSS-стилей здесь используется ровно тот же трюк, что и в [[Модуль:Спрайт]]. -- А именно, собирается таблица (причём без table.insert!) и в конкатенированном виде передаётся через cssText. local css = {} if args["выравн"] then css[#css+1] = "vertical-align:" .. args["выравн"] end if scale == '0.5' then css[#css+1] = 'top:-1px' end if animated then body:addClass('animated') end if args["класс"] then body:addClass(args["класс"]) end body:addClass('invslot') css[#css+1] = "width:" .. imgSize .. "px; height:" .. imgSize .. "px" -- Если args["стиль"] равен nil, то ничего по сути в таблицу не добавляется. css[#css+1] = args["стиль"] if (args["умолчание"] or '') ~= '' then css[#css+1] = 'background-image: {{FileUrl|' .. args["умолчание"] .. '.png}}' end ---спрайты для фона local n = args["умолчаниеCSS"] local Back_ID = args["Фон ИД"] local mod = args["мод"] if (n or Back_ID) and mod then if not Back_ID then if mw.title.new('Модуль:ФоновыйСпрайт/' .. mod).exists then back_modData = mw.loadData('Модуль:ФоновыйСпрайт/' .. mod .. '/ID') param = mw.loadData('Модуль:ФоновыйСпрайт/' .. mod) size = param["разм"] sheet_size = param["формат"] Back_ID = back_modData[n] css[#css+1] = 'background-image: {{FileUrl|' .. mod .. 'bkgrdCSS.png}}' end else body:addClass('gt-invslot') size = 16 sheet_size = 160 end if Back_ID then local pos = Back_ID - 1 local back_scale = 32 / size local tiles = sheet_size / size local left = pos % tiles * 32 local top = math.floor( pos / tiles ) * 32 css[#css+1] = 'background-size:' .. sheet_size * back_scale ..'px; background-position: -' .. left .. 'px -' .. top ..'px' end end -- Все CSS-стили применяются к body-элементу body:cssText(table.concat(css, ";")) --- Обработка фреймов local first = true for _, frame in ipairs(p.splitOnUnenclosedSemicolons(args[1])) do local item if frame ~= '' or frame == '' and animated then item = body:tag('span'):addClass('invslot-item') if imgClass then item:addClass(imgClass) end if imgStyle then item:cssText(imgStyle) end end if frame == '' then (item or body):tag('br') else local category local parts = p.getParts(frame, args["мод"]) local title = parts.title or mw.text.trim(args["назв"] or '') local mod = parts.mod local name = parts.name local num = parts.num local description = parts.text --- Добавляем к доп тексту название мода local img, idData, en_name if mod then local modData = modIds[mod] if not modData and mw.title.new('Модуль:ИнвСпрайт/' .. mod).exists then local modDataModule = mw.loadData('Модуль:ИнвСпрайт/' .. mod) local idListOverride = modDataModule['настройки']['списокID'] if idListOverride then modData = mw.loadData('Модуль:' .. idListOverride)['IDы'] else modData = modDataModule['IDы'] end modIds[mod] = modData end if modData and modData[name] then idData = modData[name] en_name = idData["en"] else img = name .. ' (' .. mod .. ')' end elseif ids[name] then idData = ids[name] else img = name end local link = args["ссылка"] or '' if link == '' then if mod then link = mod .. '/' .. name else link = mw.ustring.gsub(name, '^Повреждённ[ыао][йяе] ', '') end elseif mw.ustring.lower(link) == 'нет' then link = nil end if link == pageName then link = nil end local formattedTitle local plainTitle if title == '' then plainTitle = name elseif mw.ustring.lower(title) ~= 'нет' then plainTitle = mw.ustring.gsub(mw.ustring.gsub(title, '\\\\', '&#92;'), '\\&', '&#38;') local formatPattern = '&[0-9a-fk-or]' if mw.ustring.match(plainTitle, formatPattern) then formattedTitle = title plainTitle = mw.ustring.gsub(plainTitle, formatPattern, '') end if plainTitle == '' then plainTitle = name else plainTitle = mw.ustring.gsub(mw.ustring.gsub(plainTitle, '&#92;', '\\'), '&#38;', '&') end elseif link then if img then formattedTitle = '' else plainTitle = '' end end if mod == 'GregTech' and idData and idData["страница"] and mw.title.new('Модуль:GregTechProc/Материалы/' .. idData["страница"]).exists then local mat_info = mw.loadData('Модуль:GregTechProc/Материалы/' .. idData["страница"]) if mat_info then local formula = mat_info["Формула"] local melt = mat_info["Плавление"] local boil = mat_info["Испарение"] if not description then description = '' end description = description .. '/&7Формула: &e' .. formula .. '/&6t° плавления: ' .. melt .. 'K/&ct° испарения: ' .. boil .. 'K' end end item:attr{ ['data-minetip-title'] = formattedTitle, ['data-minetip-text'] = description, ['data-modinfo-text'] = mod, ['data-minetip-lowtitle'] = en_name } if img then -- & is re-escaped because mw.html treats attributes -- as plain text, but MediaWiki doesn't local escapedTitle = ( plainTitle or '' ):gsub( '&', '&#38;' ) item:addClass('invslot-item-image') :wikitext('[[Файл:Grid ', img, '.png|' .. imgSize .. 'x' .. imgSize .. 'px|link=', link or '', '|', escapedTitle, ']]') :cssText('width:' .. imgSize .. 'px; height:' .. imgSize .. 'px') else if not sprite then sprite = require([[Модуль:Спрайт]]).sprite end local image if mod then image = (args["таблспрайтов"] or mod or "Inv") .. 'CSS.png' end if link then item:wikitext('[[', link, '|') end local image, spriteCat local dataPage = "ИнвСпрайт" if mod then dataPage = "ИнвСпрайт/" .. mod end image, spriteCat = sprite{ ["масштаб"] = scale, ["данныеID"] = idData, ["назв"] = plainTitle, ["изобр"] = image, ["данные"] = dataPage } item:node(image) category = spriteCat end if num and num > 1 and num < 1000 then if img and link then item:wikitext('[[', link, '|') end local number = item :tag('span') :addClass('invslot-stacksize') :attr{title = plainTitle} :wikitext(num) if numStyle then number:cssText(numStyle) end if img and link then item:wikitext(']]') end end if idData and link then item:wikitext(']]') end item:wikitext(category) end if first then if animated and item then item:addClass('active') end first = false end end return tostring( body ) end function p.expandAlias( frameParts, alias ) -- If the frame has no parts, we can just return the alias as-is --[[if not frameParts.title and not frameParts.mod and not frameParts.num and not frameParts.text then return alias end--]] local expandedFrames = {} for _, aliasFrame in ipairs(p.splitOnUnenclosedSemicolons(alias)) do local aliasParts = p.getParts(aliasFrame) aliasParts.title = frameParts.title or aliasParts.title or '' aliasParts.mod = frameParts.mod or aliasParts.mod or 'Minecraft' aliasParts.num = frameParts.num or aliasParts.num or '' aliasParts.text = frameParts.text or aliasParts.text or '' table.insert(expandedFrames, mw.ustring.format( '[%s]%s:%s,%s[%s]', aliasParts.title, aliasParts.mod, aliasParts.name, aliasParts.num, aliasParts.text )) end return table.concat(expandedFrames, ';') end function p.getParts(frame, mod) ----Функция получает название предмета в формате "[титл]мод:имя[доп.текст],число" ----parts.title = титл, название предмета при наведении ----parts.mod = мод ----parts.name = имя ----parts.text = текст, дополнительный текст при наведении на предмет ----parts.num = число local parts = {} parts.title = mw.ustring.match(frame, '^%[%s*([^%]]+)%s*%]') local modPattern if mw.ustring.match(frame, '^%[.*%]([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):') then modPattern = '^%[.*%]([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):' else modPattern = '^([a-zA-Zа-яА-Я0-9ёЁé _%-\']+):' end parts.mod = mw.text.trim(mw.ustring.match(frame, modPattern) or mod or '') ---- Получаем название мода local vanilla = {v = 1, vanilla = 1, mc = 1, minecraft = 1} if parts.mod == '' or vanilla[mw.ustring.lower(parts.mod)] then parts.mod = nil else if p.modAliases[parts.mod] then parts.mod = p.modAliases[parts.mod] end parts.mod = mw.ustring.gsub(parts.mod,'_',' ') end local _, nameStartV = mw.ustring.find( frame, '^%[[^%]]*%]' ) local nameStart = ( ({mw.ustring.find( frame, modPattern )})[2] or nameStartV or 0 ) + 1 if nameStart - 1 == #frame then nameStart = 1 end parts.name = mw.text.trim( mw.ustring.sub( frame, nameStart, ( mw.ustring.find( frame, '[,%[]', nameStart ) or 0 ) - 1 ) ) parts.num = math.floor(mw.ustring.match(frame, ',%s*(%d+)') or 0) if parts.num == 0 then parts.num = nil end parts.text = mw.ustring.match(frame, '%[%s*([^%]]+)%s*%]$') return parts end return p 
В данной статье используются материалы из статьи «Модуль:Участник:BabylonAS/Nova/Инвентарный слот» с вики-сайта Minecraft Wiki, расположенного на Фэндоме, и они распространяются согласно лицензии Creative Commons Attribution-NonCommercial-ShareAlike 3.0. Авторы статьи.