Module:Sandbox/Lakelimbo/TypeEffectiveness
Charmander:
Swampert:
Shedinja:
Tinkaton:
Dusknoir:
Ferrothorn:
Malamar:
Goodra (sap sipper):
--[[
This module calculates the type effectiveness of a Pokémon's types.
It's meant to replace the current {{TypeEffectiveness}} template.
EXPERIMENTAL! Do not use it yet!
TO-DO:
- Fix some design issues
- Decide how abilities will impact the calculation
- Decide how generations will impact the calculation
--]]
local type_effectiveness = {}
local lang = mw.language.getContentLanguage()
local types = require("Module:Sandbox/Lakelimbo/TypeEffectiveness/Types")
local utils = require("Module:Sandbox/Lakelimbo/Utils")
local container = mw.html.create("div"):addClass("roundy")
---The main part of the module, which takes the arguments and outputs the
---damage value
---@return string
function type_effectiveness.main(frame)
---First type, mandatory
---@type string
local type_1 = utils.trim_lower(frame:getParent().args[1])
or utils.trim_lower(frame:getParent().args["type1"])
or "normal"
---Second type, optional
---@type string | nil
local type_2 = utils.trim_lower(frame:getParent().args[2]) or utils.trim_lower(frame:getParent().args["type2"])
-- If for whatever reason `type_2` is defined but not `type_1`
if type_2 and not type_1 then
container
:wikitext("For some reason you have set the secondary type but not the first. Plase fix this.")
:allDone()
return tostring(container)
end
container
:tag("div")
:css({
["font-weight"] = "bold",
["padding"] = "0.5rem",
["color"] = "#fff",
})
:wikitext("Something here on top...")
:done()
---Table for the resulting damage calculation
local results = {
["Weaknesses"] = {},
["Resistances"] = {},
["Immunities"] = {},
}
-- Loop for each type and push it to its respective
-- place on `results`
for i = 1, #types.types do
---@type number
local factor = calculate_damage(type_1, type_2, types.types[i])
local group
if factor > 1 then
group = "Weaknesses"
elseif factor == 0 then
group = "Immunities"
elseif factor < 1 then
group = "Resistances"
end
if factor ~= 1 then
table.insert(results[group], types.types[i])
end
end
local groups = container:tag("div"):css({
["display"] = "flex",
["flex-wrap"] = "wrap",
["gap"] = "1px",
})
-- Loop once again, now to create each an element
-- for each table inside of `results`
for group, values in pairs(results) do
local subgroup = groups
:tag("div")
:css({
["background-color"] = "#fff",
["flex"] = "175px",
})
:tag("div")
:css({
["background-color"] = "#{{" .. type_1 .. " color dark}}",
["color"] = "#fff",
["padding"] = "0.333rem",
})
:wikitext(group)
:done()
:tag("div")
:css({
["padding"] = "0.25rem"
})
if #values > 0 then
for _, value in ipairs(values) do
local factor = calculate_damage(type_1, type_2, value)
subgroup:node(type_label(value, factor, frame)):done()
end
else
subgroup:node(type_label()):done()
end
subgroup:done()
end
-- At this point, if `type_2` is nil, it's better to just
-- fallback to `type_1` instead of creating multiple other
-- check conditions for the colors below
if not type_2 then
type_2 = type_1
end
container
:css({
["border"] = "2px solid #{{" .. type_2 .. " color}}",
["background-color"] = "#{{" .. type_1 .. " color}}",
["text-align"] = "center",
["margin"] = "auto",
["max-width"] = "600px",
["overflow"] = "hidden",
})
:allDone()
return tostring(container)
end
---This function will calculate the damage between the user's types
---and a specific opposing (attacking) type.
---@param user_type_1 string
---@param user_type_2 string | nil
---@param opposing_type string
---@return number
function calculate_damage(user_type_1, user_type_2, opposing_type)
---@type number | nil
local damage
if user_type_2 then
damage = types.effectiveness[opposing_type][user_type_1] * types.effectiveness[opposing_type][user_type_2]
else
damage = types.effectiveness[opposing_type][user_type_1]
end
return damage
end
---Creates a label with {{TypeIcon}} and also insert the
---damage factor on the side.
---@param name string | nil
---@param factor number | nil
---@return string
function type_label(name, factor, frame)
local label = mw.html.create("div")
if not name then
return label
:css({
["background-color"] = "#000",
["color"] = "#fff",
["padding"] = "0.25rem",
["border-radius"] = "50px",
["font-weight"] = "bold",
["width"] = "84px",
["margin"] = "auto",
})
:wikitext("None")
:allDone()
end
local factor_color = "#000"
if factor == 4 then
factor_color = "#ff0000"
elseif factor == 0.25 then
factor_color = "#0000ff"
end
name = lang:ucfirst(name)
label:wikitext(frame:expandTemplate({title = "TypeIcon", args = { name }}))
if factor ~= 0 then
label:tag("span")
:css({
["display"] = "inline-block",
["width"] = "25px",
["padding"] = "3px 0",
["background-color"] = factor_color,
["color"] = "#fff",
["border-radius"] = "100%",
["font-weight"] = "bold",
}):wikitext(utils.fraction(factor) .. "×")
end
label:allDone()
return label
end
return type_effectiveness
Categories
- No categories associated with this article