Module:Items/ComparisonTables: Difference between revisions

no edit summary
(Use printError function)
No edit summary
(29 intermediate revisions by 4 users not shown)
Line 1: Line 1:
local p = {}
local p = {}


local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local Common = require('Module:Common')
local Modifiers = require('Module:Modifiers')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Items = require('Module:Items')
local Num = require('Module:Number')


local weaponTypes = {'Magic Staff', 'Magic Wand', 'Ranged Weapon', 'Weapon'}
local weaponTypes = {'Magic Staff', 'Magic Wand', 'Ranged Weapon', 'Weapon'}


local styleOverrides = {
local styleOverrides = {
Melee = {'Slayer Helmet (Basic)', 'Slayer Platebody (Basic)', 'Paladin Gloves', 'Desert Wrappings', 'Almighty Lute', 'Candy Cane', 'Bob's Rake', "Knight's Defender", "Ward of Flame Platebody"},
Melee = {'Slayer Helmet (Basic)', 'Slayer Platebody (Basic)', 'Paladin Gloves', 'Desert Wrappings', 'Almighty Lute', 'Candy Cane', "Bob's Rake", "Knight's Defender", "Ward of Flame Platebody"},
Ranged = {'Slayer Cowl (Basic)', 'Slayer Leather Body (Basic)', 'Ice Arrows'},
Ranged = {'Slayer Cowl (Basic)', 'Slayer Leather Body (Basic)', 'Ice Arrows'},
Magic = {'Slayer Wizard Hat (Basic)', 'Slayer Wizard Robes (Basic)', 'Enchanted Shield', 'Elementalist Gloves', 'Frostspark Boots', 'Freezing Touch Body', 'Lightning Boots'},
Magic = {'Slayer Wizard Hat (Basic)', 'Slayer Wizard Robes (Basic)', 'Enchanted Shield', 'Elementalist Gloves', 'Frostspark Boots', 'Freezing Touch Body', 'Lightning Boots'},
Line 18: Line 20:
NotMagic = {'Torrential Blast Crossbow', 'Spectral Ice Sword', 'Lightning Strike 1H Sword', 'FrostSpark 1H Sword'}
NotMagic = {'Torrential Blast Crossbow', 'Spectral Ice Sword', 'Lightning Strike 1H Sword', 'FrostSpark 1H Sword'}
}
}
local function getSlotID(slot)
-- If slot is a slot name, convert it to the slot ID instead
local slotID = Shared.getNamespacedID('melvorD', slot)
local slotData = GameData.getEntityByID('equipmentSlots', slotID)
-- Validate slotID
if slotData == nil then
-- slotID invalid, check if user provided a slot name
slotData = GameData.getEntityByProperty('equipmentSlots', 'emptyName', slot)
if slotData == nil then
return nil
end
slotID = slotData.id
end
return slotID
end
local function getItemDesc(item)
if item.customDescription ~= nil then
return item.customDescription
elseif item.modifiers ~= nil then
return Modifiers.getModifiersText(item.modifiers, false, false)
else
return ''
end
end


function p._getEquipmentTable(itemList, includeModifiers, includeDescription, sortByName)
function p._getEquipmentTable(itemList, includeModifiers, includeDescription, sortByName)
Line 25: Line 53:
--Getting some lists set up here that will be used later
--Getting some lists set up here that will be used later
--First, the list of columns used by both weapons & armour
--First, the list of columns used by both weapons & armour
local statColumns = {'stabAttackBonus', 'slashAttackBonus','blockAttackBonus','rangedAttackBonus', 'magicAttackBonus', 'meleeStrengthBonus', 'rangedStrengthBonus', 'magicDamageBonus', 'meleeDefenceBonus', 'rangedDefenceBonus', 'magicDefenceBonus', 'damageReduction', 'attackLevelRequired', 'defenceLevelRequired', 'rangedLevelRequired', 'magicLevelRequired'}
local statColumns = {
'stabAttackBonus', 'slashAttackBonus', 'blockAttackBonus',  
'rangedAttackBonus', 'magicAttackBonus', 'meleeStrengthBonus',
'rangedStrengthBonus', 'magicDamageBonus', 'meleeDefenceBonus',
'rangedDefenceBonus', 'magicDefenceBonus', 'damageReduction',
'attackLevelRequired', 'strengthLevelRequired', 'defenceLevelRequired',
'rangedLevelRequired', 'magicLevelRequired'
}


if Shared.tableIsEmpty(itemList) then
if Shared.tableIsEmpty(itemList) then
Line 51: Line 86:
local strBonusCols = 2
local strBonusCols = 2
local defBonusCols = 3
local defBonusCols = 3
local lvlReqCols = 4
local lvlReqCols = 5
local ndx = 1
local ndx = 1
while Shared.tableCount(statColumns) >= ndx do
while Shared.tableCount(statColumns) >= ndx do
Line 149: Line 184:
if Shared.contains(statColumns, 'attackLevelRequired') then
if Shared.contains(statColumns, 'attackLevelRequired') then
table.insert(resultPart, '\r\n!'..Icons.Icon({'Attack', type='skill', notext='true'}))
table.insert(resultPart, '\r\n!'..Icons.Icon({'Attack', type='skill', notext='true'}))
end
if Shared.contains(statColumns, 'strengthLevelRequired') then
table.insert(resultPart, '\r\n!'..Icons.Icon({'Strength', type='skill', notext='true'}))
end
end
if Shared.contains(statColumns, 'defenceLevelRequired') then
if Shared.contains(statColumns, 'defenceLevelRequired') then
Line 178: Line 216:
table.insert(resultPart, '\r\n|style="text-align: centre;"|'..Icons.Icon({item.name, type='item', size=50, notext=true}))
table.insert(resultPart, '\r\n|style="text-align: centre;"|'..Icons.Icon({item.name, type='item', size=50, notext=true}))
table.insert(resultPart, '\r\n|' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))
table.insert(resultPart, '\r\n|' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))
table.insert(resultPart, '\r\n| data-sort-value="' .. atkSpeed .. '" style="text-align:right;" |'..Shared.round(atkSpeed / 1000, 3, 1) .. 's')
table.insert(resultPart, '\r\n| data-sort-value="' .. atkSpeed .. '" style="text-align:right;" |'..Num.round(atkSpeed / 1000, 3, 1) .. 's')
--That's the first list out of the way, now for 2-Handed
--That's the first list out of the way, now for 2-Handed
table.insert(resultPart, '\r\n| style="text-align: right;"|')
table.insert(resultPart, '\r\n| style="text-align: right;"|')
Line 192: Line 230:
end
end
end
end
table.insert(resultPart, '"|'..Shared.formatnum(statValue))
table.insert(resultPart, '"|'..Num.formatnum(statValue))
if statName == 'magicDamageBonus' or statName == 'damageReduction' then table.insert(resultPart, '%') end
if statName == 'magicDamageBonus' or statName == 'damageReduction' then table.insert(resultPart, '%') end
end
end
--If requested, add the item Modifiers
--If requested, add the item Modifiers
if includeModifiers then
if includeModifiers then
table.insert(resultPart, '\r\n|')
table.insert(resultPart, '\r\n| ')
local txtLines = {}
local txtLines = {}
local modTxt = Constants.getModifiersText(item.modifiers, true)
if item.modifiers ~= nil then
if modTxt ~= '' then
table.insert(txtLines, Modifiers.getModifiersText(item.modifiers, true, false, 10))
table.insert(txtLines, modTxt)
end
end
--For items with a special attack, show the details
--For items with a special attack, show the details
Line 208: Line 245:
for i, spAttID in ipairs(item.specialAttacks) do
for i, spAttID in ipairs(item.specialAttacks) do
local spAtt = GameData.getEntityByID('attacks', spAttID)
local spAtt = GameData.getEntityByID('attacks', spAttID)
table.insert(txtLines, spAtt.defaultChance .. '% chance for ' .. spAtt.name .. ':')
local attChance = spAtt.defaultChance
if item.overrideSpecialChances ~= nil then
attChance = item.overrideSpecialChances[i]
end
table.insert(txtLines, attChance .. '% chance for ' .. spAtt.name .. ':')
table.insert(txtLines, spAtt.description)
table.insert(txtLines, spAtt.description)
end
end
Line 216: Line 257:
--If requested, add description
--If requested, add description
if includeDescription then
if includeDescription then
table.insert(resultPart, '\r\n| ')
table.insert(resultPart, '\r\n| ' .. getItemDesc(item))
table.insert(resultPart, Constants.getDescription(item.customDescription, item.modifiers) or '')
end
end
else
else
--Building rows for armour
--Building rows for armour
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|'..Icons.Icon({item.name, type='item', size=50, notext=true}))
table.insert(resultPart, '\r\n|'..Icons.Icon({(item.name or 'Unknown'), type='item', size=50, notext=true}))
table.insert(resultPart, '\r\n|' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))
table.insert(resultPart, '\r\n|' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))
for j, statName in pairs(statColumns) do
for j, statName in pairs(statColumns) do
Line 232: Line 272:
table.insert(resultPart, 'table-negative')
table.insert(resultPart, 'table-negative')
end
end
table.insert(resultPart, '"|'..Shared.formatnum(statValue))
table.insert(resultPart, '"|'..Num.formatnum(statValue))
if statName == 'magicDamageBonus' or statName == 'damageReduction' then table.insert(resultPart, '%') end
if statName == 'magicDamageBonus' or statName == 'damageReduction' then table.insert(resultPart, '%') end
end
end
Line 239: Line 279:
table.insert(resultPart, '\r\n| ')
table.insert(resultPart, '\r\n| ')
local txtLines = {}
local txtLines = {}
local modTxt = Constants.getModifiersText(item.modifiers, true)
if item.modifiers ~= nil then
if modTxt ~= '' then
table.insert(txtLines, Modifiers.getModifiersText(item.modifiers, true, false, 10))
table.insert(txtLines, modTxt)
end
end
--For items with a special attack, show the details
--For items with a special attack, show the details
Line 248: Line 287:
for i, spAttID in ipairs(item.specialAttacks) do
for i, spAttID in ipairs(item.specialAttacks) do
local spAtt = GameData.getEntityByID('attacks', spAttID)
local spAtt = GameData.getEntityByID('attacks', spAttID)
table.insert(txtLines, spAtt.defaultChance .. '% chance for ' .. spAtt.name .. ':')
local attChance = spAtt.defaultChance
if item.overrideSpecialChances ~= nil then
attChance = item.overrideSpecialChances[i]
end
table.insert(txtLines, attChance .. '% chance for ' .. spAtt.name .. ':')
table.insert(txtLines, spAtt.description)
table.insert(txtLines, spAtt.description)
end
end
Line 256: Line 299:
--If requested, add description
--If requested, add description
if includeDescription then
if includeDescription then
table.insert(resultPart, '\r\n| ')
table.insert(resultPart, '\r\n| ' .. getItemDesc(item))
table.insert(resultPart, Constants.getDescription(item.customDescription, item.modifiers) or '')
end
end
end
end
Line 268: Line 310:


function p._getCategoryTable(style, slot, other, includeModifiers, includeDescription, sortByName)
function p._getCategoryTable(style, slot, other, includeModifiers, includeDescription, sortByName)
if type(slot) == 'number' then
-- If slot is a slot name, convert it to the slot ID instead
slot = Constants.getEquipmentSlotName(slot)
local slotID = getSlotID(slot)
if slotID == nil then
return Shared.printError('Invalid slot ID: ' .. (slot or 'nil'))
end
end
local slotNS, slotLocalID = Shared.getLocalID(slotID)


local itemList = Items.getItems(function(item)
local itemList = Items.getItems(function(item)
-- Exclude the debug item
if item.id == 'melvorD:DEBUG_ITEM' then
return false
end
-- Exclude Golbin raid exclusives for now, such that they don't
-- Exclude Golbin raid exclusives for now, such that they don't
-- pollute various equipment tables
-- pollute various equipment tables
Line 292: Line 341:
end
end
end
end
if slot == nil or not Shared.contains(item.validSlots, slot) then isMatch = false end
local sID = slotLocalID
if sID == nil or not Shared.contains(item.validSlots, sID) then isMatch = false end


if isMatch and other ~= nil then
if isMatch and other ~= nil then
Line 304: Line 354:
end
end
end
end
if slot == 'Weapon' then --For quiver slot or weapon slot, 'other' is the ammo type
if slotLocalID == 'Weapon' then --For quiver slot or weapon slot, 'other' is the ammo type
isMatch = other == item.ammoTypeRequired
isMatch = other == item.ammoTypeRequired
elseif slot == 'Quiver' then
elseif slotLocalID == 'Quiver' then
if other == 'Thrown' and Shared.contains({'Javelins', 'ThrowingKnives'}, item.ammoType) then
if other == 'Thrown' and Shared.contains({'Javelins', 'ThrowingKnives'}, item.ammoType) then
isMatch = true
isMatch = true
Line 337: Line 387:


function p.getTableForList(frame)
function p.getTableForList(frame)
local stuffString = frame.args ~= nil and frame.args[1] or frame[1]
local pFrame = frame:getParent()
local itemNames = Shared.splitString(stuffString, ',')
local frameArgs = pFrame.args ~= nil and pFrame.args or frame
 
local includeModifiers = frameArgs.includeModifiers ~= nil and string.upper(frameArgs.includeModifiers) == 'TRUE' or false
local includeModifiers = frame.args ~= nil and frame.args[2] or frame[2]
includeModifiers = includeModifiers ~= nil and string.upper(includeModifiers) == 'TRUE' or false


local itemList = {}
local itemList, errItems = {}, {}
local errMsg = 'Some items not found in database: '
local errMsg = 'Some items not found in database: '
local hasErr = false
local hasErr = false
for i, name in Shared.skpairs(itemNames) do
for i, rawItemName in ipairs(frameArgs) do
local nextItem = Items.getItem(Shared.trim(name))
local itemName = Shared.trim(rawItemName)
if nextItem == nil then
local item = Items.getItem(itemName)
errMsg = errMsg.." '"..name.."'"
if item == nil then
hasErr = true
table.insert(errItems, "'" .. itemName .. "'")
else
else
table.insert(itemList, nextItem)
table.insert(itemList, item)
end
end
end
end


if hasErr then
if not Shared.tableIsEmpty(errItems) then
return Shared.printError(errMsg)
return Shared.printError('Some items not found in database: ' .. table.concat(errItems, ', '))
else
else
return p._getEquipmentTable(itemList, includeModifiers)
return p._getEquipmentTable(itemList, includeModifiers)
Line 365: Line 413:
function p.getDoubleLootTable(frame)
function p.getDoubleLootTable(frame)
local modsDL = {
local modsDL = {
'increasedChanceToDoubleLootCombat',
["id"] = {
'decreasedChanceToDoubleLootCombat',
'melvorD:doubleItemsSkill',
'increasedChanceToDoubleLootThieving',
'melvorD:doubleItemsChanceAgainstDamageType'
'decreasedChanceToDoubleLootThieving',
},
'increasedChanceToDoubleItemsGlobal',
["alias"] = {
'decreasedChanceToDoubleItemsGlobal'
'increasedChanceToDoubleLootCombat',
'decreasedChanceToDoubleLootCombat',
'increasedChanceToDoubleItemsGlobal',
'decreasedChanceToDoubleItemsGlobal'
}
}
}
local modDetail = {}
local matchCriteria = Modifiers.getMatchCriteriaFromIDs(modsDL.id, modsDL.alias)
for i, modName in pairs(modsDL) do
local itemMatchedMods = {}
local mName, mText, mSign, mIsNeg, mValUnsigned = Constants.getModifierDetails(modName)
local itemList = Items.getItems(
modDetail[modName] = { mult = (mSign == "+" and 1 or -1) }
function(item)
end
 
local itemList = Items.getItems(function(item)
if item.modifiers ~= nil then
if item.modifiers ~= nil then
for modName, val in pairs(item.modifiers) do
local matchedMods = Modifiers.getMatchingModifiers(item.modifiers, matchCriteria)
if Shared.contains(modsDL, modName) then return true end
if Shared.tableIsEmpty(matchedMods.matched) then
return false
else
itemMatchedMods[item.id] = matchedMods.matched
return true
end
end
return false
end
end
end)
end
)


local resultPart = {}
local resultPart = {}
Line 391: Line 444:
table.insert(resultPart, '\r\n!colspan="2"|Name!!Bonus!!Description')
table.insert(resultPart, '\r\n!colspan="2"|Name!!Bonus!!Description')
for i, item in Shared.skpairs(itemList) do
for i, item in Shared.skpairs(itemList) do
local lootValue = 0
local lootValue = Modifiers.getModifierValue(itemMatchedMods[item.id])
for modName, modDet in pairs(modDetail) do
 
lootValue = lootValue + (item.modifiers[modName] or 0) * modDet.mult
end
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|data-sort-value="'..item.name..'"|'..Icons.Icon({item.name, type='item', size=50, notext=true}))
table.insert(resultPart, '\r\n|data-sort-value="'..item.name..'"|'..Icons.Icon({item.name, type='item', size=50, notext=true}))
table.insert(resultPart, '||' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))
table.insert(resultPart, '||' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..lootValue..'"|'..lootValue..'%')
table.insert(resultPart, '||style ="text-align: right;" data-sort-value="'..lootValue..'"|'..lootValue..'%')
table.insert(resultPart, '||'..(Constants.getDescription(item.customDescription, item.modifiers) or ''))
table.insert(resultPart, '||' .. getItemDesc(item))
end
end


Line 406: Line 457:
end
end


function p.getStatChangeString(item1, item2)
function p.getItemUpgradeTable(frame)
--Used by getItemUpgradeTable to get the stat change between two items
local args = frame.args ~= nil and frame.args or frame
local changeArray = {}
local category, usedItemName = args[1], args.usedItem
 
local upgradeArray = {}
local getSpecificStatString = function(val1, val2, subStr)
local isEquipment = false
if val1 == nil then val1 = 0 end
if val2 == nil then val2 = 0 end
local usedItemID = nil
 
if usedItemName ~= nil and usedItemName ~= '' then
if val1 ~= val2 then
local usedItem = Items.getItem(usedItemName)
local txt = string.gsub(subStr, '{V}', Shared.numStrWithSign(val1 - val2))
if usedItem == nil then
table.insert(changeArray, txt)
return Shared.printError('Used item not found: ' .. usedItemName)
end
usedItemID = usedItem.id
end
local function upgradeConsumesItem(itemUpgrade, itemID)
if itemID == nil then
return true
end
for i, itemCost in ipairs(itemUpgrade.itemCosts) do
if itemCost.id == itemID then
return true
end
end
end
end
 
return false
--Unfortunately just gonna have to manually check all the changes I think...
local statList = {
-- {'statName', 'statDescription'}
{'stabAttackBonus', '{V} '..Icons.Icon({'Melee', notext=true})..' Stab Bonus'},
{'slashAttackBonus', '{V} '..Icons.Icon({'Melee', notext=true})..' Slash Bonus'},
{'blockAttackBonus', '{V} '..Icons.Icon({'Melee', notext=true})..' Block Bonus'},
{'meleeStrengthBonus', '{V} '..Icons.Icon({'Strength', type='skill', notext=true})..' Strength Bonus'},
{'rangedStrengthBonus', '{V} '..Icons.Icon({'Ranged', type='skill', notext=true})..' Strength Bonus'},
{'magicStrengthBonus', '{V}% '..Icons.Icon({'Magic', type='skill', notext=true})..' Damage Bonus'},
{'meleeDefenceBonus', '{V} '..Icons.Icon({'Defence', type='skill', notext=true})..' Defence Bonus'},
{'rangedDefenceBonus', '{V} '..Icons.Icon({'Ranged', type='skill', notext=true})..' Defence Bonus'},
{'magicDefenceBonus', '{V} '..Icons.Icon({'Magic', type='skill', notext=true})..' Defence Bonus'},
{'damageReduction', '{V}% Damage Reduction'},
{'increasedSlayerXP', '{V}% '..Icons.Icon({'Slayer', type='skill', notext=true})..' Bonus XP'},
{'attackLevelRequired', '{V} '..Icons.Icon({'Attack', type='skill', notext=true})..' Level Required'},
{'defenceLevelRequired', '{V} '..Icons.Icon({'Defence', type='skill', notext=true})..' Level Required'},
{'rangedLevelRequired', '{V} '..Icons.Icon({'Ranged', type='skill', notext=true})..' Level Required'},
{'magicLevelRequired', '{V} '..Icons.Icon({'Magic', type='skill', notext=true})..' Level Required'},
}
for i, stat in ipairs(statList) do
if stat[1] == 'increasedSlayerXP' then
getSpecificStatString(Items._getItemModifier(item1, stat[1], 'Slayer'), Items._getItemModifier(item2, stat[1], 'Slayer'), stat[2])
else
getSpecificStatString(Items._getItemStat(item1, stat[1]), Items._getItemStat(item2, stat[1]), stat[2])
end
end
end
return table.concat(changeArray, '<br/>')
end
function p.getItemUpgradeTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
local upgradeArray = {}
local isEquipment = false


if string.upper(category) == 'POTION' then
if string.upper(category) == 'POTION' then
upgradeArray = GameData.getEntities('itemUpgrades',
upgradeArray = GameData.getEntities('itemUpgrades',
function(upgrade) return Shared.contains(upgrade.upgradedItemID, 'Potion') end
function(upgrade)
return Shared.contains(upgrade.upgradedItemID, 'Potion') and upgradeConsumesItem(upgrade, usedItemID)
end
)
)
elseif string.upper(category) == 'OTHER' then
elseif string.upper(category) == 'OTHER' then
upgradeArray = GameData.getEntities('itemUpgrades',
upgradeArray = GameData.getEntities('itemUpgrades',
function(upgrade)
function(upgrade)
if not Shared.contains(upgrade.upgradedItemID, 'Potion') then
if not Shared.contains(upgrade.upgradedItemID, 'Potion') and upgradeConsumesItem(upgrade, usedItemID) then
local item = Items.getItemByID(upgrade.upgradedItemID)
local item = Items.getItemByID(upgrade.upgradedItemID)
if item ~= nil then
if item ~= nil then
Line 472: Line 503:
)
)
else
else
if Constants.getEquipmentSlotID(category) == nil then
-- If category is a slot name, convert it to the slot ID instead
local slotID = getSlotID(category)
if slotID ~= nil then
local slotNS, slotLocalID = Shared.getLocalID(slotID)
category = slotLocalID
end
 
if category == nil then
return Shared.printError('Invalid option. Choose either an equipment slot, Potion, or Other')
return Shared.printError('Invalid option. Choose either an equipment slot, Potion, or Other')
end
end
Line 478: Line 516:
upgradeArray = GameData.getEntities('itemUpgrades',
upgradeArray = GameData.getEntities('itemUpgrades',
function(upgrade)
function(upgrade)
local item = Items.getItemByID(upgrade.upgradedItemID)
if upgradeConsumesItem(upgrade, usedItemID) then
if item ~= nil then
local item = Items.getItemByID(upgrade.upgradedItemID)
return item.validSlots ~= nil and Shared.contains(item.validSlots, category)
if item ~= nil then
return item.validSlots ~= nil and Shared.contains(item.validSlots, category)
end
end
end
return false
return false
Line 487: Line 527:
end
end


local useStatChange = isEquipment or (string.upper(category) == 'POTION')
local resultPart = {}
local resultPart = {}
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '\r\n|- class="headerRow-0"')
table.insert(resultPart, '\r\n|- class="headerRow-0"')
table.insert(resultPart, '\r\n!colspan="2"|Upgraded Item!!Ingredients')
table.insert(resultPart, '\r\n!colspan="2"|Upgraded Item!!Ingredients')
if isEquipment then table.insert(resultPart, '!!Stat Change') end
if useStatChange then table.insert(resultPart, '!!Stat Change') end


for i, upgrade in ipairs(upgradeArray) do
for i, upgrade in ipairs(upgradeArray) do
Line 499: Line 540:
table.insert(resultPart, '||' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))
table.insert(resultPart, '||' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))


local matArray = {}
table.insert(resultPart, '|| ' .. Common.getCostString({ items = upgrade.itemCosts, gp = upgrade.gpCost, sc = upgrade.scCost}, 'None'))
local statChangeString = ''
 
for i, itemCost in ipairs(upgrade.itemCosts) do
if useStatChange then
local mat = Items.getItemByID(itemCost.id)
-- Generate stat change column
if mat ~= nil then
local statChangeString = ''
table.insert(matArray, Icons.Icon({mat.name, type='item', qty=itemCost.quantity}))
if not Shared.tableIsEmpty(upgrade.rootItemIDs) then
if isEquipment and item.validSlots ~= nil and mat.validSlots ~= nil and statChangeString == '' then
-- Some items (e.g. FEZ) may have multiple root items. Simply use the first one
statChangeString = p.getStatChangeString(item, mat)
local rootItem = Items.getItemByID(upgrade.rootItemIDs[1])
if rootItem ~= nil then
statChangeString = Items.getStatChangeString(item, rootItem)
end
end
end
end
table.insert(resultPart, '|| '..statChangeString)
end
end
if upgrade.gpCost ~= nil and upgrade.gpCost > 0 then
end
table.insert(matArray, Icons.GP(upgrade.gpCost))
 
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
 
function p.getRuneProvidingItemTable(frame)
local itemArray = Items.getItems(function(item) return item.providedRunes ~= nil end)
local resultPart = {}
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '\r\n|- class="headerRow-0"')
table.insert(resultPart, '\r\n!colspan="2"|Item!!Runes Provided')
for i, item in pairs(itemArray) do
local PR = item.providedRunes
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|style="text-align: centre;"|'..Icons.Icon({item.name, type='item', size=50, notext=true}))
table.insert(resultPart, '\r\n|' .. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}))
local runeLines = {}
local sortVal = ''
for j, runePair in pairs(PR) do
local runeID = runePair.id
local qty = runePair.quantity
local rune = Items.getItemByID(runeID)
sortVal = sortVal..rune.name..qty
table.insert(runeLines, Icons.Icon({rune.name, type='item', qty=qty}))
end
end
if upgrade.scCost ~= nil and upgrade.scCost > 0 then
table.insert(resultPart, '\r\n|data-sort-value="'..sortVal..'"|'..table.concat(runeLines, '<br/>'))
table.insert(matArray, Icons.SC(upgrade.scCost))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
 
function p._getDRTable(slots, items)
local resultPart = {}
table.insert(resultPart, '{| class="wikitable sortable" style="width:90%;"')
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n! style="width:4%"|DR%')
for i, slot in pairs(slots) do
table.insert(resultPart, '\r\n! '..slot)
end
local DRTable = {}
table.sort(items, function(a, b) return a.name < b.name end)
for i, item in pairs(items) do
local DR = Items._getItemStat(item, 'damageReduction', true)
local EquipSlot = Items._getItemEquipSlot(item)
if DRTable[DR] == nil then
DRTable[DR] = {}
end
end
table.insert(resultPart, '||'..table.concat(matArray, '<br/>'))
if DRTable[DR][EquipSlot] == nil then
 
DRTable[DR][EquipSlot] = {}
if isEquipment then
end
table.insert(resultPart, '||'..statChangeString)
table.insert(DRTable[DR][EquipSlot], Icons.Icon({item.name, type='item', expicon = Icons.getExpansionIcon(item.id)}))
end
for DR, SlotTables in Shared.skpairs(DRTable) do
table.insert(resultPart, '\r\n|-\r\n|'..DR..'%')
for i, SlotName in pairs(slots) do
table.insert(resultPart, '\r\n|')
if SlotTables[SlotName] ~= nil then
table.insert(resultPart, table.concat(SlotTables[SlotName], '<br/>'))
end
end
end
end
end
 
table.insert(resultPart, '\r\n|}')
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
return table.concat(resultPart)
end
function p.getDRTable(frame)
local style = frame.args ~= nil and frame.args[1] or frame
local SlotNames = {}
local ItemList = {}
if style == 'Other' then
SlotNames = {'Helmet', 'Platelegs', 'Gloves', 'Shield', 'Cape', 'Amulet', 'Ring'}
else
SlotNames = {'Helmet', 'Platebody', 'Platelegs', 'Boots', 'Gloves', 'Weapon', 'Shield'}
end
ItemList =  Items.getItems(function(item)
local isMatch = true
if Items._getItemStat(item, 'damageReduction', true) <= 0 then
return false
end
-- Exclude Golbin raid exclusives for now, such that they don't
-- pollute various equipment tables
if item.golbinRaidExclusive ~= nil and item.golbinRaidExclusive then
return false
end
--Using the same checks for Melee/Ranged/Magic that the Equipment Tables use
if style == 'Melee' then
if ((Items._getItemStat(item, 'defenceLevelRequired') == nil and Items._getItemStat(item, 'attackLevelRequired') == nil) and not Shared.contains(styleOverrides.Melee, item.name)) or Shared.contains(styleOverrides.NotMelee, item.name) then isMatch = false end
elseif style == 'Ranged' then
if (Items._getItemStat(item, 'rangedLevelRequired') == nil and not Shared.contains(styleOverrides.Ranged, item.name)) or Shared.contains(styleOverrides.NotRanged, item.name)  then isMatch = false end
elseif style == 'Magic' then
if (Items._getItemStat(item, 'magicLevelRequired') == nil and not Shared.contains(styleOverrides.Magic, item.name)) or Shared.contains(styleOverrides.NotMagic, item.name) then isMatch = false end
else
if (Items._getItemStat(item, 'attackLevelRequired') ~= nil or Items._getItemStat(item, 'defenceLevelRequired') ~= nil or Items._getItemStat(item, 'rangedLevelRequired') ~= nil or Items._getItemStat(item, 'magicLevelRequired') ~= nil or
Shared.contains(styleOverrides.Melee, item.name) or Shared.contains(styleOverrides.Ranged, item.name) or Shared.contains(styleOverrides.Magic, item.name)) and
not Shared.contains(styleOverrides.None, item.name) then
isMatch = false
end
end
if isMatch and not Shared.contains(SlotNames, Items._getItemEquipSlot(item)) then
isMatch = false
end
return isMatch
end)
return p._getDRTable(SlotNames, ItemList)
end
end


return p
return p
2,875

edits