Module:ItemTables

From Deadlock Wiki
Revision as of 21:20, 8 October 2024 by Sylphoid (talk | contribs) (add alphabetical sort)
Jump to navigation Jump to search

Documentation for this module may be created at Module:ItemTables/doc

local p = {};
local data = mw.loadJsonData("Data:ItemData.json")
local get_cost = require("Module:ItemData")._get_cost
local get_type = require("Module:ItemData")._get_type

--[===[
-- Adds commas delimiter to the thousands place
function Format(amount)
    local formatted = amount
    while true do
        formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
        if (k == 0) then
            break
        end
    end
    return formatted
end
--]===]

-- Returns an array of item tables that have the same properties
-- @function   get_similar_items_array
-- @param      {array}
-- @return     {array of tables}
local function get_similar_items_array(property)
	local similarItems = {}
	for _, v in pairs(data) do
		for _, value in ipairs(property) do
			if (v[value] ~= nil and v["Disabled"] == false and v["Name"] ~= nil and v[value] ~= "0" ) then
				table.insert(similarItems, v)
			end
		end
	end
	return similarItems
end

--- Copies original table with its children as deep as possible. Does not handle metatables. (Copy is needed because Lua passes by reference, not value)
-- @function   Deepcopy
-- @param      {n-D table}
-- @return     {n-D table}
function Deepcopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[Deepcopy(orig_key)] = Deepcopy(orig_value)
        end
    else
        copy = orig
    end
    return copy
end


--	local link_patterns = {}
--	link_patterns["BonusClipSizePercent"] = { "[Aa]mmo" }
--	link_patterns["CloseRangeBonusWeaponPower"] = { "[Cc]lose [Ww]eapon [Dd]amage" }
--	link_patterns["BaseAttackDamagePercent"] = { "[Ww]eapon [Dd]amage" }
--	link_patterns["BulletLifestealPercent"] = { "[Bb]ullet [Ll]ifesteal" }
--	link_patterns["BonusHealthRegen"] = { "[Hh]ealth [Rr]egen" }
--	link_patterns["BonusHealth"] = { "[Hh]ealth" }
--	link_patterns["BonusFireRate"] = { "[Ff]ire [Rr]ate" }
--	
--	function FriendlyNames(desc)
--		for link, patterns in pairs(link_patterns) do
--			for i, v in ipairs(patterns) do
--	    		local a = string.find(desc, v)
--					if a then desc = link break
--	    		end
--	    	end
--		end
--		return desc
--	end

local friendly_to_internal = {}
friendly_to_internal["ammo"] = { "BonusClipSizePercent", "BonusClipSize", "ActiveReloadPercent" }
friendly_to_internal["weapon damage"] = { "BaseAttackDamagePercent" }
friendly_to_internal["bullet shield health"] = { "BulletShieldMaxHealth", "BulletShieldOnCast", "SaviorBulletShieldHealth", "FlyingBulletShield" }
friendly_to_internal["spirit shield health"] = { "TechShieldMaxHealth", "TechShieldOnCast", "SaviorMagicShieldHealth", "FlyingTechShield" }
friendly_to_internal["spirit resist"] = { "TechResist" }
friendly_to_internal["bullet resist"] = { "BulletResist" }
friendly_to_internal["health"] = { "BonusHealth" }
friendly_to_internal["health regen"] = { "BonusHealthRegen" }
friendly_to_internal["fire rate"] = { "BonusFireRate" }
friendly_to_internal["stamina"] = { "Stamina" }
friendly_to_internal["stamina recovery"] = { "StaminaCooldownReduction" }

-- Returns a table of internal properties 
-- @function   friendlyNames
-- @param      {string}
-- @return     {table}
local function friendlyNames(desc)
	local keysTable = {}
	desc = string.lower(desc or "")
	for link, patterns in pairs(friendly_to_internal) do
		if (desc == link) then keysTable = patterns end 
	end
	return keysTable
end

local unitSuffix = {
	["%"] = { "BonusClipSizePercent", "BaseAttackDamagePercent", "ActiveReloadPercent", "TechResist", "BulletResist", "BonusFireRate", "StaminaCooldownReduction" },
	["m/s"] = { "BonusMoveSpeed" }
}

local function appendSuffix(internal)
	local unitName = ""
	for key, s in pairs(unitSuffix) do
		for _, pattern in pairs(s) do
			if (internal == pattern) then return key end
		end
	end
	return unitName
end

local sortByWeapon = {}
sortByWeapon["Weapon"] = 1
sortByWeapon["Armor"] = 10000
sortByWeapon["Tech"] = 100000000

-- Sort the order of items in a preset as it appears when no filtered ordering is applied. Ordered first by slot and cost increasing, then alphabetical within same slot and cost.
function defaultSort()
    return function(a, b)
    	if (get_cost(a["Name"]) == get_cost(b["Name"]) and sortByWeapon[a["Slot"]] == sortByWeapon[b["Slot"]]) then return a["Name"] < b["Name"] end
        return get_cost(a["Name"]) * sortByWeapon[a["Slot"]] < get_cost(b["Name"]) * sortByWeapon[b["Slot"]]
    end
end

-- Outputs a wikitable of items that increase a specified stat. Invoked by {{Item stat table}}
-- @function   p.itemPropTable
-- @param      {string}
-- @return     {string}
p.itemPropTable = function(frame)
	local TableValues = {}
	local requirements = {}
	local listofKeysTable = {}
	local listofItems = ""
	local property = frame:getParent().args[1] or mw.title.getCurrentTitle().text
	local copyVar = property
	listofKeysTable = friendlyNames(property) 
	local filteredData = {}
	filteredData = get_similar_items_array(listofKeysTable)
	table.sort(filteredData, defaultSort())
	
	local createTable = mw.html.create('table')
			:addClass('wikitable sortable')
			:tag('caption'):wikitext("List of Items"):done()
			
	local createTableHeader = mw.html.create('tr')
	createTableHeader
		:tag('th'):wikitext('Name'):done()
		:tag('th'):wikitext('Cost'):done()
		:tag('th'):wikitext('Category'):done()
		:tag('th'):wikitext('Stat change'):done()
		
	createTable:node(createTableHeader)
	
	-- query the filtered items
	for internalName, itemName in ipairs(filteredData) do --itemName is the item table. go through whole table.

		local display = frame:expandTemplate{
		title = 'ItemIcon',
		args = {
			itemName["Name"]
			}
		}
		
		for k, t in pairs(listofKeysTable) do
			-- filter out items that: don't have the property and the value isn't zero
			if(itemName[t] ~= nil and itemName[t] ~= "0" ) then
				listofItems = listofItems .. itemName["Name"] .. "<br/>"
				copyVar = copyVar:gsub("^%l", string.upper)
				
				local tableData = mw.html.create('tr')
				tableData
					:tag('td'):wikitext(display):done()
					:tag('td'):wikitext(get_cost(itemName["Name"])):done()
					:tag('td'):wikitext(get_type(itemName["Name"])):done()
					:tag('td'):wikitext("+<b>" .. itemName[t].. "</b>" .. appendSuffix(t) .. " " .. copyVar):done()
					
				table.insert(requirements, tableData)
				--	TableValues = table.insert(TableValues, itemName["Name"]) -- i may want to make a table first, so it includes weapon and cost to make it sortable.
			end
		end
	end	
	
	for _, row in ipairs(requirements) do
		createTableHeader:node(row)
	end
	
	return tostring(createTable)
	--return listofItems -- this is just a string list, same thing as createTable. delete this when line when finished
	--return table.concat(TableValues, ", ")

end

return p