Module:Damage display/format
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Damage display/format/doc
local formatting = {}
-- Special damage values, mostly a legacy of {{Damage info}}
local special_values = {
["weapon"] = function(frame)
return "Normal weapon damage"
end,
["half weapon"] = function(frame)
return "1/2 Normal weapon damage"
end,
["superiority die"] = function(frame)
return frame:expandTemplate{
title = "SmallIcon",
args = { "Superiority Die d8 Icon.png" },
} .. "[[Battlemaster#Superiority_dice|Superiority Die]]"
end,
["unarmed"] = function(frame)
return frame:expandTemplate{
title = "DamageColor",
args = { "Bludgeoning", "Unarmed" }
} .. frame:expandTemplate{
title = "DamageType",
args = { "Bludgeoning" }
}
end,
}
-- Translation and rotation to position each dice image in a way that replicates
-- the in-game damage preview
local dice_image_transform = {
[1] = "translate( 0%, 0%)",
[2] = "translate( 40%, -30%) rotate(20deg)",
[3] = "translate(-35%, -25%) rotate(40deg)",
[4] = "translate( 40%, -70%) rotate(25deg)",
[5] = "translate(-40%, -68%) rotate(40deg)",
}
-- Render the scattered damage dice to replicate how it looks in-game
function formatting.damage_dice(frame, damage_dice, width)
local n_dice = #damage_dice
-- Determine width of overall element which is dependent on number of dice
local elem_width = width
if n_dice >= 2 then
elem_width = elem_width * 1.4
end
-- Determine padding which is dependent on number of dice
local left_padding = 0
if n_dice >= 3 then
left_padding = width * 0.4
end
local top_padding = 0
if n_dice >= 2 and n_dice < 4 then
top_padding = width * 0.3
elseif n_dice >= 4 then
top_padding = width * 0.7
end
local element = mw.html.create("span")
:css("display", "block")
:css("position", "relative")
:css("width", elem_width .. "px")
:css("height", width .. "px")
:css("margin-left", left_padding .. "px")
:css("padding-top", top_padding .. "px")
for i, dice in ipairs(damage_dice) do
if i > #dice_image_transform then
break
end
element:tag("span")
:css("z-index", n_dice - i)
:css("position", "absolute")
:css("transform", dice_image_transform[i])
:wikitext(string.format(
"[[File:%s %s.png|link=|alt=|x%s]]",
dice["value"],
dice["type"],
width .. "px"
))
end
return element
end
-- Format the damage values in a list format
function formatting.damage(frame, args, data, header)
-- Flexbox that holds the dice images on the left and damage values on the right
local element = mw.html.create("div")
:css("display", "flex")
:css("align-items", "center")
:css("width", "fit-content")
-- Left div element containing the damage dice images
local dice_size = tonumber(args["dice size"] or args["dice width"] or "30")
if dice_size > 0 and #data.dice > 0 then
element:node(formatting.damage_dice(frame, data.dice, dice_size))
end
-- Right div element containing the damage instance list
local damage_div = element:tag("div")
for i, damage in ipairs(data.instances) do
local damage_text = ""
if i > 1 then
damage_text = damage_text .. " + "
end
local value = damage["value"]
if value == "weapon" then
damage_text = damage_text .. "Normal weapon damage"
elseif special_values[value] then
-- Handle some special values
damage_text = damage_text .. special_values[value](frame)
else
damage_text = damage_text .. frame:expandTemplate{
title = "DamageColor",
args = { damage["type"], value }
} .. frame:expandTemplate{
title = "DamageType",
args = { damage["type"] }
}
end
-- Extra info field to add free-form annotation to the damage instance
if damage["info"] then
damage_text = damage_text .. " (" .. damage["info"] .. ")"
end
damage_div:tag("div")
:css("white-space", "nowrap")
:wikitext(damage_text)
end
if args["format"] ~= "nosummary" then
local header_text = header .. ": "
-- Damage range preview
if data.min_roll and data.max_roll then
if data.min_roll ~= data.max_roll then
header_text = header_text .. data.min_roll .. "~" .. data.max_roll
elseif data.max_roll > 0 then
header_text = header_text .. data.max_roll
end
if data.uneval_mods and data.max_roll > 0 then
header_text = header_text .. " + modifiers"
end
end
local header = mw.html.create("dt"):wikitext(header_text)
return tostring(header) .. tostring(element)
else
return tostring(element)
end
end
-- Format the damage values in a compact inline format with less details
function formatting.damage_inline(frame, args, data)
local result = ""
mw.log(data)
for _, kind in pairs(data) do
mw.log(kind)
for i, damage in ipairs(kind.instances) do
local value = damage["value"]
if i > 1 then
result = result .. " + "
end
if special_values[value] then
-- Handle some legacy special values
result = result .. special_values[value](frame)
else
result = result .. frame:expandTemplate{
title = "DamageColor",
args = { damage["type"], value }
} .. frame:expandTemplate{
title = "DamageType",
args = { damage["type"] }
}
end
end
end
return result
end
return formatting