From Dark and Darker Wiki

(Undoing previous change for row)
(Table header is made redundant and unnecessary by the tab toggles)
 
(One intermediate revision by the same user not shown)
Line 166: Line 166:


---Create monster table wikitext
---Create monster table wikitext
---- Test on wiki with:  mw.log(p.draw_table({args={"Back","Craftable"}}))
----                    mw.log(p.draw_table({args={"Head","Uncraftable"}}))
--- @param frame table
--- @param frame table
--- @return string
--- @return string
Line 181: Line 179:
return concat(wikitext)
return concat(wikitext)
end
end
--[=[
################################################################################
                        Functions for individual armor pages
################################################################################
]=]
local function tab_toggle(title,content,active,tabid)
local class = ""
if active then
class = " class='selected-tab tab-toggle tab'"
else
class = " class='tab-toggle tab'"
end
return string.format("<div style='display:inline-block' %s data-tabid='%s' data-tab='%s' title='%s'>%s</div>",class,tabid,title,title,content)
end
local function reference_table(wt,table_type)
local types_order = {"Head","Chest","Legs","Hands","Foot","Back"}
local separator = "]] • [["
wt[#wt+1] = "<table cellspacing='0' class='wikitable sortable jquery-tablesorter' style='width:100%;text-align:center;vertical-align:middle;margin-top:15px'>"
for _,armor_type in ipairs(types_order) do
wt[#wt+1] = string.format("<tr><td style='font-weight:bold; background-color:rgb(220,220,220,0.2); width:10%%'>[[Armors#%s|%s]]</td><td style='text-align-last:left;padding:10px 25px'>",armor_type,armor_type)
if AD[armor_type][table_type] then
wt[#wt+1] = "[["
for i,v in ipairs(AD[armor_type][table_type]) do
if i~=1 then wt[#wt+1] = separator end
wt[#wt+1] = v
end
wt[#wt+1] = "]]"
end
wt[#wt+1] = "</td></tr>"
end
wt[#wt+1] = "</table>"
end
function p.references()
local table_types = {"Uncraftable","Craftable"}
local wt = {}
wt[#wt+1] = "<br><h2>References</h2>"
wt[#wt+1] = "<div style='display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;margin-top:15px'>"
for i,table_type in ipairs(table_types) do
wt[#wt+1] = tab_toggle(table_type,table_type.." Armors",i==1,"")
end
wt[#wt+1] = "</div>"
for i,table_type in ipairs(table_types) do
wt[#wt+1] = "<div class='"..table_type.."-data'"
if i==1 then wt[#wt+1] = ">" else wt[#wt+1] = "style='display:none'>" end
reference_table(wt,table_type)
wt[#wt+1] = "</div>"
end
return concat(wt)
end




return p
return p
-- Test on wiki with
-- mw.log(p.draw_table({args={"Back","Craftable"}}))
-- mw.log(p.draw_table({args={"Head","Uncraftable"}}))
-- mw.log(p.references())

Latest revision as of 07:31, 13 April 2026

Overview

Functions for making Armor table. Data comes from Data:Armor.json.

Functions

draw_table

Creates a table of armors

Parameters

  • 1 - <Slot Type>
  • 2 - Craftable or Uncraftable


draw_table examples

Back


{{#invoke:Armor|draw_table|Back|Craftable}}


NameArmor/magical RatingAttributesOther
Armor Rating
11
Will
2
Spell Casting Speed
3%
Armor Rating
10
Agility
3
Action Speed
1%
Armor Rating
15
Dexterity
1
Vigor
1
Will
1
Resourcefulness
1
Luck
40
All Attributes
1
Armor Rating
19
Strength
2
Dexterity
2
Will
2
Armor Rating
8
Vigor
3
Debuff Duration Bonus
2%


Head


{{#invoke:Armor|draw_table|Head|Uncraftable}}


NameClass RequirementsMovement SpeedArmor/magical RatingAttributesOther
Wizard
Warlock
Druid
Sorcerer
-2
Armor Rating
21
22
23
24~25
26~27
28
29
Will
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Armet.pngPlate
Armet
Fighter-5
Armor Rating
54
55
56~57
58~59
60~61
62
63
Strength
1
2
2
3
4
5
5
Projectile Damage Reduction
2.1%
Headshot Damage Reduction
23%
Fighter
Barbarian
-4
Armor Rating
26
27
28~29
30~31
32~33
34
35
Magical Resistance
30
Dexterity
1
2
2
3
4
5
5
Projectile Damage Reduction
1.2%
Headshot Damage Reduction
15%
Warlock-3
Armor Rating
33
34
35~36
37~38
39~40
41
42
Will
1
1
1
2
2
3
3
Projectile Damage Reduction
1.8%
Headshot Damage Reduction
15%
Headshot Damage Modifier
2.5%
3%
3%
3%
3.5%
3.5%
4%
Ranger-2
Armor Rating
24
25
26
27
28
29
30
Dexterity
1
1
1
2
2
3
3
Headshot Damage Reduction
8%
Headshot Damage Modifier
2.5%
3%
3%
3%
3.5%
3.5%
4%
Cleric
Sorcerer
-2
Armor Rating
21
22
23
24~25
26~27
28
29
Magical Resistance
20
Resourcefulness
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Fighter
Cleric
-3
Armor Rating
39
40
41~42
43~44
45~46
47
48
Magical Resistance
10
Agility
1
2
2
3
4
5
5
Projectile Damage Reduction
0.6%
Headshot Damage Reduction
13%
Cleric
Sorcerer
-2
Armor Rating
23
24
25
26~27
28~29
30
31
Magical Resistance
20
Will
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Coif.pngCloth
Coif
Wizard
Cleric
Druid
Sorcerer
-1
Armor Rating
17
18
19
20~21
22~23
24
25
Knowledge
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Fighter
Cleric
-5
Armor Rating
52
53
54~55
56~57
58~59
60
61
Strength
1
1
1
2
2
3
3
Vigor
0
1
1
1
2
2
2
Projectile Damage Reduction
1.8%
Headshot Damage Reduction
20%
Druid-2
Armor Rating
24
25
26
27~28
29~30
31
32
Strength
1
1
1
2
2
3
3
Will
0
1
1
1
2
2
2
Headshot Damage Reduction
8%
Dryad Mask.pngLeather
Dryad Mask
Warlock
Druid
-2
Armor Rating
26
27
28
29~30
31~32
33
34
Strength
1
1
1
2
2
2
2
Knowledge
1
1
1
1
2
2
2
Agility
0
1
1
1
1
2
2
Headshot Damage Reduction
10%
Druid-3
Armor Rating
31
32
33~34
35~36
37~38
39
40
Dexterity
0
1
1
1
2
2
2
Vigor
1
1
1
2
2
3
3
Headshot Damage Reduction
11%
Bard-2
Armor Rating
28
29
30
31~32
33~34
35
36
Knowledge
1
2
2
3
4
5
5
Headshot Damage Reduction
9%
Ranger
Druid
-2
Armor Rating
25
26
27
28~29
30~31
32
33
Magical Resistance
15
Strength
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Barbarian-4
Armor Rating
41
42
43~44
45~46
47~48
49
50
Magical Resistance
15
Vigor
1
2
2
3
4
5
5
Projectile Damage Reduction
1.2%
Headshot Damage Reduction
15%
Fighter
Cleric
-5
Armor Rating
55
56
57~58
59~60
61~62
63
64
Knowledge
1
2
2
3
4
5
5
Projectile Damage Reduction
2.1%
Headshot Damage Reduction
23%
Fighter
Cleric
-5
Armor Rating
58
59
60~61
62~63
64~65
66
67
Magical Resistance
-5
Vigor
1
2
2
3
4
5
5
Projectile Damage Reduction
2.1%
Headshot Damage Reduction
24%
Rogue
Bard
-2
Armor Rating
24
25
26
27
28
29
30
Dexterity
1
1
1
2
2
3
3
Headshot Damage Reduction
8%
Headshot Damage Modifier
2.5%
3%
3%
3%
3.5%
3.5%
4%
Fighter
Cleric
-3
Armor Rating
36
37
38~39
40~41
42~43
44
45
Magical Resistance
10
Knowledge
1
2
2
3
4
5
5
Projectile Damage Reduction
0.6%
Headshot Damage Reduction
13%
Bard-2
Armor Rating
29
30
31
32~33
34~35
36
37
Resourcefulness
1
2
2
3
4
5
5
Headshot Damage Reduction
10%
-3
Armor Rating
31
32
33~34
35~36
37~38
39
40
Vigor
1
2
2
3
4
5
5
Headshot Damage Reduction
11%
Mitre.pngLeather
Mitre
Cleric-2
Armor Rating
28
29
30
31
32
33
34
Will
1
1
1
2
2
3
3
Headshot Damage Reduction
11%
Undead Race Damage Bonus
5%
6%
6%
6%
7%
7%
8%
Barbarian-3
Armor Rating
37
38
39~40
41~42
43~44
45
46
Strength
0
1
1
1
2
2
2
Vigor
1
1
1
2
2
3
3
Projectile Damage Reduction
0.9%
Headshot Damage Reduction
13%
Wizard
Warlock
Druid
Sorcerer
-2
Armor Rating
26~27
Will
4
Headshot Damage Reduction
8%
Projectile Damage Reduction
2%
Fighter
Cleric
-3
Armor Rating
45~46
Magical Resistance
10
Agility
4
Projectile Damage Reduction
0.6%
Headshot Damage Reduction
15%
Rogue
Warlock
Sorcerer
-1
Armor Rating
9
Agility
2
Dexterity
2
Strength
1
Projectile Damage Reduction
2%
Rogue
Bard
-2
Armor Rating
25
Strength
2
Dexterity
2
Headshot Damage Reduction
8%
Projectile Damage Reduction
2%
Barbarian
Ranger
-3
Armor Rating
37
Strength
2
Headshot Damage Reduction
11%
Projectile Damage Reduction
2%
Headshot Damage Modifier
3.5%
Warlock-2
Armor Rating
25
26
27
28~29
30~31
32
33
Headshot Damage Reduction
8%
Outgoing Magical Healing Add
1
1
1
2
2
3
3
Magical Power
0
1
1
1
2
2
2
Fighter
Ranger
Cleric
Bard
-3
Armor Rating
35
36
37~38
39~40
41~42
43
44
Will
1
1
1
2
2
2
2
Knowledge
1
1
1
1
2
2
2
Resourcefulness
0
1
1
1
1
2
2
Projectile Damage Reduction
0.9%
Headshot Damage Reduction
14%
Ranger-2
Armor Rating
25
26
27
28~29
30~31
32
33
Agility
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Cleric-2
Armor Rating
28
29
30
31
32
33
34
Will
1
1
1
2
2
3
3
Headshot Damage Reduction
11%
Demon Race Damage Bonus
5%
6%
6%
6%
7%
7%
8%
Rogue-2
Armor Rating
25
26
27
28~29
30~31
32
33
Agility
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Sallet.pngPlate
Sallet
Fighter
Cleric
-3
Armor Rating
33
34
35~36
37~38
39~40
41
42
Strength
1
1
1
2
2
3
3
Vigor
0
1
1
1
2
2
2
Projectile Damage Reduction
0.9%
Headshot Damage Reduction
13%
Rogue
Warlock
-2
Armor Rating
18
19
20
21~22
23~24
25
26
Magical Resistance
15
Strength
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Rogue
Warlock
-1
Armor Rating
5
6
7
8
9
10
11
Agility
1
1
1
2
2
2
2
Dexterity
1
1
1
1
2
2
2
Strength
0
1
1
1
1
2
2
Fighter
Ranger
Cleric
-4
Armor Rating
40
41
42~43
44~45
46~47
48
49
Agility
1
1
1
2
2
3
3
Dexterity
0
1
1
1
2
2
2
Projectile Damage Reduction
1.2%
Headshot Damage Reduction
16%
Rogue
Bard
-2
Armor Rating
21
22
23
24
25
26
27
Strength
1
1
1
2
2
3
3
Dexterity
0
1
1
1
2
2
2
Headshot Damage Reduction
8%
Bard
Druid
-2
Armor Rating
26
27
28
29~30
31~32
33
34
Strength
1
2
2
3
4
5
5
Headshot Damage Reduction
8%
Fighter
Cleric
-5
Armor Rating
57
58
59~60
61~62
63~64
65
66
Vigor
1
1
1
2
2
3
3
Will
0
1
1
1
2
2
2
Projectile Damage Reduction
2.1%
Headshot Damage Reduction
24%
Ranger
Barbarian
-3
Armor Rating
33
34
35
36
37
38
39
Strength
1
1
1
2
2
3
3
Headshot Damage Reduction
11%
Headshot Damage Modifier
2.5%
3%
3%
3%
3.5%
3.5%
4%
Barbarian-3
Armor Rating
37
38
39~40
41~42
43~44
45
46
Agility
1
2
2
3
4
5
5
Projectile Damage Reduction
2%
Headshot Damage Reduction
15%
Fighter-4
Armor Rating
48
49
50~51
52~53
54~55
56
57
Will
1
2
2
3
4
5
5
Projectile Damage Reduction
1.8%
Headshot Damage Reduction
16%
Action Speed
1.4%
1.4%
1.4%
1.6%
1.8%
2%
2.2%
Barbarian-5
Armor Rating
50
51
52~53
54~55
56~57
58
59
Agility
1
1
1
2
2
3
3
Dexterity
0
1
1
1
2
2
2
Projectile Damage Reduction
2.1%
Headshot Damage Reduction
18%
Wizard
Warlock
-2
Armor Rating
20
21
22
23~24
25~26
27
28
Headshot Damage Reduction
8%
Magical Power
1
2
2
3
4
5
5
Memory Capacity Add
3
-2
Armor Rating
20
21
22
23
24
25
26
Vigor
1
1
1
2
2
2
2
Dexterity
1
1
1
1
2
2
2
Agility
0
1
1
1
1
2
2
Headshot Damage Reduction
5%

local p = {}
local AD = mw.loadJsonData("Data:Armor.json")
local insert = table.insert
local concat = table.concat
local is_special = {["Move Speed"]=true, ["Armor Rating"]=true, ["Magical Resistance"]=true}
local is_primitive = {["Strength"]=true, ["Vigor"]=true, ["Agility"]=true, ["Dexterity"]=true, ["Will"]=true, ["Knowledge"]=true, ["Resourcefulness"]=true}


---Get the type of the armor as a string
--- @param item table
--- @return string
local function get_type(item)
	--Assumes that the item only has one type
	for key,_ in pairs(item.types) do
		--Scribunto uses meta tables so we can't use next() here
		return key
	end
	return ""
end


---Get the size of the armor in pixels
--- @param item table
--- @return string
local function size(item)
	return tostring(item.invwidth*45).."x"..tostring(item.invheight*45).."px"
end


---Counts number of keys. Tables from Misc.json don't work with next() or the # operator
--- @param t table
--- @return number
local function count(t)
	local c = 0
	for _ in pairs(t) do c = c + 1 end
	return c
end


---Create css/html wikitext for iconbox
---@param item table
---@return string
local function iconbox(item)
	local color = "2"
	local caption = "[["..item.name
	if count(item.rarities) == 1 then
		color = item.rarities[1]
		caption = caption.."|<b class=cr"..color..">"..item.name.."</b>"
	end
	return "<div class='iconbox' style='display:inline-flex;width:max-content;max-width:initial;flex-direction:column;align-items:center;flex-wrap:wrap;white-space:pre-wrap'>"
		.."<div class='rarity"..color.." rounded relative'>"
		.."[[File:"..item.name..".png|"..size(item).."|link="..item.name.."]]"
		.."<span class='iconamount' style='pointer-events:none;color:#EEEA;font-size:16px'>"..get_type(item).."</span></div>"
		..caption.."]]</div>"
end


---Turns a list of classes into a wikitext string with line break separators
--- @param list table
--- @return string
local function classes(list)
	local wikitext = "" --classes are few enough that we can just concatenate them without worrying about performance
	local newline = ""
	for i, class in ipairs(list) do
		wikitext = wikitext..newline..class
		if i == 1 then newline = "<br>" end
	end
	return wikitext
end


---Marks up a list of values with color based on rarity
---@param values string|table
---@param armor table
---@return string
local function color_values(values,armor)
	if values == nil then return "" end
	if type(values)=="string" then
		if count(armor.rarities) == 1 then return "<span class='cr"..armor.rarities[1].."'>"..values.."</span>" end
		return values
	end

	--TODO this assumes i is the same as the color rating, this may result in a bug
	local wikitext = ""
	local newline = ""
	for i, value in ipairs(values) do
		wikitext = wikitext..newline.."<span class='cr"..i.."'>"..value.."</span>"
		if i == 1 then newline = "<br>" end
	end
	return wikitext
end


---Marks up a stat block with the stat name and colored values and appropriate margins and alignment
--- @param stat string
--- @param armor table
--- @return string
local function inline_block(stat, armor)
	if armor.stats[(stat):lower()] == nil then return "" end
	return "<div style='display:inline-block;vertical-align:top;margin:0 15px 0 15px'><b style='color:#eee8'>"..stat.."</b><br>"..color_values(armor.stats[(stat):lower()],armor).."</div>"
end


---Return a table row of data cells containing armor information
--- @param armor table
--- @return string
local function row(armor)
	local wikitext = {}
	insert(wikitext,"<tr><td>")
	insert(wikitext,iconbox(armor))
	insert(wikitext,"</td><td>")

	if armor.slottype ~= "Back" then
		insert(wikitext,classes(armor.classes))
		insert(wikitext,"</td><td>")
		insert(wikitext,color_values(armor.stats["move speed"],armor))
		insert(wikitext,"</td><td>")
	-- elseif armor.stats["move speed"] then
	-- 	insert(wikitext,"<span style='color:red;'>Error: Back "..armor.name.." has unpresented move speed.</span>")
	-- elseif next(armor.classes) then
	-- 	insert(wikitext,"<span style='color:red;'>Error: Back "..armor.name.." has unpresented class requirements.</span>")
	end

	insert(wikitext,inline_block("Armor Rating",armor))
	insert(wikitext,inline_block("Magical Resistance",armor))
	insert(wikitext,"</td><td>")

	-- create the table data cell for attributes
	for _,stat in ipairs(armor.stats.order) do
		if is_primitive[stat] then
			insert(wikitext,inline_block(stat,armor))
		end
	end
	insert(wikitext,"</td><td>")

	-- create the table data cell for the rest of the stats
	for _, stat in ipairs(armor.stats.order) do
		if not is_primitive[stat] and not is_special[stat] then
			insert(wikitext,inline_block(stat,armor))
		end
	end
	insert(wikitext,"</td></tr>")
	return concat(wikitext)
end


--- Return a list of armor keys to be used in the table
--- @param frame table
--- @return table - strings
local function get_list(frame)
	--TODO add minor string validation and correction, e.g. "DeMoN" -> "demon"  ("DeMoN"):lower()
	return AD[frame.args[1]][frame.args[2]] or {}
end


--- Return a table row of appropriate headers cells
--- @param frame table
--- @return string
local function table_header(frame)
	local wikitext = [=[<table cellspacing="0" class="wikitable sortable jquery-tablesorter" style="width:95%;color:#eee;background:transparent;text-align:center;vertical-align:middle;"><tr><th style="width:5%">Name</th>]=]
	if (frame.args[1] or ""):lower() ~= "back" then
		wikitext = wikitext..[=[<th style="width:5%">Class Requirements</th><th style="width:5%">Movement Speed</th>]=]
	end
	return wikitext..[=[<th style="width:10%">Armor/magical Rating</th><th style="width:10%">Attributes</th><th style="width:25%">Other</th></tr>]=]
end

---Create monster table wikitext
--- @param frame table
--- @return string
function p.draw_table(frame)
	if not AD then return "<span style='color:red;'>Error: Could not load Armor data in [[Module:Armor]]</span>" end

	local wikitext = {}
	insert(wikitext, table_header(frame))
	for _, key in ipairs(get_list(frame)) do
		insert(wikitext, row(AD.Armor[key]))
	end
	insert(wikitext, "</table>")
	return concat(wikitext)
end


--[=[
################################################################################
                        Functions for individual armor pages
################################################################################
]=]

local function tab_toggle(title,content,active,tabid)
	local class = ""
	if active then
		class = " class='selected-tab tab-toggle tab'"
	else
		class = " class='tab-toggle tab'"
	end
	return string.format("<div style='display:inline-block' %s data-tabid='%s' data-tab='%s' title='%s'>%s</div>",class,tabid,title,title,content)
end

local function reference_table(wt,table_type)
	local types_order = {"Head","Chest","Legs","Hands","Foot","Back"}
	local separator = "]] • [["

	wt[#wt+1] = "<table cellspacing='0' class='wikitable sortable jquery-tablesorter' style='width:100%;text-align:center;vertical-align:middle;margin-top:15px'>"

	for _,armor_type in ipairs(types_order) do
		wt[#wt+1] = string.format("<tr><td style='font-weight:bold; background-color:rgb(220,220,220,0.2); width:10%%'>[[Armors#%s|%s]]</td><td style='text-align-last:left;padding:10px 25px'>",armor_type,armor_type)
		if AD[armor_type][table_type] then
			wt[#wt+1] = "[["
			for i,v in ipairs(AD[armor_type][table_type]) do
				if i~=1 then wt[#wt+1] = separator end
				wt[#wt+1] = v
			end
			wt[#wt+1] = "]]"
		end
		wt[#wt+1] = "</td></tr>"
	end
	wt[#wt+1] = "</table>"
end

function p.references()
	local table_types = {"Uncraftable","Craftable"}

	local wt = {}
	wt[#wt+1] = "<br><h2>References</h2>"
	wt[#wt+1] = "<div style='display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;margin-top:15px'>"
	for i,table_type in ipairs(table_types) do
		wt[#wt+1] = tab_toggle(table_type,table_type.." Armors",i==1,"")
	end
	wt[#wt+1] = "</div>"
	for i,table_type in ipairs(table_types) do
		wt[#wt+1] = "<div class='"..table_type.."-data'"
		if i==1 then wt[#wt+1] = ">" else wt[#wt+1] = "style='display:none'>" end
		reference_table(wt,table_type)
		wt[#wt+1] = "</div>"
	end

	return concat(wt)
end



return p



-- Test on wiki with
-- mw.log(p.draw_table({args={"Back","Craftable"}}))
-- mw.log(p.draw_table({args={"Head","Uncraftable"}}))

-- mw.log(p.references())