Home
Random
Log in
Settings
About the Deadlock Wiki
Search
Editing
Module
:
ItemData/nav
Give feedback
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.
Anti-spam check. Do
not
fill this in!
local p = {} local items_data = mw.loadJsonData("Data:ItemData.json") 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)" } -- The card navboxes put every item on a single page, so their cards opt into -- the cheaper ItemBox rendering via lowGraphics. This swaps the paper texture -- from the normal-mode multiply (which blends two images and is re-rasterised -- every scrolled frame) to a transparent-paper overlay that is a single -- cacheable image, the one change that carried the navbox scroll cost. The wear -- and icon masks stay at full detail, since a single-image mask caches fine. -- See [[Template:ItemBox]]. Only the ItemBox branch of write_wrapped_item_list -- uses this; the ItemIcon lists are unaffected. local LOW_GRAPHICS = "|lowGraphics=true" -- Cached items grouped by slot to prevent redundant full-table evaluations local cached_slots = nil local function get_items_by_slot(slot) if not cached_slots then cached_slots = { table = {}, Weapon = {}, Armor = {}, Tech = {} } for item_key, item_data in pairs(items_data) do local this_slot = item_data["Slot"] if this_slot and cached_slots[this_slot] then table.insert(cached_slots[this_slot], { key = item_key, data = item_data }) end end end return cached_slots[slot] or {} end -- With debug_mode on, it outputs unprocessed wikitext local function process_debug_mode(wikitext, debug_mode) if debug_mode == 'true' then return wikitext elseif debug_mode == 'false' or debug_mode == nil then return mw.getCurrentFrame():preprocess(wikitext) else return "debug_mode must be 'true' or 'false'" end end -- Writes list of items of a certain slot within the min and max soul bounds 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 '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 items = {} local slot_items = get_items_by_slot(slot) -- Drastically reduces search pool size for _, item_entry in ipairs(slot_items) do local item_key = item_entry.key local item_data = item_entry.data local this_cost = tonumber(item_data["Cost"]) local is_street_brawl = item_data["StreetBrawl"] == true local should_include = true -- Filter logic for Street Brawl items if filter_mode == "street_brawl_only" and not is_street_brawl then should_include = false elseif filter_mode == "exclude_street_brawl" and is_street_brawl then should_include = false end if should_include and item_data["Name"] ~= nil and item_data["IsDisabled"] == false and this_cost ~= nil 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_link = linkOverrides[item_name_english] or item_name_english local item_name_local = lang_module.get_string(item_key, lang_code) local item_template if template == "ItemIcon" then 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" .. LOW_GRAPHICS .. "}}" else item_template = "{{ItemBox|itemName=" .. item_name_english .. "|overrideLinkClick=" .. item_link .. LOW_GRAPHICS .. "}}" 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}}" .. LOW_GRAPHICS .. "}}" else item_template = "{{ItemBox|itemName=" .. item_name_english .. "|overrideLinkClick=" .. link_local .. LOW_GRAPHICS .. "}}" end end else return "Invalid template type" end table.insert(items, item_template) end end end -- Order list alphabetically table.sort(items) -- Append closing tags and bullets if template == "ItemIcon" then local total_items = #items for i = 1, total_items do if i == total_items then items[i] = items[i] .. '</span>' else items[i] = items[i] .. '<span class="item-nav-search-sep"> • </span></span>' end end end 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 -- 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 local item_list = write_wrapped_item_list(slot, min_souls, max_souls, "ItemBox", ' ', filter_mode) return process_debug_mode(item_list, debug_mode) 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}}}}' if slot == nil then return "'slot' parameter is required" end 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 i, souls in ipairs(prices) do local min_souls = souls if min_souls ~= 0 then local max_souls = prices[i+1] or (min_souls * 10) local list if type_func == 'get_item_nav_cards' then list = p.get_item_nav_cards(slot, min_souls, max_souls, debug_mode, "exclude_street_brawl") elseif type_func == 'get_item_nav_bulletpoints' then list = p.get_item_nav_bulletpoints(slot, min_souls, max_souls, debug_mode, "exclude_street_brawl") else return "'type' should be get_item_nav_cards or get_item_nav_bulletpoints" end if list and list ~= "" then template_args["group" .. group_index] = frame:expandTemplate{title="Souls", args={[1] = min_souls, ["Shadow"] = soul_style}} template_args["list" .. group_index] = list group_index = group_index + 1 end end end 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 if sb_list and sb_list ~= "" then 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;" local sb_link_text = "[[Street Brawl{{if_lang}}|<span style=\"" .. sb_style .. "\"><b>" .. street_brawl_label .. "</b></span>]]" template_args["group" .. group_index] = frame:preprocess(sb_link_text) template_args["list" .. group_index] = sb_list end return frame:expandTemplate{title="Navbox subgroup", args=template_args} end -- for [[Template:Active Items]] -- Displayed when a stat does not apply to an item local NO_VALUE = "—" -- One expanded inline attribute as produced by [[Module:Lang]]: -- wrapper span > icon span > spacer span > wikilink local INLINE_ATTRIBUTE_PATTERN = '<span class="no%-blue%-link" style="text%-wrap:nowrap; font%-weight:bold; color:[^;"]*;">' .. '<span style="[^"]*">%[%[File:[^%]]*%]%]</span>' .. '<span style="color: inherit;"> </span> ' .. '%[%[([^|%]]+)|([^%]]*)%]%]</span>' -- Range is taken from the first of these the item has a usable value for local RANGE_PROPERTIES = { "AbilityCastRange", "Radius", "EndRadius" } -- Rewrites the description markup [[Module:Lang]] produces local function restyle_description(text) text = text:gsub(INLINE_ATTRIBUTE_PATTERN, '[[%1|%2]]') -- Attributes with an icon but no link keep their span; follow the site text color text = text:gsub('color:#ffefd7;', 'color:var(--color-base);') -- Diminished notes ("Cannot be used while Stunned...") return (text:gsub('color:#C0C0C0', 'color:var(--color-subtle)')) end -- Numeric value of a stat, used for sorting local function stat_sort_value(value) if type(value) == "table" then value = value["Value"] end if value == nil then return -1 end return tonumber(tostring(value):match("[-%d%.]+")) or -1 end -- First range property the item has a usable value for local function get_range_property(item_data) for _, property in ipairs(RANGE_PROPERTIES) do local value = item_data[property] if value ~= nil and stat_sort_value(value) > 0 then return property, value end end return nil, nil end -- Builds a stat cell, falling back to an em dash when the stat does not apply local function stat_cell(raw_value, item_name, property, postfix) if raw_value == nil or property == nil then return '| data-sort-value="-1" style="text-align:center;font-size:16px" | ' .. NO_VALUE end return string.format( '| data-sort-value="%s" style="text-align:center;font-size:16px" | {{#invoke:ItemData|get_prop|%s|%s}}%s', stat_sort_value(raw_value), item_name, property, postfix or "") end function p.generate_active_items_table(frame) local active_items = {} for item_key, item_data in pairs(items_data) do local cost = tonumber(item_data["Cost"]) if item_data["Name"] and item_data["IsDisabled"] == false and cost ~= nil and cost > 0 and item_data["Activation"] and item_data["Activation"] ~= "Passive" then local range_property, range_value = get_range_property(item_data) table.insert(active_items, { name = item_data["Name"], key = item_key, cost = cost, slot = item_data["Slot"] or "Weapon", has_active_desc = item_data["ActiveDescription"] ~= nil, cooldown = item_data["AbilityCooldown"], duration = item_data["AbilityDuration"], range_property = range_property, range_value = range_value }) end end table.sort(active_items, function(a, b) return a.name < b.name end) -- Optimized string compilation using a structural buffer table local rows = {} table.insert(rows, [=[{| class="wikitable mw-collapsible sortable" style="width:100%" |+{{#invoke:Dictionary|translate|Active Items}} ! colspan="2" | {{#invoke:Lang|get_string|Citadel_HeroBuilds_CategoryNameLabel}} ! {{#invoke:Lang|get_string|Citadel_UserFeedback_TypeLabel}} ! {{Souls|{{#invoke:Dictionary|translate|Cost}}}} ! {{#invoke:Lang|get_string|Citadel_Mod_Tooltip_Active}} ! {{#invoke:Lang|get_string|AbilityCooldown_label}} ! {{#invoke:Lang|get_string|AbilityDuration_label}} ! {{#invoke:Lang|get_string|AbilityCastRange_label}}]=]) for _, item in ipairs(active_items) do local bg_color = util_module.get_slot_color(item.slot) local item_type if item.slot == "Armor" then item_type = "Armor" elseif item.slot == "Tech" then item_type = "Tech" else item_type = "Weapon" end local row = string.format([=[ |- ! style="background-color:%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}} %s %s %s]=], bg_color, 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, stat_cell(item.cooldown, item.name, "AbilityCooldown", "s"), stat_cell(item.duration, item.name, "AbilityDuration", "s"), stat_cell(item.range_value, item.name, item.range_property)) table.insert(rows, row) end table.insert(rows, "\n|}") return restyle_description(frame:preprocess(table.concat(rows, "\n"))) end return p
Summary:
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
Pages included on this page:
Template:Icon/Brown
(
edit
)
Template:Icon/Green
(
edit
)
Template:Icon/NoColor
(
edit
)
Template:Icon/Purple
(
edit
)
Template:Icon/White
(
edit
)
Template:If lang
(
view source
) (⧼restriction-level-bot+⧽)
Template:ItemBox
(
edit
)
Template:ItemBox/styles.css
(
edit
)
Template:ItemIcon
(
edit
)
Template:ItemType
(
edit
)
Template:Legendary
(
edit
)
Template:MissingValveTranslationTooltip
(
edit
)
Template:Navbox
(
edit
)
Template:Navbox subgroup
(
edit
)
Template:Souls
(
edit
)
Template:Ss
(
edit
)
Template:Ss/styles.css
(
edit
)
Template:Tooltip
(
edit
)
Module:Dictionary
(
edit
)
Module:GenericData
(
edit
)
Module:Icon
(
edit
)
Module:Icon/data
(
edit
)
Module:ItemBox
(
edit
)
Module:ItemData
(
edit
)
Module:ItemData/nav
(
edit
)
Module:ItemData/nav/doc
(
edit
)
Module:Lang
(
edit
)
Module:Souls
(
edit
)
Module:TextFit
(
edit
)
Module:Utilities
(
edit
)
Data:Dictionary
(
edit
)
Data:GenericData.json
(
view source
) (⧼restriction-level-bot+⧽)
Data:ItemData.json
(
view source
) (⧼restriction-level-bot+⧽)
Data:LangCodes.json
(
view source
) (⧼restriction-level-bot+⧽)
Data:Lang en.json
(
view source
) (⧼restriction-level-bot+⧽)
Data:ResourceLookup.json
(
edit
)
Data:ResourceLookup2.json
(
edit
)