Module:AbilityHints: Difference between revisionsGive feedback
Render hint icons without the item link so the icon no longer triggers the native title and infobox-tooltip gadget; only the custom hint tooltip remains (with help from vergir-bot LLM) |
Use the standard interacts text for the enhanced state (with help from vergir-bot LLM) |
||
| (33 intermediate revisions by 7 users not shown) | |||
| Line 1: | Line 1: | ||
-- | -- Small item icons on ability cards showing how an ability interacts with items (dispellable, reduced, blocked, etc.). | ||
-- Used by Template:AbilitySection. Styles are there too. | |||
-- | |||
-- | -- label_dict_key names the [[Data:Dictionary]] entry holding the tooltip text. It is | ||
-- resolved at render time rather than here, so the tooltip follows the page language | |||
-- and so no frame is needed while the module is still loading. | |||
local CONFIG = { | |||
{ list = "melee", file = "Melee Lifesteal.png", label_dict_key = "AbilityHintsMelee" }, | |||
{ list = "dontbreakstealth", file = "Veil Walker.png", label_dict_key = "AbilityHintsDontBreakStealth" }, | |||
{ list = "movementbased", file = "Slowing Hex.png", label_dict_key = "AbilityHintsMovementBased" }, | |||
{ list = "debuffresist", file = "Debuff Reducer.png", label_dict_key = "AbilityHintsDebuffResist" }, | |||
{ list = "heal", file = "Healing Booster.png", label_dict_key = "AbilityHintsHeal" }, | |||
{ list = "healingtempo", file = "Healing Tempo.png", label_dict_key = "AbilityHintsHealingTempo" }, | |||
{ list = "reactivebarrier", file = "Reactive Barrier.png", label_dict_key = "AbilityHintsReactiveBarrier" }, | |||
{ list = "dispelmagic", file = "Dispel Magic.png", label_dict_key = "AbilityHintsDispelMagic" }, | |||
{ list = "indomitable", file = "Indomitable.png", label_dict_key = "AbilityHintsIndomitable" }, | |||
{ list = "unstoppable", file = "Unstoppable.png", label_dict_key = "AbilityHintsUnstoppable" }, | |||
{ list = "platedarmor", file = "Plated Armor.png", label_dict_key = "AbilityHintsPlatedArmor" }, | |||
{ list = "summons", file = "Monster Rounds.png", label_dict_key = "AbilityHintsSummons" }, | |||
} | |||
-- Tooltip wording for a manually placed icon, keyed by its iconbox state. Each entry | |||
-- takes the item title as {{{1}}}, so translations can put the object where their | |||
-- grammar wants it rather than always after the verb. The enhanced state has no entry | |||
-- of its own: the glow already marks it, so it falls through to the normal wording. | |||
local STATE_DICT_KEYS = { | |||
normal = "AbilityHintsInteracts", | |||
disabled = "AbilityHintsInteractsNot", | |||
partial = "AbilityHintsInteractsPartial", | |||
} | |||
local AbilityTable = require("Module:AbilityTable") | local AbilityTable = require("Module:AbilityTable") | ||
local | local dictionary = require("Module:Dictionary") | ||
local | local resource_lookup = mw.loadJsonData("Data:ResourceLookup.json") | ||
local item_data = mw.loadJsonData("Data:ItemData.json") | |||
local p = {} | local p = {} | ||
-- Display order. | -- Display order: item type (Weapon => Vitality => Spirit), then cost, then name. | ||
local function sort_key(file) | |||
local base = mw.ustring.lower((file:gsub('%.%w+$', ''))) | |||
local entry = resource_lookup[base] | |||
local item = (entry ~= nil and entry.type == 'item') and item_data[entry.key] or nil | |||
local | if item == nil then | ||
return { 99, math.huge, base } | |||
end | |||
local slot = item["Slot"] | |||
{ | local slot_rank = (slot == "Weapon" and 1) or (slot == "Armor" and 2) or (slot == "Tech" and 3) or 98 | ||
return { | |||
slot_rank, | |||
tonumber(item["Cost"]) or math.huge, | |||
mw.ustring.lower(item["Name"] or base), | |||
} | |||
end | |||
{ | local function compare(a, b) | ||
} | for i = 1, 3 do | ||
if a.sort[i] ~= b.sort[i] then return a.sort[i] < b.sort[i] end | |||
end | |||
return false | |||
end | |||
-- partial: split the icon so the top-left half is grayscale (mirrors the iconbox-partial box icon). | |||
-- An empty link makes the icon non-clickable; automatic hints link from their tooltip text instead. | |||
local function icon_img(file, link, partial) | |||
link = link or '' | |||
if partial then | |||
return '<span class="ability-hint-icon"><span class="ability-hint-split">' | |||
.. '[[File:' .. file .. '|24px|link=' .. link .. ']]' | |||
.. '<span class="ability-hint-split-gray">[[File:' .. file .. '|24px|link=]]</span>' | |||
.. '</span></span>' | |||
end | |||
return '<span class="ability-hint-icon">[[File:' .. file .. '|24px|link=' .. link .. ']]</span>' | |||
end | |||
local function hint_icon(def) | |||
return '<span class="ability-hint">' .. icon_img(def.file) | |||
.. '<span class="ability-hint-tip">' .. dictionary.translate(def.label_dict_key) .. '</span></span>' | |||
end | |||
local function manual_icon(m) | |||
local cls = 'ability-hint' | |||
local dict_key = STATE_DICT_KEYS.normal | |||
local partial = false | |||
if m.state == 'disabled' then | |||
cls = cls .. ' ability-hint--disabled' | |||
dict_key = STATE_DICT_KEYS.disabled | |||
elseif m.state == 'partial' then | |||
dict_key = STATE_DICT_KEYS.partial | |||
partial = true | |||
elseif m.state == 'enhanced' then | |||
cls = cls .. ' ability-hint--enhanced' | |||
end | |||
local tip = dictionary.translate(dict_key, nil, nil, { m.title }) | |||
.. '<br>' .. dictionary.translate('AbilityHintsClickReveal') | |||
return '<span class="' .. cls .. '">' .. icon_img(m.file, '#' .. m.anchor, partial) | |||
.. '<span class="ability-hint-tip">' .. tip .. '</span></span>' | |||
end | |||
function p.get_icons(ability_key, ability_num, manual) | |||
manual = manual or {} | |||
local manual_by_file = {} | |||
for _, m in ipairs(manual) do | |||
manual_by_file[mw.ustring.lower(m.file)] = m | |||
end | |||
local entries = {} | |||
local placed = {} | |||
local num = tonumber(ability_num) | local num = tonumber(ability_num) | ||
for _, def in ipairs(CONFIG) do | for _, def in ipairs(CONFIG) do | ||
if AbilityTable.is_member(def.list, ability_key, num) then | |||
local key = mw.ustring.lower(def.file) | |||
local m = manual_by_file[key] | |||
if m ~= nil then | |||
table.insert(entries, { file = m.file, html = manual_icon(m) }) | |||
placed[key] = true | |||
else | |||
table.insert(entries, { file = def.file, html = hint_icon(def) }) | |||
end | |||
end | |||
end | end | ||
for _, m in ipairs(manual) do | |||
for _, | if not placed[mw.ustring.lower(m.file)] then | ||
if | table.insert(entries, { file = m.file, html = manual_icon(m) }) | ||
table.insert( | |||
end | end | ||
end | end | ||
if # | if #entries == 0 then return '' end | ||
for _, e in ipairs(entries) do e.sort = sort_key(e.file) end | |||
table.sort(entries, compare) | |||
local icons = {} | |||
for _, e in ipairs(entries) do table.insert(icons, e.html) end | |||
return '<div class="ability-section-hints">' .. table.concat(icons) .. '</div>' | return '<div class="ability-section-hints">' .. table.concat(icons) .. '</div>' | ||
end | end | ||
return p | return p | ||