Module:Sandbox/LVL

From The Deadlock Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Sandbox/LVL/doc

local p = {}

-- Single pre-indexed lookup, built by the bot at deploy time.
-- mw.loadJsonData re-parses JSON on every page render, but is still
-- dramatically faster than loading 3 separate files and iterating them.
local iconData = mw.loadJsonData("Data:Sandbox.json")
local lang_codes = mw.loadJsonData("Data:LangCodes.json")

local cachedLangCode, cachedLangData

local linkOverrides = {
    ["Bullet Lifesteal"] = "Bullet Lifesteal (item)",
    ["Spirit Lifesteal"] = "Spirit Lifesteal (item)"
}

local aliases = {
    ["doorman"] = "the doorman",
    ["mo and krill"] = "mo & krill",
    ["mo"] = "mo & krill",
    ["krill"] = "mo & krill",
    ["curse"] = "cursed relic",
    ["debuff remover"] = "dispel magic",
    ["defend and fight!"] = "plot armor",
    ["conjure dragon"] = "bookwyrm",
    ["backstabber"] = "stalker",
    ["flying strike"] = "flying slash",
    ["tornado"] = "dust devil",
    ["kudzu bomb"] = "entangling thorns",
    ["kudzu connection"] = "watcher's covenant"
}

local function getLangData()
    if cachedLangData then
        return cachedLangCode, cachedLangData
    end

    local title = mw.title.getCurrentTitle().fullText
    local subpageLang = title:match("/([^/]+)$")
    local langCode = (subpageLang and lang_codes[subpageLang]) and subpageLang or "en"

    local langData = {}
    if langCode ~= "en" then
        local success, data = pcall(function()
            return mw.loadJsonData("Data:Lang " .. langCode .. ".json")
        end)
        if success and type(data) == "table" then
            langData = data
        end
    end

    cachedLangCode = langCode
    cachedLangData = langData
    return langCode, langData
end

function p.render(frame)
    local args = frame.args[1] ~= nil and frame.args or frame:getParent().args
    local name = args[1] or ""
    local lowerName = name:lower()

    -- Resolve aliases
    if aliases[lowerName] then
        lowerName = aliases[lowerName]
    end

    -- Direct O(1) lookup, no iteration
    local iconInfo = iconData[lowerName]

    if not iconInfo then
        return string.format("[[:Category:Module:Icon ERROR|Icon not found]] ('%s'). [[Category:Module:Icon ERROR]]", name)
    end

    -- Argument parsing
    local customText = args.l1 or ""
    local size = args.size or "20px"
    local noLink = args["no-link"] == "true"
    local iconOnly = args["icon-only"] == "true"

    for k, v in pairs(args) do
        if type(k) == "number" and k > 1 then
            local val = mw.text.trim(v)
            if val == "icon-only" then iconOnly = true
            elseif val == "no-link" then noLink = true
            elseif val:match("^%d+px$") then size = val end
        end
    end

    -- Language handling
    local langCode, langData = getLangData()

    local displayName = customText
    if displayName == "" then
        if iconInfo.key and langData[iconInfo.key] then
            displayName = langData[iconInfo.key]
        else
            displayName = iconInfo.name
        end
    end

    -- Link logic
    local baseLink = linkOverrides[iconInfo.name] or iconInfo.link or ""
    local link = baseLink
    if langCode ~= "en" and baseLink ~= "" then
        link = baseLink .. "/" .. langCode
    end

    -- Style logic
    local style
    if iconInfo.class and iconInfo.class:find("theme", 1, true) then
        style = 'class="module-icon-ability" style="position:relative; bottom:2px;"'
    else
        style = 'style="position:relative; bottom:2px;"'
    end

    -- Render
    local imageLink = noLink and "" or link
    local iconHtml = string.format('<span %s>[[File:%s|%s|link=%s]]</span>', style, iconInfo.image, size, imageLink)

    if iconOnly or displayName == "" then
        return iconHtml
    end

    local textHtml = (noLink or link == "") and displayName or string.format('[[%s|%s]]', link, displayName)
    return '<span style="white-space:nowrap;">' .. iconHtml .. " " .. textHtml .. '</span>'
end

return p