Jump to content

Module:ItemTables: Difference between revisions

From Deadlock Wiki
add return fire to bullet resist
add bullet resist reduction, add souls icon, apply fix for negative numbers that are not red, cleanup
Line 38: Line 38:
     return copy
     return copy
end
end


-- local link_patterns = {}
-- local link_patterns = {}
Line 66: Line 65:
friendly_to_internal["spirit shield health"] = { "TechShieldMaxHealth", "TechShieldOnCast", "SaviorMagicShieldHealth", "FlyingTechShield", "VexBarrierTechMaxHealth" }
friendly_to_internal["spirit shield health"] = { "TechShieldMaxHealth", "TechShieldOnCast", "SaviorMagicShieldHealth", "FlyingTechShield", "VexBarrierTechMaxHealth" }
friendly_to_internal["bullet resist"] = { "BulletResist", "LocalBulletArmorReduction", "ReturnFireBulletResist" }
friendly_to_internal["bullet resist"] = { "BulletResist", "LocalBulletArmorReduction", "ReturnFireBulletResist" }
friendly_to_internal["bullet resist reduction"] = { "BulletArmorReduction", "BulletResistReduction" }
friendly_to_internal["spirit resist"] = { "TechResist" }
friendly_to_internal["spirit resist"] = { "TechResist" }
friendly_to_internal["health"] = { "BonusHealth" }
friendly_to_internal["health"] = { "BonusHealth" }
Line 94: Line 94:
"TechResist", "BulletResist",
"TechResist", "BulletResist",
"BonusFireRate", "FireRateWhenShielded", "FervorFireRate", "FireRateBonus", "AmbushBonusFireRate", "ActiveBonusFireRate", "FireRateSlow",
"BonusFireRate", "FireRateWhenShielded", "FervorFireRate", "FireRateBonus", "AmbushBonusFireRate", "ActiveBonusFireRate", "FireRateSlow",
"LocalBulletArmorReduction", "ReturnFireBulletResist",
"LocalBulletArmorReduction", "ReturnFireBulletResist", "BulletArmorReduction", "BulletResistReduction",
"BonusBulletSpeedPercent",
"BonusBulletSpeedPercent",
"StaminaCooldownReduction" },
"StaminaCooldownReduction" },
Line 122: Line 122:
         return get_cost(a["Name"]) * sortByWeapon[a["Slot"]] < get_cost(b["Name"]) * sortByWeapon[b["Slot"]]
         return get_cost(a["Name"]) * sortByWeapon[a["Slot"]] < get_cost(b["Name"]) * sortByWeapon[b["Slot"]]
     end
     end
end
-- Formats the value of the stat with a + or -
-- @function  signPrefix
-- @param      {string}
-- @return    {string}
local function signPrefix(value)
local signString = ""
value = tonumber(value)
if (value > 0) then
return "+<b>" .. value .. "</b>"
elseif (value < 0) then
value = math.abs(value)
return "-<b>" .. value .. "</b>"
end
end
end


Line 129: Line 144:
-- @return    {string}
-- @return    {string}
p.itemPropTable = function(frame)
p.itemPropTable = function(frame)
local TableValues = {}
local requirements = {}
local requirements = {}
local listofKeysTable = {}
local listofKeysTable = {}
Line 153: Line 167:
createTable:node(createTableHeader)
createTable:node(createTableHeader)
-- query the filtered items
-- query all the filtered items. itemName is the item table.
for internalName, itemName in ipairs(filteredData) do --itemName is the item table. go through whole table.
for internalName, itemName in ipairs(filteredData) do  


local display = frame:expandTemplate{
local display = frame:expandTemplate{
Line 162: Line 176:
}
}
}
}
local soulIcon = frame:expandTemplate{ title = 'Souls' }
for k, t in pairs(listofKeysTable) do
for k, t in pairs(listofKeysTable) do
Line 172: Line 187:
tableData
tableData
:tag('td'):wikitext(display):done()
:tag('td'):wikitext(display):done()
:tag('td'):wikitext(commas._add(get_cost(itemName["Name"]))):done()
:tag('td'):wikitext(soulIcon .. commas._add(get_cost(itemName["Name"]))):done()
:tag('td'):wikitext(get_type(itemName["Name"])):done()
:tag('td'):wikitext(get_type(itemName["Name"])):done()
if (tonumber(itemName[t]) < 0) then  
if (t == "LocalBulletArmorReduction") then  
tableData
tableData
:tag('td'):wikitext("<span style=\"color:red;\"><b>" .. itemName[t].. "</b>" .. appendSuffix(t) .. "</span> " .. copyVar):done()
:tag('td'):wikitext("<span style=\"color:red;\">" .. signPrefix(itemName[t]) .. appendSuffix(t) .. "</span> " .. copyVar):done()
else
else
tableData
tableData
:tag('td'):wikitext("+<b>" .. itemName[t].. "</b>" .. appendSuffix(t) .. " " .. copyVar):done()
:tag('td'):wikitext(signPrefix(itemName[t]) .. appendSuffix(t) .. "</span> " .. copyVar):done()
end
end
table.insert(requirements, tableData)
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
end
Line 195: Line 209:
return tostring(createTable)
return tostring(createTable)
--return listofItems -- this is just a string list, same thing as createTable. delete this when line when finished
--return listofItems -- this is just a string list, same thing as createTable. delete this when line when finished
--return table.concat(TableValues, ", ")


end
end


return p
return p

Revision as of 06:23, 12 October 2024

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
local commas = require("Module:Addcommas")

-- 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", "CloseRangeBonusWeaponPower", "LongRangeBonusWeaponPower", "AttackDamageWhenShielded" }
friendly_to_internal["bullet shield health"] = { "BulletShieldMaxHealth", "BulletShieldOnCast", "SaviorBulletShieldHealth", "FlyingBulletShield", "VexBarrierBulletMaxHealth" }
friendly_to_internal["spirit shield health"] = { "TechShieldMaxHealth", "TechShieldOnCast", "SaviorMagicShieldHealth", "FlyingTechShield", "VexBarrierTechMaxHealth" }
friendly_to_internal["bullet resist"] = { "BulletResist", "LocalBulletArmorReduction", "ReturnFireBulletResist" }
friendly_to_internal["bullet resist reduction"] = { "BulletArmorReduction", "BulletResistReduction" }
friendly_to_internal["spirit resist"] = { "TechResist" }
friendly_to_internal["health"] = { "BonusHealth" }
friendly_to_internal["health regen"] = { "BonusHealthRegen" }
friendly_to_internal["fire rate"] = { "BonusFireRate", "FireRateWhenShielded", "FireRateBonus", "FervorFireRate", "AmbushBonusFireRate", "ActiveBonusFireRate" }
friendly_to_internal["fire rate slow"] = { "FireRateSlow" }
friendly_to_internal["bullet velocity"] = { "BonusBulletSpeedPercent" }
friendly_to_internal["spirit power"] = { "TechPower", "BonusSpirit", "SpiritPower", "BonusSpiritWithMagicShield", "ImbuedTechPower", "AmbushBonusTechPower" }
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", "ActiveReloadPercent", 
		"BaseAttackDamagePercent", "CloseRangeBonusWeaponPower", "LongRangeBonusWeaponPower", "AttackDamageWhenShielded",
		"TechResist", "BulletResist",
		"BonusFireRate", "FireRateWhenShielded", "FervorFireRate", "FireRateBonus", "AmbushBonusFireRate", "ActiveBonusFireRate", "FireRateSlow",
		"LocalBulletArmorReduction", "ReturnFireBulletResist", "BulletArmorReduction", "BulletResistReduction",
		"BonusBulletSpeedPercent",
		"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

-- Formats the value of the stat with a + or -
-- @function   signPrefix
-- @param      {string}
-- @return     {string}
local function signPrefix(value)
	local signString = ""
	value = tonumber(value)
	if (value > 0) then
		return "+<b>" .. value .. "</b>"
	elseif (value < 0) then
		value = math.abs(value)
		return "-<b>" .. value .. "</b>"
	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 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 all the filtered items. itemName is the item table.
	for internalName, itemName in ipairs(filteredData) do 

		local display = frame:expandTemplate{
		title = 'ItemIcon',
		args = {
			itemName["Name"]
			}
		}
		local soulIcon = frame:expandTemplate{ title = 'Souls' }
		
		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(soulIcon .. commas._add(get_cost(itemName["Name"]))):done()
					:tag('td'):wikitext(get_type(itemName["Name"])):done()
					
					if (t == "LocalBulletArmorReduction") then 
					tableData
						:tag('td'):wikitext("<span style=\"color:red;\">" .. signPrefix(itemName[t]) .. appendSuffix(t) .. "</span> " .. copyVar):done()
					else
					tableData
						:tag('td'):wikitext(signPrefix(itemName[t]) .. appendSuffix(t) .. "</span> " .. copyVar):done()
					end
					
				table.insert(requirements, tableData)
			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

end

return p