Module:AbilityHints: Difference between revisions

From The Deadlock Wiki
Jump to navigation Jump to search
Replace the reactive/indomitable split icon with a grouped single icon whose image and tooltip depend on which of the two lists match (with help from vergir-bot LLM)
Revert groups/combinations: reactivebarrier and indomitable are plain separate icons again (with help from vergir-bot LLM)
Line 10: Line 10:
local p = {}
local p = {}


-- Display order. Each entry is either:
-- Display order. Each entry: { list = "...", item = "...", tip = "..." }
--  { list = "...", item = "...", tip = "..." }   a single icon shown when the ability is in `list`
-- The icon is shown when the ability is a member of `list`.
--  { group = "..." }                            a grouped relationship (see GROUPS)
local CONFIG = {
local CONFIG = {
     { list = "melee",          item = "Melee Lifesteal",  tip = "Benefits from melee items" },
     { list = "melee",          item = "Melee Lifesteal",  tip = "Benefits from melee items" },
Line 18: Line 17:
{ list = "debuffresist",    item = "Debuff Reducer",  tip = "Duration reduced by Debuff Resist" },
{ list = "debuffresist",    item = "Debuff Reducer",  tip = "Duration reduced by Debuff Resist" },
     { list = "heal",            item = "Healing Booster",  tip = "Healing amplified by Healing Booster and affected by healing reduction" },
     { list = "heal",            item = "Healing Booster",  tip = "Healing amplified by Healing Booster and affected by healing reduction" },
     { group = "reactive_indomitable" },
     { list = "reactivebarrier", item = "Reactive Barrier", tip = "Triggers Reactive Barrier" },
     { list = "dispelmagic",    item = "Dispel Magic",    tip = "Effect can be dispelled" },
     { 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 = "unstoppable",    item = "Unstoppable",      tip = "Disable prevented by Unstoppable" },
     { list = "platedarmor",    item = "Plated Armor",    tip = "On-shot effect prevented by Plated Armor" },
     { list = "platedarmor",    item = "Plated Armor",    tip = "On-shot effect prevented by Plated Armor" },
}
-- Grouped relationships: two related lists collapse into ONE full-size icon
-- whose item and tooltip depend on which of the two the ability matches.
local GROUPS = {
    reactive_indomitable = {
        a = "reactivebarrier",
        b = "indomitable",
        a_only = { item = "Reactive Barrier", tip = "Triggers Reactive Barrier<br>does <b>not</b> trigger Indomitable" },
        b_only = { item = "Indomitable",      tip = "Blocked by Indomitable<br>does <b>not</b> trigger Reactive Barrier" },
        both  = { item = "Reactive Barrier", tip = "Triggers Reactive Barrier<br>Blocked by Indomitable" },
    },
}
}


Line 57: Line 45:
     if record == nil then return '' end
     if record == nil then return '' end
     local num = tonumber(ability_num)
     local num = tonumber(ability_num)
    -- Membership for every list referenced by CONFIG or GROUPS.
    local member = {}
    local function check(list)
        if list ~= nil and member[list] == nil then
            member[list] = AbilityTable.is_member(list, record, num)
        end
    end
    for _, def in ipairs(CONFIG) do
        if def.list then
            check(def.list)
        elseif def.group then
            local g = GROUPS[def.group]
            check(g.a)
            check(g.b)
        end
    end


     local icons = {}
     local icons = {}
     for _, def in ipairs(CONFIG) do
     for _, def in ipairs(CONFIG) do
         if def.group then
         if AbilityTable.is_member(def.list, record, num) then
            local g = GROUPS[def.group]
            local ma, mb = member[g.a], member[g.b]
            local case
            if ma and mb then
                case = g.both
            elseif ma then
                case = g.a_only
            elseif mb then
                case = g.b_only
            end
            if case then
                table.insert(icons, hint_icon(case.item, case.tip))
            end
        elseif def.list and member[def.list] then
             table.insert(icons, hint_icon(def.item, def.tip))
             table.insert(icons, hint_icon(def.item, def.tip))
         end
         end

Revision as of 14:10, 12 July 2026

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 = "...", item = "...", tip = "..." }
-- The icon is shown when the ability is a member of `list`.
local CONFIG = {
    { list = "melee",           item = "Melee Lifesteal",  tip = "Benefits from melee items" },
    { list = "movementbased",   item = "Slowing Hex",      tip = "Disabled by Slowing Hex" },
	{ list = "debuffresist",    item = "Debuff Reducer",   tip = "Duration reduced by Debuff Resist" },
    { list = "heal",            item = "Healing Booster",  tip = "Healing amplified by Healing Booster and affected by healing reduction" },
    { list = "reactivebarrier", item = "Reactive Barrier", tip = "Triggers Reactive Barrier" },
    { 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 = "On-shot effect prevented by Plated Armor" },
}

-- 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

-- One full-size hint icon with a tooltip.
local function hint_icon(item, tip)
    return '<span class="ability-hint">' .. icon_img(item)
        .. '<span class="ability-hint-tip">' .. 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 icons = {}
    for _, def in ipairs(CONFIG) do
        if AbilityTable.is_member(def.list, record, num) then
            table.insert(icons, hint_icon(def.item, def.tip))
        end
    end

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

return p