Module:EnemyStats2/Table
Jump to navigation
Jump to search
Implements the functionality in Template:EnemyStats2/Table.
local Cargo = mw.ext.cargo
local Histogram = require("Module:Histogram")
local Regions = require("Module:Regions2")
local TableArguments = require("Module:TableArguments")
local Types = require("Module:EnemyStats2/Types")
local Utils = require("Module:EnemyStats2/Utils")
local function query(search_parameter, search_value, hs)
local tables = {
"EnemyStats2=S",
"EnemyStats2Types=T",
}
local fields = {
"S.name=name",
"icon",
"article",
"is_boss",
"champion_of",
"minion_of",
-- Cargo doesn't support CASE statements?
[[IF(is_boss=1, 3,
IF(champion_of IS NOT NULL, 1,
IF(minion_of IS NOT NULL, 2,
0
)))=tier_key]],
"region",
"GROUP_CONCAT(T.type ORDER BY T.type SEPARATOR ' ')=types"
}
for _, stat in ipairs(Utils.STATS) do
table.insert(fields, stat.name)
end
local join_keys = {
"S.name=T.name"
}
local order_keys = {
"tier_key",
"hp",
"name",
}
local where = nil
if search_parameter == "name" then
where = ("S.name='%s'"):format(search_value)
elseif search_parameter == "category" then
where = ("category='%s'"):format(search_value)
elseif search_parameter == "type" then
table.insert(tables, "EnemyStats2Types=F")
table.insert(join_keys, "S.name=F.name")
where = ("F.type='%s'"):format(search_value)
elseif search_parameter == "region" then
where = ("region='%s'"):format(search_value)
else
-- invalid filter
return
end
local enemies = Cargo.query(
table.concat(tables, ","),
table.concat(fields, ","),
{
groupBy="name",
join=table.concat(join_keys, ","),
orderBy=table.concat(order_keys, ","),
where=where
}
)
for _, enemy in ipairs(enemies) do
Utils.parse_row(enemy, hs)
end
return enemies
end
local function fetch_all(args)
local hs = Histogram._load_table("EnemyStats2Histograms")
local enemies = {}
for _, row in ipairs(args) do
if #row >= 2 then
local fetched = query(row[1], row[2], hs) or {}
for _, enemy in ipairs(fetched) do
table.insert(enemies, enemy)
end
end
end
return enemies
end
local function text_cell(label, sort_key)
return mw.html.create("td")
:attr("data-sort-value", sort_key)
:addClass("ctr")
:wikitext(label)
end
local function name_cell(enemy)
local label = enemy.name
if enemy.article ~= nil then
label = ("[[%s|%s]]"):format(enemy.article, label)
end
if enemy.icon ~= nil then
label = ("[[File:%s|40px]]<br>"):format(enemy.icon) .. label
end
return text_cell(label, enemy.name)
end
local function region_cell(enemy)
local region = enemy.region
if region == nil then
return text_cell("''Any''", 0)
elseif Regions[region] == nil then
return text_cell(region, -1)
end
region = Regions[region]
return text_cell(
("[[%s]]"):format(region.article),
region.sort_key
)
end
local function types_cell(enemy)
local type_links = {}
for i, t in ipairs(enemy.types) do
if Types[t] == nil then
type_links[i] = t
else
type_links[i] = Types[t]:link()
end
end
return text_cell(table.concat(type_links, "<br>"))
end
local function tiers_cell(enemy)
local tiers = {}
if enemy.is_boss == 1 then
table.insert(tiers, "[[Bosses (Darkest Dungeon II)|Boss]]")
end
if enemy.champion_of ~= nil then
table.insert(tiers, "Champion")
end
if enemy.minion_of ~= nil then
table.insert(tiers, "Minion")
end
return text_cell(table.concat(tiers, "<br>"), enemy.tier_key)
end
local function _render(enemies)
local res = mw.html.create("table")
:addClass("tablebgdd2")
:addClass("sortable")
local header = res:tag("tr")
header:tag("th")
:wikitext("Enemy")
header:tag("th")
:wikitext("[[Regions|Region]]")
header:tag("th")
:wikitext("[[Enemy Type (Darkest Dungeon II)|Types]]")
header:tag("th")
:wikitext("Tiers")
for _, stat in ipairs(Utils.STATS) do
header:tag("th")
:wikitext(stat:icon())
end
for _, enemy in ipairs(enemies) do
local row = res:tag("tr")
:attr("id", enemy.name)
row:node(name_cell(enemy))
row:node(region_cell(enemy))
row:node(types_cell(enemy))
row:node(tiers_cell(enemy))
for _, stat in ipairs(Utils.STATS) do
row:node(stat:render(enemy))
end
end
return res
end
local function render(frame)
local args = TableArguments.getArgs(frame)
local enemies = fetch_all(args)
return _render(enemies)
end
return {render=render}