Module:Resource
Jump to navigation
Jump to search
This module handles displaying resource costs. It can:
- Handle multiple resources at once. The input is a comma separated list of resource names.
- Handle auto-categorisation for actions based on resource consumption via the
categoriesfunction. This is not done implicitly so page generators must call this additional function. - Display in multiple formats suitable for inline usage or for compact table columns.
End users should invoke this module through the wrapper template: {{Resource}}.
File tree
- Module:Resource
- Module:Resource/data: Defines all the resources and their associated icons, links, categories, etc.
- Module:Resource/doc: Documentation page
- Template:Resource: Wrapper template for end users
Parameters
| Parameter | Meaning |
|---|---|
| Unnamed parameter | A comma separated list of resources with an optional count parameter separated by : List → Term | Term, Term |
force plural
|
Boolean flag to force icon names to always use their plural forms. Default is no. |
icons only
|
Boolean flag to show only the icon names. Full resource names are visible in hover-over tooltips. Default is no. |
show links
|
Boolean flag to make resource names into links to the appropriate pages. Default is no. |
icon size
|
Adjust the size of the resource icons. Default is 20 and for inline text, larger icons should not be used. |
Resource types
The available resource types are as follows:
| Resource | Name and aliases |
|---|---|
| Actions | action |
| Bonus Actions | bonus, ba, bonus action |
| Reactions | reaction |
| Movement Speed | movement, movement m, m |
| Movement Speed (Half cost) | half movement, 1/2 movement |
| Level 1 Spell Slots | spell1, s1, level1, l1 |
| Level 2 Spell Slots | spell2, s2, level2, l2 |
| Level 3 Spell Slots | spell3, s3, level3, l3 |
| Level 4 Spell Slots | spell4, s4, level4, l4 |
| Level 5 Spell Slots | spell5, s5, level5, l5 |
| Level 6 Spell Slots | spell6, s6, level6, l6 |
| Level 3 Shadow Spell Slots | shadowspell3, shadow spell, ss3, shadowlevel3, sl3 |
| Warlock Spell Slots | wspell, wsp |
| Arcane Arrows | arcarr, aa, arcane arrow |
| Arcane Recovery Charges | arcrec, ar, arcane recovery |
| Bardic Inspirations | bi, bardin, bardic inspiration |
| Bladesong Power | bladesong, bs, bsp, bladesong power |
| Channel Divinity Charges | cd, chadiv, channel divinity |
| Channel Oath Charges | co, oath, chao, chaoat, channel oath |
| Cosmic Omens | cos, cosmic, omen, cosmic omen |
| Eyestalk actions | es, eyestalk, eyestalk action |
| Fungal Infestation Charges | fi, fnginf, fungal infestation |
| Ki Points | ki |
| Lay on Hands Charges | loh, lh, layonh, lay on hands |
| Luck Points | luck, lp, lukpnt, luck point |
| Natural Recovery Charges | natrec, nr, natural recovery |
| Rage Charges | rage, rg |
| Sorcery Points | sp, srcpnt, sorcery, sorcery point |
| Star Maps | starmap, sm, star map |
| Superiority Dice | supdie, sd, superiority die |
| Tides of Chaos Charges | toc, tides, tides of chaos |
| Writhing Currents | wc, writhing, writhing current |
| Wild Shape Charges | ws, wldshp, wildshape, wild shape |
| War Priest Charges | wp, warpri, war priest |
Examples
| Example | Markup | Renders as |
|---|---|---|
| Basic usage | {{#invoke: Resource | main | action}} | Action |
| Optional count specified | {{#invoke: Resource | main | ki:3 }} | 3 Ki Points |
| Multiple resources | {{#invoke: Resource | main | action, bonus, spell1}} | Action + Bonus Action + Level 1 Spell Slot |
| Movement speed | {{#invoke: Resource | main | bonus, m:3 }} | Bonus Action + 3 m / 10 ft Movement Speed |
| Icons only | {{#invoke: Resource | main
| action, bonus, spell1
| icons only = yes
}} | + + |
local getArgs = require("Module:Arguments").getArgs
local data = mw.loadData("Module:Resource/data")
local resources = data.resources
local aliases = data.aliases
local alias_warnings = data.alias_warnings
local p = {}
-- Non-breaking thin space character
local nbts = " "
local function flag_is_set(args, flag)
-- Standardise string by trimming whitespace and converting to lowercase
local value = string.lower(string.match(args[flag] or "", "^%s*(.-)%s*$"))
return value == "y" or value == "yes" or value == "1" or value == "t" or value == "true"
end
local function get_resource(name)
-- Standardise string by trimming whitespace and converting to lowercase
local name = string.lower(string.match(name, "^%s*(.-)%s*$"))
if resources[aliases[name]] then
return resources[aliases[name]]
else
mw.addWarning(string.format(
"Unknown resource name: \"%s\"",
name
))
return {
name = "Unknown",
plural = "Unknown",
icon = "Alert Icon.png",
category = "Pages with unknown resources"
}
end
end
local function resource_icon(resource, args)
local size = args["icon size"] or 20
-- Image alt text should be blank unless _only_ the icon is displayed
-- If this not blank, copy-pasting or TextExtract of something like "costs an {{r|action}"
-- will give "costs an Action Icon.png action"
local alt = ""
if flag_is_set(args, "icons only") then
alt = resource.name
end
if resource.cropping then
-- Crop the icon. This is used for some icons which have large amounts of whitespace
return string.format(
"<span style=\"display: inline-block; height: %dpx; width: %dpx; margin-left: %dpx; margin-top: %dpx\">",
size,
size,
-size * (resource.cropping)/100,
-size * (resource.cropping)/100
) .. string.format(
"[[File:%s|link=|x%dpx|alt=%s|class=bg3wiki-icon nowrap]]",
resource.icon,
size * (100 + resource.cropping)/100,
alt,
resource.name
) .. "</span>"
else
return string.format(
"[[File:%s|link=|x%dpx|alt=%s|class=bg3wiki-icon nowrap]]",
resource.icon,
size,
alt,
resource.name
)
end
end
local function print_resource(resource, count, args)
local name = resource.name
local count = count:match("^%s*(.-)%s*$")
local count_num = tonumber(count)
if ((count ~= "") and (count_num ~= 1)) or flag_is_set(args, "force plural") then
name = resource.plural or resource.name .. "s"
end
if flag_is_set(args, "show links") and resource.link then
name = string.format("[[%s|%s]]", resource.link, name)
end
local amount = ""
-- Movement has a special format when count is specified. It is displayed is both m and ft
if count_num ~= nil and resource.name:find("Movement") ~= nil then
local m = count_num
if m >= 2 then
amount = string.format("%.0f%sm / %.0f%sft ", m, nbts, (m * 10)/3, nbts)
else
amount = string.format("%.1f%sm / %.0f%sft ", m, nbts, (m * 10)/3, nbts)
end
elseif count ~= "" and count_num ~= 1 then
amount = count .. " "
end
local icon = resource_icon(resource, args)
if flag_is_set(args, "icons only") then
local tooltip = string.format([[<span aria-label="%s">%s</span>]], resource.name, icon)
if count ~= "" and count_num ~= 1 and resource.name:find("Movement") == nil then
return count .. " " .. tooltip
else
return tooltip
end
else
return icon .. nbts .. amount .. name
end
end
-- Print the resource list
function p.main(frame, args)
local args = args or getArgs(frame)
local terms = args[1] or "Unknown"
local result = ""
-- Parse comma separated list of resource names
for term in terms:gmatch("[^,]+") do
-- Split on ":"" if the optional count is specified
local sep_idx = term:find(":") or 1000
local name = term:sub(0, sep_idx - 1)
local count = term:sub(sep_idx + 1, -1)
result = result .. print_resource(get_resource(name), count, args) .. " + "
end
result = result:sub(0, -9)
return result
end
-- Add a page to the relevant categories for actions that consume these resources
function p.categories(frame, args)
local args = args or getArgs(frame)
local terms = args[1]
if terms == nil or terms == "" then
return ""
end
local result = ""
-- Parse comma separated list of resource names
for term in terms:gmatch("[^,]+") do
-- Split on ":"" if the optional count is specified
local sep_idx = term:find(":") or 0
local name = term:sub(0, sep_idx - 1)
local category = get_resource(name).category
if category then
result = result .. string.format("[[Category:%s]]\n", category)
end
end
return result
end
-- Print a formatted list of all the resources for documentation pages
function p.resource_table(frame, args)
local args = args or getArgs(frame)
local result = ""
for _, warning in ipairs(alias_warnings) do
result = result .. frame:expandTemplate{
title = "Warning",
args = { warning }
} .. "<br>"
end
result = result .. [[<table class="wikitable">
<caption>List of resources</caption>
<tr>
<th>Resource</th>
<th>Name and aliases</th>
</tr>
]]
for _, resource in ipairs(resources) do
local names = ""
for _, alias in ipairs(resource.aliases or {}) do
names = names .. string.format("<code>%s</code>, ", alias)
end
names = names:sub(0,-3)
result = result .. string.format(
"<tr><td>%s</td><td>%s</td></tr>\n",
print_resource(resource, "", args),
names
)
end
result = result .. "</table>"
return result
end
return p