Module:Items/ComparisonTables: Difference between revisions

m
no edit summary
(Added first pass at a getDRTable function)
mNo edit summary
 
(18 intermediate revisions by 3 users not shown)
Line 4: Line 4:
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 Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Items = require('Module:Items')
Line 10: Line 11:


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 25: Line 26:
--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 59:
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 157:
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 208: Line 219:
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 248: Line 263:
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 268: Line 287:


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)
slot = Constants.getEquipmentSlotID(slot) or (Constants.getEquipmentSlotName(slot) ~= nil and slot)
end


local itemList = Items.getItems(function(item)
local itemList = Items.getItems(function(item)
Line 374: Line 392:
local modDetail = {}
local modDetail = {}
for i, modName in pairs(modsDL) do
for i, modName in pairs(modsDL) do
local mName, mText, mSign, mIsNeg, mValUnsigned = Constants.getModifierDetails(modName)
local mName, mText, mIsNeg, mModifyValue = Constants.getModifierDetails(modName)
modDetail[modName] = { mult = (mSign == "+" and 1 or -1) }
modDetail[modName] = { mult = (mIsNeg == false and 1 or -1) }
end
end


Line 404: Line 422:
table.insert(resultPart, '\r\n|}')
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
return table.concat(resultPart)
end
function p.getStatChangeString(item1, item2)
--Used by getItemUpgradeTable to get the stat change between two items
local changeArray = {}
local getSpecificStatString = function(val1, val2, subStr)
if val1 == nil then val1 = 0 end
if val2 == nil then val2 = 0 end
if val1 ~= val2 then
local txt = string.gsub(subStr, '{V}', Shared.numStrWithSign(val1 - val2))
table.insert(changeArray, txt)
end
end
--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
return table.concat(changeArray, '<br/>')
end
end


Line 472: Line 446:
)
)
else
else
if Constants.getEquipmentSlotID(category) == nil then
-- If category is a slot name, convert it to the slot ID instead
category = Constants.getEquipmentSlotID(category) or (Constants.getEquipmentSlotName(category) ~= nil and category)
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 487: Line 463:
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 476:
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
end
table.insert(resultPart, '|| '..statChangeString)
if upgrade.gpCost ~= nil and upgrade.gpCost > 0 then
table.insert(matArray, Icons.GP(upgrade.gpCost))
end
if upgrade.scCost ~= nil and upgrade.scCost > 0 then
table.insert(matArray, Icons.SC(upgrade.scCost))
end
table.insert(resultPart, '||'..table.concat(matArray, '<br/>'))
 
if isEquipment then
table.insert(resultPart, '||'..statChangeString)
end
end
end
end
Line 567: Line 536:
local DRTable = {}
local DRTable = {}
table.sort(items, function(a, b) return a.name < b.name end)
for i, item in pairs(items) do
for i, item in pairs(items) do
Line 577: Line 547:
DRTable[DR][EquipSlot] = {}
DRTable[DR][EquipSlot] = {}
end
end
local itemString = Icons.getExpansionIcon(item.id)..Icons.Icon({item.name, type='item'})
table.insert(DRTable[DR][EquipSlot], Icons.Icon({item.name, type='item', expicon = Icons.getExpansionIcon(item.id)}))
table.insert(DRTable[DR][EquipSlot], itemString)
end
end
Line 586: Line 555:
table.insert(resultPart, '\r\n|')
table.insert(resultPart, '\r\n|')
if SlotTables[SlotName] ~= nil then
if SlotTables[SlotName] ~= nil then
table.sort(SlotTables[SlotName], function(a, b) return a < b end)
table.insert(resultPart, table.concat(SlotTables[SlotName], '<br/>'))
table.insert(resultPart, table.concat(SlotTables[SlotName], '<br/>'))
end
end
Line 602: Line 570:
local ItemList = {}
local ItemList = {}
if style == 'Other' then
if style == 'Other' then
SlotNames = {'Cape', 'Amulet', 'Ring'}
SlotNames = {'Helmet', 'Platelegs', 'Gloves', 'Shield', 'Cape', 'Amulet', 'Ring'}
ItemList =  Items.getItems(function(item)
if Items._getItemStat(item, 'damageReduction', true) <= 0 then
return false
end
return Shared.contains(SlotNames, Items._getItemEquipSlot(item))
end)
else
else
SlotNames = {'Helmet', 'Platebody', 'Platelegs', 'Boots', 'Gloves', 'Shield'}
SlotNames = {'Helmet', 'Platebody', 'Platelegs', 'Boots', 'Gloves', 'Weapon', 'Shield'}
ItemList =  Items.getItems(function(item)
end
local isMatch = true
if Items._getItemStat(item, 'damageReduction', true) <= 0 then
ItemList =  Items.getItems(function(item)
return false
local isMatch = true
end
if Items._getItemStat(item, 'damageReduction', true) <= 0 then
--Using the same checks for Melee/Ranged/Magic that the Equipment Tables use
return false
if style == 'Melee' then
end
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
-- Exclude Golbin raid exclusives for now, such that they don't
elseif style == 'Ranged' then
-- pollute various equipment tables
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
if item.golbinRaidExclusive ~= nil and item.golbinRaidExclusive then
elseif style == 'Magic' then
return false
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
end
end
--Using the same checks for Melee/Ranged/Magic that the Equipment Tables use
if isMatch and not Shared.contains(SlotNames, Items._getItemEquipSlot(item)) then
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
isMatch = false
end
end
return isMatch
end
end)
if isMatch and not Shared.contains(SlotNames, Items._getItemEquipSlot(item)) then
end
isMatch = false
end
return isMatch
end)
return p._getDRTable(SlotNames, ItemList)
return p._getDRTable(SlotNames, ItemList)