From Dark and Darker Wiki
| m (attempt#1 at giving col1 their own row thats visually hidden for css purposes) Tag: Reverted | m (typo) | ||
| (38 intermediate revisions by 2 users not shown) | |||
| Line 29: | Line 29: | ||
| end | end | ||
| function p. | function p.draw_roll_range_table(base_or_gem) | ||
| 	-- Handle based on how it was called | 	-- Handle based on how it was called | ||
| 	if type(base_or_gem) == "table" and base_or_gem.args then -- if called via wikitext instead of lua | 	if type(base_or_gem) == "table" and base_or_gem.args then -- if called via wikitext instead of lua | ||
| 		local frame = base_or_gem | |||
| 		base_or_gem = frame.args[1] | |||
| 	end | 	end | ||
| 	-- Validate | 	-- Validate | ||
| 	if base_or_gem ~= "base" and base_or_gem ~= "gem" then return "1st parameter 'base_or_gem' must be either 'base' or 'gem'." end | 	if base_or_gem ~= "base" and base_or_gem ~= "gem" and base_or_gem ~= "unique_base" then | ||
| 		return "1st parameter 'base_or_gem' must be either 'base' or 'gem' or 'unique_base'." | |||
| 	end | |||
| 	local slot_headers = '<th rowspan="2" colspan="2">Enchantments</th>' | 	local slot_headers = '<th rowspan="2" colspan="2">Enchantments</th>' | ||
| 	local min_max_headers = '' | 	local min_max_headers = '' | ||
| 	-- Add required gem col header | |||
| 	if base_or_gem == 'gem' then | |||
| 		slot_headers = slot_headers .. '<th rowspan="2">Required Gem</th>' | |||
| 	end | |||
| 	-- Create enchant_name_headers (row1) and min/max (row2) | 	-- Create enchant_name_headers (row1) and min/max (row2) | ||
| Line 66: | Line 73: | ||
| 		for i, enchant_name in ipairs(enchants_in_group) do | 		for i, enchant_name in ipairs(enchants_in_group) do | ||
| 			-- Get that enchant's data | 			-- Get that enchant's data | ||
| 			local slots_data = enchantments_data["enchant_rolls"][enchant_name] | 			local slots_data = enchantments_data["enchant_rolls"][enchant_name]["slots"] | ||
| 			if slots_data == nil then return "Error: " .. enchant_name .. " not found in \"enchant_rolls\"" end | 			if slots_data == nil then return "Error: " .. enchant_name .. " not found in \"enchant_rolls\"" end | ||
| Line 88: | Line 95: | ||
| 			--Max Total Possible = MAX(1H Shield + 1H Weapon, 2 * 1H Weapon, 2H Physical, 2H Magical, 2H Hybrid) + Head + Chest + Legs + Hands + Foot + Cloak + Necklace) + 2*Ring | 			--Max Total Possible = MAX(1H Shield + 1H Weapon, 2 * 1H Weapon, 2H Physical, 2H Magical, 2H Hybrid) + Head + Chest + Legs + Hands + Foot + Cloak + Necklace) + 2*Ring | ||
| 			local weapons = math.max( | 			local weapons = math.max( | ||
| 				p.get_roll(slots_data, " | 				p.get_roll(slots_data, "1H", base_or_gem) + p.get_roll(slots_data, "1H Shield", base_or_gem), | ||
| 				p.get_roll(slots_data, " | 				p.get_roll(slots_data, "1H", base_or_gem)*2, | ||
| 				p.get_roll(slots_data, " | 				p.get_roll(slots_data, "2H Shield", base_or_gem), | ||
| 				p.get_roll(slots_data, " | 				p.get_roll(slots_data, "2H Physical", base_or_gem), | ||
| 				p.get_roll(slots_data, " | 				p.get_roll(slots_data, "2H Hybrid", base_or_gem), | ||
| 				p.get_roll(slots_data, " | 				p.get_roll(slots_data, "2H Magical", base_or_gem) | ||
| 				) | 				) | ||
| Line 107: | Line 114: | ||
| 				) | 				) | ||
| 			local max_total_possible = weapons + armor | 			local max_total_possible = weapons + armor | ||
| 			-- Get the required gem | |||
| 			local required_gem_td = '' | |||
| 			if base_or_gem == 'gem' then | |||
| 				required_gem = enchantments_data["enchant_rolls"][enchant_name]["required_gem"] | |||
| 				if required_gem == nil then | |||
| 					required_gem = "" | |||
| 				else | |||
| 					required_gem = "<div class=\"iconbox\" style=\"margin:0px;\"><div class=\"rounded relative\">[[File:" .. required_gem .. ".png|x35px|link=" .. required_gem .. "]]</div></div>" | |||
| 				end | |||
| 				required_gem_td = '<td id="gem" style=\"padding:0px;\">' .. required_gem .. '</td>' | |||
| 			end | |||
| 			-- Add cells to row | 			-- Add cells to row | ||
| 			local rowspanned_cell = '' | 			local rowspanned_cell = '' | ||
| 			local  | 			local row_id = ' id="' .. utils.dash_for_space(enchant_group_name) .. '"' | ||
| 			if is_first then | 			if is_first then | ||
| 				rowspan = ' rowspan="' .. num_enchants_in_group+1 .. '"' | 				rowspan = ' rowspan="' .. num_enchants_in_group+1 .. '"' | ||
| 				rowspanned_cell = '<td' .. rowspan .. '>' .. enchant_group_name ..  | 				rowspanned_cell = '<td' .. rowspan .. '>' .. enchant_group_name .. '</td></tr><tr' .. row_id .. '>' | ||
| 			end | 			end | ||
| 			enchant_row = '' .. rowspanned_cell | |||
| 			enchant_row = enchant_row .. "<td>" .. enchant_name .. "</td>" | |||
| 			enchant_row = enchant_row .. required_gem_td | |||
| 			enchant_row = enchant_row .. min_max_cols | |||
| 			enchant_row = enchant_row .. "<td>" .. max_total_possible .. "</td>" | |||
| 			enchant_rows = enchant_rows .. '<tr' .. row_id .. '>' .. enchant_row .. "</tr>" | |||
| 			is_first = false | 			is_first = false | ||
| 		end | 		end | ||
| 	end | 	end | ||
| 	local slot_headers = '<tr>' .. slot_headers .. '<th rowspan="2">Max Total Possible</th>' .. '</tr>' | 	local slot_headers = '<tr>' .. slot_headers .. '<th rowspan="2">Max Total Possible</th>' .. '</tr>' | ||
| Line 132: | Line 153: | ||
| 	local table_str = '<table class="enchantmenttable">' .. slot_headers .. min_max_headers .. enchant_rows .. "</table>" | 	local table_str = '<table class="enchantmenttable">' .. slot_headers .. min_max_headers .. enchant_rows .. "</table>" | ||
| 	return table_str | 	return table_str | ||
| end | |||
| function p.draw_socket_cost_table(frame) | |||
| 	local output_str = "" | |||
| 	local data_rows = "" | |||
| 	local header_row = "<tr>" .. "<th>Rarity</td>" .. "<th>Cost</th>" .. "</tr>" | |||
| 	local row | |||
| 	local i = 1 --display rarity_nums starting at i=1 (Poor), skipping Junk | |||
| 	local ending_i = 7 --end with Unique=7 | |||
| 	-- this is O(n^2), but since theres only 8 elements, its inconsequential | |||
| 	-- Iterate costs in data first | |||
| 	local rarity_num | |||
| 	while i <= ending_i do | |||
| 		for rarity_name, cost in pairs(enchantments_data["enchant_costs"]) do | |||
| 			-- Determine the rarity_num | |||
| 			rarity_num = utils.rarity_name_to_num(rarity_name) | |||
| 			if i == rarity_num then | |||
| 				-- This is the next rarity that should be displayed | |||
| 				row = "<td>" .. "<span class=\"colorrarity" .. i .. "\">" .. rarity_name .. "</span>" .. "</td>" .. "<td>" .. cost .. "</td>"  | |||
| 				data_rows = data_rows .. "<tr>" ..  row .. "</tr>" | |||
| 				i = i+1 -- look for the next rarity | |||
| 				break -- end the current rarity-search | |||
| 			end | |||
| 		end | |||
| 	end | |||
| 	return "<table class=\"wikitable\" style=\"border-collapse:collapse;\">" .. header_row .. data_rows .. "</table>" | |||
| end | end | ||
| return p | return p | ||
Latest revision as of 02:09, 11 April 2025
Overview
Functions for Enchantments. Data comes from Data:Enchantments.json.
Functions
draw_roll_range_table
Create's a table of enchants for the Enchantments page
Parameters
- base_or_gem - List 'base' (traditional) or 'gem' enchant roll ranges?
Examples
{{#invoke:Enchantments|draw_roll_range_table|gem}}
| Enchantments | Required Gem | 1H | 1H Shield | 2H Shield | 2H Physical | 2H Hybrid | 2H Magical | Chest | Legs | Foot | Head | Hands | Cloak | Necklace | Ring | Max Total Possible | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | Min | Max | ||||
| Attributes | |||||||||||||||||||||||||||||||
| All Attributes | 0 | ||||||||||||||||||||||||||||||
| Strength | 0 | ||||||||||||||||||||||||||||||
| Vigor | 0 | ||||||||||||||||||||||||||||||
| Agility | 0 | ||||||||||||||||||||||||||||||
| Dexterity | 0 | ||||||||||||||||||||||||||||||
| Will | 0 | ||||||||||||||||||||||||||||||
| Knowledge | 0 | ||||||||||||||||||||||||||||||
| Resourcefulness | 0 | ||||||||||||||||||||||||||||||
| Physical Damage | |||||||||||||||||||||||||||||||
| Physical Power Bonus | 0.6 | 0.9 | 0.6 | 0.9 | 1.2 | 1.9 | 1.2 | 1.9 | 1.2 | 1.9 | 1.2 | 1.9 | 0.9 | 1.4 | 0.9 | 1.4 | 0.6 | 0.9 | 0.6 | 0.9 | 0.6 | 0.9 | 0.6 | 0.9 | 0.9 | 1.4 | 0.6 | 0.9 | 11.5 | ||
| Physical Power | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 11 | ||||||||||||||||
| Physical Gear Weapon Damage | 1 | 1 | 1 | 1 | 1 | 1 | 2 | ||||||||||||||||||||||||
| Physical Damage Add | 1 | 1 | 1 | 1 | 5 | ||||||||||||||||||||||||||
| True Physical Damage | 1 | 1 | 1 | 1 | 5 | ||||||||||||||||||||||||||
| Armor Penetration | 1 | 1.6 | 1 | 1.6 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.5 | 2.4 | 1 | 1.6 | 20 | ||
| Magical Damage | |||||||||||||||||||||||||||||||
| Magical Power Bonus | 0.5 | 0.9 | 0.5 | 0.9 | 1.2 | 1.9 | 1.2 | 1.9 | 1.2 | 1.9 | 1.2 | 1.9 | 0.7 | 1.4 | 0.7 | 1.4 | 0.5 | 0.9 | 0.5 | 0.9 | 0.5 | 0.9 | 0.5 | 0.9 | 0.7 | 1.4 | 0.5 | 0.9 | 11.5 | ||
| Magical Power | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 11 | ||||||||||||||||
| Magical Damage Add | 1 | 1 | 1 | 1 | 5 | ||||||||||||||||||||||||||
| True Magical Damage | 1 | 1 | 1 | 1 | 5 | ||||||||||||||||||||||||||
| Magical Penetration | 1 | 1.6 | 1 | 1.6 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.5 | 2.4 | 1 | 1.6 | 20 | ||
| Neutral Damage | |||||||||||||||||||||||||||||||
| Headshot Damage Modifier | 1 | 1.6 | 1 | 1.6 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.5 | 2.4 | 1 | 1.6 | 20 | ||
| Undead Race Damage Bonus | 1 | 1.6 | 1 | 1.6 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.5 | 2.4 | 1 | 1.6 | 20 | ||
| Demon Race Damage Bonus | 1 | 1.6 | 1 | 1.6 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.5 | 2.4 | 1 | 1.6 | 20 | ||
| Reductions | |||||||||||||||||||||||||||||||
| Armor Rating Add | 3 | 4 | 3 | 4 | 6 | 9 | 6 | 9 | 6 | 9 | 6 | 9 | 5 | 8 | 5 | 8 | 3 | 4 | 3 | 4 | 3 | 4 | 3 | 4 | 5 | 8 | 3 | 4 | 57 | ||
| Physical Damage Reduction | 0.5 | 0.8 | 0.5 | 0.8 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 0.7 | 1.2 | 0.7 | 1.2 | 0.5 | 0.8 | 0.5 | 0.8 | 0.5 | 0.8 | 0.5 | 0.8 | 0.7 | 1.2 | 0.5 | 0.8 | 10 | ||
| Projectile Damage Reduction | 0.7 | 1.2 | 0.7 | 1.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1 | 1.6 | 1 | 1.6 | 0.7 | 1.2 | 0.7 | 1.2 | 0.7 | 1.2 | 0.7 | 1.2 | 1 | 1.6 | 0.7 | 1.2 | 15.2 | ||
| Magical Damage Reduction | 0.5 | 0.8 | 0.5 | 0.8 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 0.7 | 1.2 | 0.7 | 1.2 | 0.5 | 0.8 | 0.5 | 0.8 | 0.5 | 0.8 | 0.5 | 0.8 | 0.7 | 1.2 | 0.5 | 0.8 | 10 | ||
| Magical Resistance | 3 | 4 | 3 | 4 | 6 | 9 | 6 | 9 | 6 | 9 | 6 | 9 | 5 | 8 | 5 | 8 | 3 | 4 | 3 | 4 | 3 | 4 | 3 | 4 | 5 | 8 | 3 | 4 | 57 | ||
| Cooldown Reduction Bonus | 0.7 | 1.2 | 0.7 | 1.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 0.7 | 1.2 | 0.7 | 1.2 | 0.7 | 1.2 | 0.7 | 1.2 | 1 | 1.6 | 0.7 | 1.2 | 14.4 | ||
| Undead Race Damage Reduction | 1 | 1.6 | 1 | 1.6 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.5 | 2.4 | 1 | 1.6 | 20 | ||
| Demon Race Damage Reduction | 1 | 1.6 | 1 | 1.6 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.5 | 2.4 | 1 | 1.6 | 20 | ||
| Actions | |||||||||||||||||||||||||||||||
| Action Speed | 0.6 | 0.9 | 0.6 | 0.9 | 1.2 | 1.9 | 1.2 | 1.9 | 1.2 | 1.9 | 1.2 | 1.9 | 0.9 | 1.4 | 0.9 | 1.4 | 0.6 | 0.9 | 0.6 | 0.9 | 0.6 | 0.9 | 0.6 | 0.9 | 0.9 | 1.4 | 0.6 | 0.9 | 11.5 | ||
| Regular Interaction Speed | 0 | ||||||||||||||||||||||||||||||
| Magical Interaction Speed | 0 | ||||||||||||||||||||||||||||||
| Spell Casting Speed | 1 | 1.6 | 1 | 1.6 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 2 | 3.2 | 1.2 | 2 | 1.2 | 2 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.2 | 2 | 1 | 1.6 | 18.8 | ||
| Move Speed Add | 1 | 4 | 4 | ||||||||||||||||||||||||||||
| Move Speed Bonus | 0.3 | 1.2 | 1.2 | ||||||||||||||||||||||||||||
| Health | |||||||||||||||||||||||||||||||
| Max Health Add | 1 | 1 | 2 | 3 | 2 | 3 | 2 | 3 | 2 | 3 | 2 | 3 | 2 | 3 | 1 | 2 | 1 | 2 | 1 | 2 | 1 | 2 | 2 | 3 | 1 | 2 | 24 | ||||
| Max Health Bonus | 0.7 | 1.2 | 0.7 | 1.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1 | 1.6 | 1.5 | 2.4 | 1 | 1.6 | 19.2 | ||
| Healing | |||||||||||||||||||||||||||||||
| Outgoing Physical Healing Add | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 11 | ||||||||||||||||
| Outgoing Magical Healing Add | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 11 | ||||||||||||||||
| Statuses | |||||||||||||||||||||||||||||||
| Buff Duration Bonus | 0.7 | 1.2 | 0.7 | 1.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 0.7 | 1.2 | 0.7 | 1.2 | 0.7 | 1.2 | 0.7 | 1.2 | 1 | 1.6 | 0.7 | 1.2 | 14.4 | ||
| Debuff Duration Bonus | 0.7 | 1.2 | 0.7 | 1.2 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1 | 1.6 | 1 | 1.6 | 0.7 | 1.2 | 0.7 | 1.2 | 0.7 | 1.2 | 0.7 | 1.2 | 1 | 1.6 | 0.7 | 1.2 | 14.4 | ||
| Memory | |||||||||||||||||||||||||||||||
| Memory Capacity Add | 1 | 1 | 2 | 3 | 2 | 3 | 2 | 3 | 2 | 3 | 2 | 3 | 2 | 3 | 1 | 1 | 1 | 1 | 2 | 3 | 1 | 18 | |||||||||
| Memory Capacity Bonus | 1.5 | 2.4 | 1.5 | 2.4 | 3 | 4.8 | 3 | 4.8 | 3 | 4.8 | 3 | 4.8 | 2.2 | 3.6 | 2.2 | 3.6 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 1.5 | 2.4 | 2.2 | 3.6 | 1.5 | 2.4 | 30 | ||
| Misc | |||||||||||||||||||||||||||||||
| Luck | 15 | 24 | 15 | 24 | 30 | 48 | 30 | 48 | 30 | 48 | 30 | 48 | 22 | 36 | 22 | 36 | 15 | 24 | 15 | 24 | 15 | 24 | 15 | 24 | 22 | 36 | 15 | 24 | 300 | ||
draw_socket_cost_table
Create's a table of socket's cost per rarity for the Enchantments page
Parameters
none
Examples
{{#invoke:Enchantments|draw_socket_cost_table}}
| Rarity | Cost | 
|---|---|
| Poor | 10 | 
| Common | 10 | 
| Uncommon | 10 | 
| Rare | 20 | 
| Epic | 100 | 
| Legend | 150 | 
| Unique | 200 | 
local enchantments_data = mw.loadJsonData("Data:Enchantments.json")
local utils = require("Module:Utilities")
local p = {}
function p.get_roll(slots_data, slot_name, base_or_gem, min_or_max, if_not_exist)
	if min_or_max ~= "min" and min_or_max ~= "max" then
		min_or_max = "max"
	end
	
	if if_not_exist == nil then
		if_not_exist = 0
	end
	
	slot_data = slots_data[slot_name]
	if slot_data == nil then
		return if_not_exist
	end
	roll_data = slot_data[base_or_gem]
	if roll_data == nil then
		return if_not_exist
	end
	
	roll = roll_data[min_or_max]
	if roll == nil then
		return if_not_exist
	end
	
	return roll
end
function p.draw_roll_range_table(base_or_gem)
	-- Handle based on how it was called
	if type(base_or_gem) == "table" and base_or_gem.args then -- if called via wikitext instead of lua
		local frame = base_or_gem
		base_or_gem = frame.args[1]
	end
	
	-- Validate
	if base_or_gem ~= "base" and base_or_gem ~= "gem" and base_or_gem ~= "unique_base" then
		return "1st parameter 'base_or_gem' must be either 'base' or 'gem' or 'unique_base'."
	end
	
	local slot_headers = '<th rowspan="2" colspan="2">Enchantments</th>'
	local min_max_headers = ''
	
	-- Add required gem col header
	if base_or_gem == 'gem' then
		slot_headers = slot_headers .. '<th rowspan="2">Required Gem</th>'
	end
	-- Create enchant_name_headers (row1) and min/max (row2)
	-- Iterate enchant groups
	for i, slot_name in ipairs(enchantments_data["slottype_order"]) do
		slot_headers = slot_headers .. '<th colspan="2">' .. slot_name .. '</th>'
		min_max_headers = min_max_headers .. '<th>Min</th>' .. '<th>Max</th>'
	end
	
	-- Add body rows
	local enchant_rows = ""
	local enchant_row
	for i, enchant_group_name in ipairs(enchantments_data["enchant_group_order"]) do
		local enchants_in_group = enchantments_data["enchant_order"][enchant_group_name]
		if enchants_in_group == nil then return "Error: " .. enchant_group_name .. " not found in \"enchant_order\"" end
		
		-- Iterate enchants in the group
		-- First just determine how many enchants are in the group to get the proper rowspan
		local num_enchants_in_group = 0
		for i, enchant_name in ipairs(enchants_in_group) do
			num_enchants_in_group = num_enchants_in_group + 1
		end
		
		local is_first = true
		for i, enchant_name in ipairs(enchants_in_group) do
			-- Get that enchant's data
			local slots_data = enchantments_data["enchant_rolls"][enchant_name]["slots"]
			if slots_data == nil then return "Error: " .. enchant_name .. " not found in \"enchant_rolls\"" end
			
			-- Iterate slottypes
			local min_max_cols = ""
			for i, slot_type in ipairs(enchantments_data["slottype_order"]) do
				-- Get rolls, default to blank if missing
				local min_roll = p.get_roll(slots_data, slot_type, base_or_gem, "min", "")
				local max_roll = p.get_roll(slots_data, slot_type, base_or_gem, "max", "")
				if min_roll == 0 then min_roll = "" end
				if max_roll == 0 then max_roll = "" end
				
				if min_roll == max_roll then
					min_max_cols = min_max_cols .. "<td colspan=\"2\">" .. min_roll .. "</td>"
				else
					min_max_cols = min_max_cols .. "<td>" .. min_roll .. "</td><td>" .. max_roll .. "</td>"
				end
			end
			
			-- Calc max
			--Max Total Possible = MAX(1H Shield + 1H Weapon, 2 * 1H Weapon, 2H Physical, 2H Magical, 2H Hybrid) + Head + Chest + Legs + Hands + Foot + Cloak + Necklace) + 2*Ring
			local weapons = math.max(
				p.get_roll(slots_data, "1H", base_or_gem) + p.get_roll(slots_data, "1H Shield", base_or_gem),
				p.get_roll(slots_data, "1H", base_or_gem)*2,
				p.get_roll(slots_data, "2H Shield", base_or_gem),
				p.get_roll(slots_data, "2H Physical", base_or_gem),
				p.get_roll(slots_data, "2H Hybrid", base_or_gem),
				p.get_roll(slots_data, "2H Magical", base_or_gem)
				)
			
			local armor = (
				p.get_roll(slots_data, "Head", base_or_gem) +
				p.get_roll(slots_data, "Chest", base_or_gem) + 
				p.get_roll(slots_data, "Legs", base_or_gem) + 
				p.get_roll(slots_data, "Hands", base_or_gem) + 
				p.get_roll(slots_data, "Foot", base_or_gem) + 
				p.get_roll(slots_data, "Cloak", base_or_gem) + 
				p.get_roll(slots_data, "Necklace", base_or_gem) + 
				p.get_roll(slots_data, "Ring", base_or_gem)*2 
				)
			local max_total_possible = weapons + armor
			
			-- Get the required gem
			local required_gem_td = ''
			if base_or_gem == 'gem' then
				required_gem = enchantments_data["enchant_rolls"][enchant_name]["required_gem"]
				if required_gem == nil then
					required_gem = ""
				else
					required_gem = "<div class=\"iconbox\" style=\"margin:0px;\"><div class=\"rounded relative\">[[File:" .. required_gem .. ".png|x35px|link=" .. required_gem .. "]]</div></div>"
				end
				required_gem_td = '<td id="gem" style=\"padding:0px;\">' .. required_gem .. '</td>'
			end
			
			-- Add cells to row
			local rowspanned_cell = ''
			local row_id = ' id="' .. utils.dash_for_space(enchant_group_name) .. '"'
			if is_first then
				rowspan = ' rowspan="' .. num_enchants_in_group+1 .. '"'
				rowspanned_cell = '<td' .. rowspan .. '>' .. enchant_group_name .. '</td></tr><tr' .. row_id .. '>'
			end
			enchant_row = '' .. rowspanned_cell
			enchant_row = enchant_row .. "<td>" .. enchant_name .. "</td>"
			enchant_row = enchant_row .. required_gem_td
			enchant_row = enchant_row .. min_max_cols
			enchant_row = enchant_row .. "<td>" .. max_total_possible .. "</td>"
			
			enchant_rows = enchant_rows .. '<tr' .. row_id .. '>' .. enchant_row .. "</tr>"
			
			is_first = false
		end
	end
	
	
	
	local slot_headers = '<tr>' .. slot_headers .. '<th rowspan="2">Max Total Possible</th>' .. '</tr>'
	local min_max_headers = '<tr>' .. min_max_headers .. '</tr>'
	
	local table_str = '<table class="enchantmenttable">' .. slot_headers .. min_max_headers .. enchant_rows .. "</table>"
	return table_str
end
function p.draw_socket_cost_table(frame)
	local output_str = ""
	local data_rows = ""
	local header_row = "<tr>" .. "<th>Rarity</td>" .. "<th>Cost</th>" .. "</tr>"
	local row
	local i = 1 --display rarity_nums starting at i=1 (Poor), skipping Junk
	local ending_i = 7 --end with Unique=7
	
	-- this is O(n^2), but since theres only 8 elements, its inconsequential
	-- Iterate costs in data first
	local rarity_num
	while i <= ending_i do
		for rarity_name, cost in pairs(enchantments_data["enchant_costs"]) do
			-- Determine the rarity_num
			rarity_num = utils.rarity_name_to_num(rarity_name)
			
			if i == rarity_num then
				-- This is the next rarity that should be displayed
				row = "<td>" .. "<span class=\"colorrarity" .. i .. "\">" .. rarity_name .. "</span>" .. "</td>" .. "<td>" .. cost .. "</td>" 
				data_rows = data_rows .. "<tr>" ..  row .. "</tr>"
				
				i = i+1 -- look for the next rarity
				break -- end the current rarity-search
			end
		end
	end
	
	return "<table class=\"wikitable\" style=\"border-collapse:collapse;\">" .. header_row .. data_rows .. "</table>"
end
return p
 
						 
					

