Module:ItemTables: Difference between revisions

Jump to navigation Jump to search
No edit summary
Instead of removing duplicates, keep all stats and use rowspan to merge the item info across multiple rows. Added FervorMovespeed to move speed
Line 4: Line 4:
local get_type = require("Module:ItemData")._get_type
local get_type = require("Module:ItemData")._get_type
local commas = require("Module:Addcommas")
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 = {}
local hash = {}
local noDuplicates = {}
for _, v in pairs(data) do
for _, value in ipairs(property) do
if (v[value] ~= nil and v["IsDisabled"] == false and v["Name"] ~= nil and v[value] ~= "0" and v[value] ~= "0m" and v[value] ~= "") then
table.insert(similarItems, v)
end
end
end
-- remove duplicate items if that item contains multiple keys of the same stat increase (eg. Fleetfoot has both "BonusMoveSpeed", "ActiveBonusMoveSpeed" in move speed).
-- there might be a more efficient way to prevent adding duplicate items in the first place in the above for loop
for _, v in pairs(similarItems) do
if (not hash[v]) then
noDuplicates[#noDuplicates+1] = v
hash[v] = true
end
end
return noDuplicates
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)
--- Copies original table with its children as deep as possible. Does not handle metatables. (Copy is needed because Lua passes by reference, not value)
Line 73: Line 46:
friendly_to_internal["bullet lifesteal"] = { "BulletLifestealPercent", "ActiveBonusLifesteal" }
friendly_to_internal["bullet lifesteal"] = { "BulletLifestealPercent", "ActiveBonusLifesteal" }
friendly_to_internal["spirit lifesteal"] = { "AbilityLifestealPercentHero" }
friendly_to_internal["spirit lifesteal"] = { "AbilityLifestealPercentHero" }
friendly_to_internal["move speed"] = { "BonusMoveSpeed", "ActiveBonusMoveSpeed" }
friendly_to_internal["move speed"] = { "BonusMoveSpeed", "ActiveBonusMoveSpeed", "FervorMovespeed"}
friendly_to_internal["sprint speed"] = { "BonusSprintSpeed" }
friendly_to_internal["sprint speed"] = { "BonusSprintSpeed" }
friendly_to_internal["movement slow"] = { "SlowPercent", "MovementSpeedSlow" }
friendly_to_internal["movement slow"] = { "SlowPercent", "MovementSpeedSlow" }
Line 138: Line 111:
"GroundDashReductionPercent"
"GroundDashReductionPercent"
     },
     },
["m/s"] = { "BonusMoveSpeed", "ActiveBonusMoveSpeed", "BonusSprintSpeed" },
["m/s"] = { "BonusMoveSpeed", "ActiveBonusMoveSpeed", "BonusSprintSpeed", "FervorMovespeed"},
[" HP"] = {"CombatBarrier", "GuardianWardCombatBarrier", "VexBarrierCombatBarrier"}
[" HP"] = {"CombatBarrier", "GuardianWardCombatBarrier", "VexBarrierCombatBarrier"}
}
}
Line 172: Line 145:
-- @return    {string} The formatted wikitext string.
-- @return    {string} The formatted wikitext string.
local function signPrefix(value)
local function signPrefix(value)
-- Returns an empty string if the input is nil to prevent errors.
if value == nil then
if value == nil then
return ""
return ""
end
end
-- Converts the input to a string to safely use string methods. This allows
-- the function to handle numbers from JSON (e.g., 10) that are not strings.
value = tostring(value)
value = tostring(value)
-- Removes the 'm' suffix if it exists (e.g., from range values like "7m").
value = value:gsub("m", "")
value = value:gsub("m", "")
-- Convert the cleaned string into a number for comparison.
value = tonumber(value)
value = tonumber(value)
-- Returns an empty string if the value cannot be converted to a number,
-- which prevents errors and malformed output.
if not value then
if not value then
return ""
return ""
end
end
if (value >= 0) then
if (value >= 0) then
return "+<b>" .. value .. "</b>"
return "+<b>" .. value .. "</b>"
Line 207: Line 169:
local requirements = {}
local requirements = {}
local listofKeysTable = {}
local listofKeysTable = {}
local listofItems = ""
local property = frame:getParent().args[1] or mw.title.getCurrentTitle().text
local property = frame:getParent().args[1] or mw.title.getCurrentTitle().text
local copyVar = property
local copyVar = property
-- Get internal keys corresponding to the friendly property name
listofKeysTable = friendlyNames(property)  
listofKeysTable = friendlyNames(property)  
local filteredData = {}
local filteredData = {}
filteredData = get_similar_items_array(listofKeysTable)
for _, v in pairs(data) do
for _, t in ipairs(listofKeysTable) do
if v[t] ~= nil and v["IsDisabled"] == false and v["Name"] ~= nil and v[t] ~= "0" and v[t] ~= "0m" and v[t] ~= "" then
table.insert(filteredData, v)
break
end
end
end
 
table.sort(filteredData, defaultSort())
table.sort(filteredData, defaultSort())
 
local createTable = mw.html.create('table')
local createTable = mw.html.create('table')
:addClass('wikitable sortable')
:addClass('wikitable sortable')
:tag('caption'):wikitext("List of items"):done()
:tag('caption'):wikitext("List of items"):done()
 
local soulIcon = frame:expandTemplate{ title = 'Souls' }
local soulIcon = frame:expandTemplate{ title = 'Souls' }
 
local createTableHeader = mw.html.create('tr')
local createTableHeader = mw.html.create('tr')
createTableHeader
createTableHeader
Line 227: Line 199:
:tag('th'):wikitext('Category'):done()
:tag('th'):wikitext('Category'):done()
:tag('th'):wikitext('Stat change'):done()
:tag('th'):wikitext('Stat change'):done()
createTable:node(createTableHeader)
createTable:node(createTableHeader)
 
-- query all the filtered items. itemName is the item table.
-- Track rowspans for items with multiple stats
for internalName, itemName in ipairs(filteredData) do  
local rowspanTracker = {}
local display = frame:expandTemplate{
 
title = 'ItemIcon',
for _, itemName in ipairs(filteredData) do  
args = {
local display = frame:expandTemplate{
itemName["Name"]
title = 'ItemIcon',
}
args = { itemName["Name"] }
}
}
 
for k, t in pairs(listofKeysTable) do
local statCount = 0
-- filter out items that: don't have the property and the value isn't zero
for _, t in pairs(listofKeysTable) do
if(itemName[t] ~= nil and itemName[t] ~= "0" ) then
if(itemName[t] ~= nil and itemName[t] ~= "0") then
statCount = statCount + 1
end
end
if statCount == 0 then statCount = 1 end
rowspanTracker[itemName["Name"]] = statCount
 
local firstStat = true
for _, t in pairs(listofKeysTable) do
if(itemName[t] ~= nil and itemName[t] ~= "0") then
-- Handles complex stat values from the JSON data.
-- Handles complex stat values from the JSON data.
-- A stat can be a simple value (e.g., "BonusMoveSpeed": "1") or a table containing
-- A stat can be a simple value (e.g., "BonusMoveSpeed": "1") or a table containing
-- scaling info (e.g., "BonusFireRate": { "Value": 10, "Scale": ... }).
-- scaling info (e.g., "BonusFireRate": { "Value": 10, "Scale": ... }).
-- This code checks if the stat is a table and extracts the base numerical value from its 'Value' key.
-- This code checks if the stat is a table and extracts the base numerical value from its 'Value' key.
local statValue = itemName[t]
local statValue = itemName[t]
if type(statValue) == 'table' and statValue.Value ~= nil then
if type(statValue) == 'table' and statValue.Value ~= nil then
statValue = statValue.Value
statValue = statValue.Value
end
end
 
listofItems = listofItems .. itemName["Name"] .. "<br/>"
copyVar = copyVar:gsub("^%l", string.upper)
copyVar = copyVar:gsub("^%l", string.upper)
 
local categoryDisplay
-- Get category display using ItemType template with appropriate parameters
if itemName["Slot"] == "Armor" then
local categoryDisplay
categoryDisplay = frame:expandTemplate{
if itemName["Slot"] == "Armor" then
title = 'ItemType',
categoryDisplay = frame:expandTemplate{
args = { "Armor", "Vitality" }
title = 'ItemType',
}
args = { "Armor", "Vitality" }
elseif itemName["Slot"] == "Tech" then
}
categoryDisplay = frame:expandTemplate{
elseif itemName["Slot"] == "Tech" then
title = 'ItemType',
categoryDisplay = frame:expandTemplate{
args = { "Tech", "Spirit" }
title = 'ItemType',
}
args = { "Tech", "Spirit" }
else
}
categoryDisplay = frame:expandTemplate{
else -- Weapon
title = 'ItemType',
categoryDisplay = frame:expandTemplate{
args = { "Weapon", "Weapon" }
title = 'ItemType',
}
args = { "Weapon", "Weapon" }
end
}
 
end
local tableData = mw.html.create('tr')
 
local tableData = mw.html.create('tr')
if firstStat then
tableData
tableData
:tag('td'):wikitext(display):done()
:tag('td'):attr('rowspan', statCount):wikitext(display):done()
:tag('td'):wikitext(commas._add(get_cost(itemName["Name"]))):done()
:tag('td'):attr('rowspan', statCount):wikitext(commas._add(get_cost(itemName["Name"]))):done()
:tag('td'):wikitext(categoryDisplay):done()
:tag('td'):attr('rowspan', statCount):wikitext(categoryDisplay):done()
-- Construct the stat change string.
firstStat = false
:tag('td'):wikitext(signPrefix(statValue) .. appendSuffix(t) .. " " .. copyVar):done()
table.insert(requirements, tableData)
end
end
tableData:tag('td'):wikitext(signPrefix(statValue) .. appendSuffix(t) .. " " .. copyVar):done()
table.insert(requirements, tableData)
end
end
end
end
end
 
 
for _, row in ipairs(requirements) do
for _, row in ipairs(requirements) do
createTable:node(row)
createTable:node(row)
end
end
 
return tostring(createTable)
return tostring(createTable)
end
end


return p
return p