Module:AbilityHints

From The Deadlock Wiki
Revision as of 13:14, 12 July 2026 by ~2026-PurpleDynamoLeap628 (talk) (Replace reactivebarrier/indomitable suppression with a diagonally-split combined icon (clip-path); tooltip shows both notes (with help from vergir-bot LLM))
Jump to navigation Jump to search

Overview

Renders a small strip of item icons showing how an ability interacts with items and used by Module:AbilitySection. Each icon displays a configured image and has a hover tooltip.

Hints can be "automatic" and "manual".

  • Automatic come from Module:AbilityTable/Lists. If an ability is part of 'debuffresist' list, then it will show automatic debuff resist hint. List of enabled automatic hints is configured through CONFIG in this module. Clicking on an icon does nothing, however tooltip often will have a link to relevant item/mechanic.
  • Manual hints come from {{AbilityInteraction}} blocks used on AbilitySection. Whenetever an editor describes an interaction using that block a hint will be displayed. Clicking on a hint reveals that hand-written block.

Entry point

p.get_icons(ability_key, ability_num)

Returns the rail HTML for one ability, or an empty string when the ability matches no lists.

Configuration

CONFIG

List of the icons the rail can show. Order within CONFIG does not affect the rendered output — see Display order. Each entry:

Field Description
list List name in Module:AbilityTable/Lists whose membership triggers the icon.
file Image file to display, e.g. Reactive Barrier.png. Also determines the icon's position in the rail.
tip Hover tooltip text. May contain wikilinks and simple HTML (<br>, <b>).

To add an icon, add a CONFIG row: pick the triggering list, the display file, and the tip. To re-scope which abilities an icon covers, edit the list in Module:AbilityTable/Lists.


-- Ability interaction hints: small item icons on ability cards showing how an
-- ability interacts with items (dispellable, reduced, blocked, etc.).
-- Membership is decided by Module:AbilityTable.is_member so these icons always
-- agree with the dynamic ability-interaction tables.

local AbilityTable = require("Module:AbilityTable")
local icon_module  = require("Module:Icon")
local ability_data = mw.loadJsonData("Data:AbilityData.json")

local p = {}

-- Display order. Each entry:
--   list           AbilityTable list name (Module:AbilityTable/Lists)
--   item           item whose icon represents the interaction
--   tip            short hover text
--   suppressed_by  optional: hide this icon when the named list is also a member
local CONFIG = {
    { list = "melee",           item = "Melee Lifesteal",  tip = "Benefits from melee items" },
	{ list = "reactivebarrier", item = "Reactive Barrier", tip = "Triggers Reactive Barrier" },
	{ list = "debuffresist",    item = "Debuff Reducer",   tip = "Duration reduced by Debuff Resist" },
    { list = "movementbased",   item = "Slowing Hex",      tip = "Disabled by Slowing Hex" },
    { list = "heal",            item = "Healing Booster",  tip = "Healing amplified by Healing Booster and affected by healing reduction" },
    { list = "dispelmagic",     item = "Dispel Magic",     tip = "Effect can be dispelled" },
    { list = "indomitable",     item = "Indomitable",      tip = "Effect blocked by Indomitable" },
    { list = "unstoppable",     item = "Unstoppable",      tip = "Disable prevented by Unstoppable" },
    { list = "platedarmor",     item = "Plated Armor",     tip = "Bullet effect prevented by Plated Armor" },
}

-- Pairs that merge into ONE diagonally-split icon when BOTH match the ability:
-- the first list fills the upper-left triangle, the second the lower-right.
-- (Replaces suppressed_by for these pairs.)
local COMBINE = {
    { "reactivebarrier", "indomitable" },
}

local DEF_BY_LIST = {}
for _, def in ipairs(CONFIG) do
    DEF_BY_LIST[def.list] = def
end

-- Renders one item icon as a title-less external link (so Page Previews / Popups
-- ignores it) wrapping just the image.
local function icon_img(item)
    local url = tostring(mw.uri.canonicalUrl(item))
    return icon_module._render(item, { size = '24px', ['icon-only'] = 'true', link = url })
end

-- A normal single hint icon.
local function single_icon(def)
    return '<span class="ability-hint">' .. icon_img(def.item)
        .. '<span class="ability-hint-tip">' .. def.tip .. '</span></span>'
end

-- A combined icon split along the diagonal: tl = upper-left, br = lower-right.
-- Each half links to its own item; the tooltip lists both notes.
local function split_icon(tl, br)
    return '<span class="ability-hint ability-hint--split">'
        .. '<span class="ability-hint-half ability-hint-half--tl">' .. icon_img(tl.item) .. '</span>'
        .. '<span class="ability-hint-half ability-hint-half--br">' .. icon_img(br.item) .. '</span>'
        .. '<span class="ability-hint-tip">' .. tl.tip .. '<br>' .. br.tip .. '</span>'
        .. '</span>'
end

-- Renders the interaction icon rail for one ability.
--   ability_key  the ability's internal key (AbilityCards .Key)
--   ability_num  the ability's slot (1-4); coerced to number
-- Returns rail HTML, or '' when the ability has no interactions.
function p.get_icons(ability_key, ability_num)
    local record = ability_data[ability_key]
    if record == nil then return '' end
    local num = tonumber(ability_num)

    local member = {}
    for _, def in ipairs(CONFIG) do
        member[def.list] = AbilityTable.is_member(def.list, record, num)
    end

    -- Resolve combos: when both lists match, the second is consumed and drawn as
    -- the lower-right half of the first list's icon.
    local split_with = {}
    local consumed = {}
    for _, c in ipairs(COMBINE) do
        local tl, br = c[1], c[2]
        if member[tl] and member[br] then
            split_with[tl] = br
            consumed[br] = true
        end
    end

    local icons = {}
    for _, def in ipairs(CONFIG) do
        if member[def.list] and not consumed[def.list]
           and not (def.suppressed_by and member[def.suppressed_by]) then
            if split_with[def.list] then
                table.insert(icons, split_icon(def, DEF_BY_LIST[split_with[def.list]]))
            else
                table.insert(icons, single_icon(def))
            end
        end
    end

    if #icons == 0 then return '' end
    return '<div class="ability-section-hints">' .. table.concat(icons) .. '</div>'
end

return p