Module:Items/ComparisonTables: Difference between revisions

no edit summary
(getItemUpgradeTable: Refactor)
No edit summary
(10 intermediate revisions by 3 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 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'}
Line 19: 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 189: 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 203: 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 219: 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 227: 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 243: 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 250: 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 259: 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 267: 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 280: Line 311:
function p._getCategoryTable(style, slot, other, includeModifiers, includeDescription, sortByName)
function p._getCategoryTable(style, slot, other, includeModifiers, includeDescription, sortByName)
-- If slot is a slot name, convert it to the slot ID instead
-- If slot is a slot name, convert it to the slot ID instead
slot = Constants.getEquipmentSlotID(slot) or (Constants.getEquipmentSlotName(slot) ~= nil and slot)
local slotID = getSlotID(slot)
if slotID == nil then
return Shared.printError('Invalid slot ID: ' .. (slot or 'nil'))
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 302: 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 314: 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 347: 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]
local itemList, errItems = {}, {}
includeModifiers = includeModifiers ~= nil and string.upper(includeModifiers) == 'TRUE' or false
 
local itemList = {}
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 375: 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 401: 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 417: Line 458:


function p.getItemUpgradeTable(frame)
function p.getItemUpgradeTable(frame)
local category = frame.args ~= nil and frame.args[1] or frame
local args = frame.args ~= nil and frame.args or frame
local category, usedItemName = args[1], args.usedItem
local upgradeArray = {}
local upgradeArray = {}
local isEquipment = false
local isEquipment = false
local usedItemID = nil
if usedItemName ~= nil and usedItemName ~= '' then
local usedItem = Items.getItem(usedItemName)
if usedItem == nil then
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
return false
end


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 439: Line 504:
else
else
-- If category is a slot name, convert it to the slot ID instead
-- If category is a slot name, convert it to the slot ID instead
category = Constants.getEquipmentSlotID(category) or (Constants.getEquipmentSlotName(category) ~= nil and category)
local slotID = getSlotID(category)
if slotID ~= nil then
local slotNS, slotLocalID = Shared.getLocalID(slotID)
category = slotLocalID
end
 
if category == nil then
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')
Line 446: 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
2,875

edits