Editing Module:Item Navbox

Warning: You are not logged in. Once you make an edit, a temporary account will be created for you. Learn more. Log in or create an account to continue receiving notifications after this account expires, and to access other features.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
local p = {}
local p = {}
local items_data = mw.loadJsonData("Data:ItemData.json")
local items_data = mw.loadJsonData("Data:ItemData.json")
local items_module = require("Module:ItemData")
local lang_module = require('Module:Lang')
local lang_module = require('Module:Lang')
local generic_module = require('Module:GenericData')
local util_module = require('Module:Utilities')
-- Exceptions if the link is different from the item name
local linkOverrides = {
    ["Bullet Lifesteal"] = "Bullet Lifesteal (item)",
    ["Spirit Lifesteal"] = "Spirit Lifesteal (item)"
}


-- Cached items grouped by slot to prevent redundant full-table evaluations
-- Cached items grouped by slot to prevent redundant full-table evaluations
Line 30: Line 37:
end
end


-- Directly fetches and formats ItemIcons for the navbox
-- Writes list of items of a certain slot within the min and max soul bounds
local function get_item_icons(slot, min_souls, max_souls, filter_mode)
local function write_wrapped_item_list(slot, min_souls, max_souls, template, sep, filter_mode)
     if slot ~= 'Weapon' and slot ~= 'Armor' and slot ~= 'Tech' then return '' end
     if slot ~= 'Weapon' and slot ~= 'Armor' and slot ~= 'Tech' then
        return 'slot must be Weapon, Armor (Vitality), or Tech (Spirit)'
    end
   
    local min_souls = tonumber(min_souls)
    local max_souls = tonumber(max_souls)
    if min_souls == nil or max_souls == nil then return 'Min/Max souls must be numerical' end
   
    filter_mode = filter_mode or "all"
      
      
    -- Lifted out of the loop: Language code doesn't change per item
     local lang_code = lang_module.get_lang_code()  
     local lang_code = lang_module.get_lang_code()  
   
     local items = {}
     local items = {}
     local slot_items = get_items_by_slot(slot)  
     local slot_items = get_items_by_slot(slot) -- Drastically reduces search pool size
      
      
     for _, item_entry in ipairs(slot_items) do
     for _, item_entry in ipairs(slot_items) do
Line 46: Line 63:
         local should_include = true
         local should_include = true
          
          
        -- Filter logic for Street Brawl items
         if filter_mode == "street_brawl_only" and not is_street_brawl then
         if filter_mode == "street_brawl_only" and not is_street_brawl then
             should_include = false
             should_include = false
Line 55: Line 73:
             if this_cost >= min_souls and this_cost < max_souls then
             if this_cost >= min_souls and this_cost < max_souls then
                 local item_name_english = lang_module.get_string(item_key, "en")
                 local item_name_english = lang_module.get_string(item_key, "en")
                local item_link = linkOverrides[item_name_english] or item_name_english
                 local item_name_local = lang_module.get_string(item_key, lang_code)
                 local item_name_local = lang_module.get_string(item_key, lang_code)
                  
                  
                 local item_template
                 local item_template
                 if lang_code == "en" then
                 if template == "ItemIcon" then
                     item_template = "{{ItemIcon|" .. item_name_english .. "|size=26px}}"
                    if lang_code == "en" then
                        item_template = "{{ItemIcon|" .. item_name_english .. "|size=26px}}"
                     else
                        item_template = "{{ItemIcon|" .. item_name_english .. "|lang=" .. lang_code .. "|l1=" .. item_name_local .. "|size=26px}}"
                    end
                   
                    local search_data = item_name_english
                    if lang_code ~= "en" and item_name_local then
                        search_data = search_data .. " " .. item_name_local
                    end
                   
                    item_template = '<span class="item-nav-search-wrapper"><span class="item-nav-search-item" data-item-name="' .. search_data .. '">' .. item_template .. '</span>'
                elseif template == "ItemBox" then
                    if lang_code == "en" then
                        if is_street_brawl then
                            item_template = "{{ItemBox|itemName=" .. item_name_english .. "|overrideLinkClick=" .. item_link .. "|overrideTier=5}}"
                        else
                            item_template = "{{ItemBox|itemName=" .. item_name_english .. "|overrideLinkClick=" .. item_link .. "}}"
                        end
                    else
                        local link_local = item_link .. "/" .. lang_code
                        if is_street_brawl then
                            item_template = "{{ItemBox|itemName=" .. item_name_english .. "|overrideLinkClick=" .. link_local .. "|item_price={{#invoke:Lang|get_string|Citadel_ItemDraft_Legendary}}}}"
                        else
                            item_template = "{{ItemBox|itemName=" .. item_name_english .. "|overrideLinkClick=" .. link_local .. "}}"
                        end
                    end
                 else
                 else
                     item_template = "{{ItemIcon|" .. item_name_english .. "|lang=" .. lang_code .. "|l1=" .. item_name_local .. "|size=26px}}"
                     return "Invalid template type"
                 end
                 end
               
                local search_data = item_name_english
                if lang_code ~= "en" and item_name_local then
                    search_data = search_data .. " " .. item_name_local
                end
               
                item_template = '<span class="item-nav-search-wrapper"><span class="item-nav-search-item" data-item-name="' .. search_data .. '">' .. item_template .. '</span>'
                 table.insert(items, item_template)
                 table.insert(items, item_template)
             end
             end
Line 75: Line 113:
     end
     end
      
      
    -- Order list alphabetically
     table.sort(items)
     table.sort(items)
      
      
     -- Append closing tags and bullets
     -- Append closing tags and bullets
     local total_items = #items
     if template == "ItemIcon" then
    for i = 1, total_items do
        local total_items = #items
        if i == total_items then
        for i = 1, total_items do
            items[i] = items[i] .. '</span>'
            if i == total_items then
        else
                items[i] = items[i] .. '</span>'
            items[i] = items[i] .. '<span class="item-nav-search-sep"> &bull; </span></span>'
            else
                items[i] = items[i] .. '<span class="item-nav-search-sep"> &bull; </span></span>'
            end
         end
         end
     end
     end
      
      
     return table.concat(items, '')
     return table.concat(items, sep)
end
 
-- for [[Template:Item Navbox]]
function p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode, filter_mode)
    if type(slot) == "table" and slot.args then
        local frame = slot
        slot = frame.args[1]
        min_souls = frame.args[2]
        max_souls = frame.args[3]
        debug_mode = frame.args["debug_mode"]
        filter_mode = frame.args["filter"]
    end
   
    local item_list = write_wrapped_item_list(slot, min_souls, max_souls, "ItemIcon", '', filter_mode)
    return process_debug_mode(item_list, debug_mode)
end
end
-- for [[Template:Infobox ShopItems]]
function p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode, filter_mode)
    if type(slot) == "table" and slot.args then
        local frame = slot
        slot = frame.args[1]
        min_souls = frame.args[2]
        max_souls = frame.args[3]
        debug_mode = frame.args["debug_mode"]
        filter_mode = frame.args["filter"]
    end
      
      
-- Gets list of item codenames
    local item_list = write_wrapped_item_list(slot, min_souls, max_souls, "ItemBox", ' ', filter_mode)
local function get_item_codenames(slot, min_souls, max_souls, filter_mode, frame)
    return process_debug_mode(item_list, debug_mode)
     if slot ~= 'Weapon' and slot ~= 'Armor' and slot ~= 'Tech' then return '' end
end
 
-- for [[Template:Item Navbox]] subgroup rows
function p.write_item_slot_subgroup(frame)
     local slot = frame.args[1]
    local type_func = frame.args[2]
    local debug_mode = frame.args['debug_mode']
    local street_brawl_label = frame.args['street_brawl_label'] or '{{Legendary|{{#invoke:Lang|get_string|Citadel_ItemDraft_Legendary}}}}'
      
      
     local lang_code = lang_module.get_lang_code()  
    if slot == nil then return "'slot' parameter is required" end
     local items = {}
   
     local slot_items = get_items_by_slot(slot)  
     local template_args = {
        ["groupstyle"] = "background-color:" .. util_module.get_slot_color(slot) .. ";width:10%;min-width:70px;border-radius: 8px 0 0 8px",
        ["grouppadding"] = "5px",
        ["listpadding"] = "0 0.25rem",
    }
   
     local soul_style = "font-size: 12px; text-shadow: 1px 1px rgba(0, 0, 0, 0.3);"
     local prices = generic_module.get_item_price_per_tier()
    local group_index = 1
      
      
     for _, item_entry in ipairs(slot_items) do
     for i, souls in ipairs(prices) do
         local item_key = item_entry.key
         local min_souls = souls
        local item_data = item_entry.data
          
          
         local this_cost = tonumber(item_data["Cost"])
         if min_souls ~= 0 then
        local is_street_brawl = item_data["StreetBrawl"] == true
            local max_souls = prices[i+1] or (min_souls * 10)
        local should_include = true
           
       
            local list
        if filter_mode == "street_brawl_only" and not is_street_brawl then
            if type_func == 'get_item_nav_cards' then
            should_include = false
                list = p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode, "exclude_street_brawl")
        elseif filter_mode == "exclude_street_brawl" and is_street_brawl then
             elseif type_func == 'get_item_nav_bulletpoints' then
             should_include = false
                 list = p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode, "exclude_street_brawl")
        end
            else
       
                 return "'type' should be get_item_nav_cards or get_item_nav_bulletpoints"
        if should_include and item_data["Name"] ~= nil and item_data["IsDisabled"] == false and this_cost ~= nil then
            end
            if this_cost >= min_souls and this_cost < max_souls then
           
                 local item_name_english = lang_module.get_string(item_key, "en")
            if list and list ~= "" then
                local item_name_local = lang_module.get_string(item_key, lang_code)
                template_args["group" .. group_index] = frame:expandTemplate{title="Souls", args={[1] = min_souls, ["Shadow"] = soul_style}}
                  
                 template_args["list" .. group_index] = list
                local codename_frame = {
                 group_index = group_index + 1
                    args = { item_name_english }
                }
 
                local item_codename = items_module.get_codename(codename_frame)
               
                local item_template
                if lang_code == "en" then
                    item_template = "{{ItemIcon|" .. item_name_english .. "|l1=" .. item_codename .. "|size=26px}}"
                else
                    item_template = "{{ItemIcon|" .. item_name_english .. "|lang=" .. lang_code .. "|l1=" .. item_name_local .. "|size=26px}}"
                 end
               
                local search_data = item_name_english
                if lang_code ~= "en" and item_name_local then
                    search_data = search_data .. " " .. item_name_local
                end
               
                 item_template = '<span class="item-nav-search-wrapper"><span class="item-nav-search-item" data-item-name="' .. search_data .. '">' .. item_template .. '</span>'
                table.insert(items, item_template)
             end
             end
         end
         end
     end
     end
      
      
     table.sort(items)
     local sb_list
    if type_func == 'get_item_nav_cards' then
        sb_list = p.get_item_nav_cards(slot, 0, 999999, debug_mode, "street_brawl_only")
    elseif type_func == 'get_item_nav_bulletpoints' then
        sb_list = p.get_item_nav_bulletpoints(slot, 0, 999999, debug_mode, "street_brawl_only")
    end
      
      
     -- Append closing tags and bullets
     if sb_list and sb_list ~= "" then
    local total_items = #items
        local sb_style = "color:#98ffde; font-family:'Retail Demo', sans-serif; text-wrap: nowrap; text-shadow: 0px 0px 2px #2c312e, 1.3px 1.3px rgba(0, 0, 0, 0.2);padding:5px;"
    for i = 1, total_items do
         local sb_link_text = "[[Street Brawl{{if_lang}}|<span style=\"" .. sb_style .. "\"><b>" .. street_brawl_label .. "</b></span>]]"
         if i == total_items then
        template_args["group" .. group_index] = frame:preprocess(sb_link_text)
            items[i] = items[i] .. '</span>'
         template_args["list" .. group_index] = sb_list
        else
            items[i] = items[i] .. '<span class="item-nav-search-sep"> &bull; </span></span>'
         end
     end
     end
      
      
     return table.concat(items, '')
     return frame:expandTemplate{title="Navbox subgroup", args=template_args}
end
end


-- Generates the full HTML item navbox recursively and efficiently
-- for [[Template:Active Items]]
function p.generate_full_navbox(frame)
function p.generate_active_items_table(frame)
     local debug_mode = type(frame) == "table" and frame.args and frame.args["debug_mode"] or nil
     local active_items = {}
 
   
    local html = {}
     for item_key, item_data in pairs(items_data) do
table.insert(html, '<div class="itemnav-header"> [[Items]] <div class="item-nav-search-container"></div></div>\n')
        local cost = tonumber(item_data["Cost"])
     table.insert(html, '<div class="itemnav-container"><templatestyles src="Item Navbox/styles.css"/>\n')
         if item_data["Name"] and
 
          item_data["IsDisabled"] == false and  
    -- Maps Headers to Slots and distinct CSS Classes
          cost ~= nil and cost > 0 and
    local categories = {
          item_data["Activation"] and
        { header = "Weapon",  slot = "Weapon", css = "itemnav-weapon" },
          item_data["Activation"] ~= "Passive" then
         { header = "Vitality", slot = "Armor",  css = "itemnav-vitality" },
           
        { header = "Spirit",  slot = "Tech",  css = "itemnav-tech" }
            table.insert(active_items, {
    }
                name = item_data["Name"],
 
                key = item_key,
    -- Maps tier boundaries and formatting
                cost = cost,
    local tiers = {
                slot = item_data["Slot"] or "Weapon",
        { label = "{{Souls|800}}", min = 0, max = 801 },
                has_active_desc = item_data["ActiveDescription"] ~= nil
        { label = "{{Souls|1600}}", min = 801, max = 1601 },
             })
        { label = "{{Souls|3200}}", min = 1601, max = 3201 },
        { label = "{{Souls|6400}}", min = 3201, max = 6401 },
        { label = "[[Street Brawl|{{Legendary|{{#invoke:Lang|get_string|Citadel_ItemDraft_Legendary}}}}]]", min = 6401, max = 99999, extra_css = "itemnav-legendary " }
    }
 
    for _, cat in ipairs(categories) do
        table.insert(html, '\n<div class="itemnav-type-header">\'\'\'' .. cat.header .. '\'\'\'</div>\n')
        table.insert(html, '<div class="itemnav-type-container">\n')
 
        for _, tier in ipairs(tiers) do
            local css_class = "itemnav-soul " .. (tier.extra_css or "") .. cat.css
            local items_wikitext = get_item_icons(cat.slot, tier.min, tier.max, nil)
 
            table.insert(html, '\n<div class="itemnav-tier-row">\n')
            table.insert(html, '<div class="' .. css_class .. '">' .. tier.label .. '</div><!--\n')
             table.insert(html, '--><div class="itemnav-cost-type-container">' .. items_wikitext .. '</div>\n')
            table.insert(html, '</div>\n')
         end
         end
        table.insert(html, '\n</div>\n')
     end
     end
 
   
     table.insert(html, '\n</div>')
     table.sort(active_items, function(a, b) return a.name < b.name end)
 
      
     -- Only ONE preprocess call for the entire structure
     -- Optimized string compilation using a structural buffer table
     return process_debug_mode(table.concat(html), debug_mode)
     local rows = {}
end
    table.insert(rows, [=[{| class="wikitable mw-collapsible sortable" style="width:100%"  
 
|+{{#invoke:Dictionary|translate|Active Items}}
-- Generates navbox with codenames
! colspan="2" | {{#invoke:Lang|get_string|Citadel_HeroBuilds_CategoryNameLabel}}
function p.generate_full_navbox_codenames(frame)
! {{#invoke:Lang|get_string|Citadel_UserFeedback_TypeLabel}}
    local debug_mode = type(frame) == "table" and frame.args and frame.args["debug_mode"] or nil
! {{Souls|{{#invoke:Dictionary|translate|Cost}}}}
 
! {{#invoke:Lang|get_string|Citadel_Mod_Tooltip_Active}}
     local html = {}
! {{#invoke:Lang|get_string|AbilityCooldown_label}}]=])
table.insert(html, '<div class="itemnav-header"> [[Items]] <div class="item-nav-search-container"></div></div>\n')
      
    table.insert(html, '<div class="itemnav-container"><templatestyles src="Item Navbox/styles.css"/>\n')
     for _, item in ipairs(active_items) do
 
         local item_class, item_type
    -- Maps Headers to Slots and distinct CSS Classes
        if item.slot == "Armor" then
    local categories = {
            item_class = "item-bg-armor"
        { header = "Weapon",  slot = "Weapon", css = "itemnav-weapon" },
             item_type = "Armor"
        { header = "Vitality", slot = "Armor",  css = "itemnav-vitality" },
        elseif item.slot == "Tech" then
        { header = "Spirit",  slot = "Tech",  css = "itemnav-tech" }
             item_class = "item-bg-tech"
    }
             item_type = "Tech"
 
        else
    -- Maps tier boundaries and formatting
             item_class = "item-bg-weapon"
    local tiers = {
             item_type = "Weapon"
        { label = "{{Souls|800}}", min = 0, max = 801 },
        { label = "{{Souls|1600}}", min = 801, max = 1601 },
        { label = "{{Souls|3200}}", min = 1601, max = 3201 },
        { label = "{{Souls|6400}}", min = 3201, max = 6401 },
        { label = "[[Street Brawl|{{Legendary|{{#invoke:Lang|get_string|Citadel_ItemDraft_Legendary}}}}]]", min = 6401, max = 99999, extra_css = "itemnav-legendary " }
     }
 
     for _, cat in ipairs(categories) do
         table.insert(html, '\n<div class="itemnav-type-header">\'\'\'' .. cat.header .. '\'\'\'</div>\n')
        table.insert(html, '<div class="itemnav-type-container">\n')
 
        for _, tier in ipairs(tiers) do
             local css_class = "itemnav-soul " .. (tier.extra_css or "") .. cat.css
            local items_wikitext = get_item_codenames(cat.slot, tier.min, tier.max, nil)
 
             table.insert(html, '\n<div class="itemnav-tier-row">\n')
             table.insert(html, '<div class="' .. css_class .. '">' .. tier.label .. '</div><!--\n')
             table.insert(html, '--><div class="itemnav-cost-type-container">' .. items_wikitext .. '</div>\n')
             table.insert(html, '</div>\n')
         end
         end
 
       
         table.insert(html, '\n</div>\n')
        local row = string.format([=[
|-
! class="%s" | [[File:%s.png|64x64px]]
! [[%s{{If_lang}}|{{#invoke:Lang|get_string|%s}}]]
| style="text-align:center;font-weight:bold" | {{ItemType|%s|{{#invoke:Lang|get_string|CitadelCategory%s}}}}
| data-sort-value="%d" style="text-align:center;font-size:15px" | {{Souls|%d}}
| {{#invoke:Utilities|process_variables|%s_active_desc|%s}}{{#invoke:Utilities|process_variables|%s_desc|%s}}{{#invoke:Utilities|process_variables|%s_active|%s}}
| style="text-align:center;font-size:16px" | {{#invoke:ItemData|get_prop|%s|AbilityCooldown}}s]=],
            item_class,
            item.name,
            item.name, item.key,
            item_type, item_type,
            item.cost, item.cost,
            item.key, item.name, item.key, item.name, item.key, item.name,
            item.name)
           
         table.insert(rows, row)
     end
     end
 
   
     table.insert(html, '\n</div>')
     table.insert(rows, "\n|}")
 
     return frame:preprocess(table.concat(rows, "\n"))
     -- Only ONE preprocess call for the entire structure
    return process_debug_mode(table.concat(html), debug_mode)
end
end


return p
return p
Please note that all contributions to The Deadlock Wiki are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see Deadlock:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template

Page included on this page: