Anonymous

Module:Sandbox/Items: Difference between revisions

From Melvor Idle
no edit summary
(Testing updated modifiers)
No edit summary
Line 7: Line 7:


local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local Constants = require('Module:Sandbox/Constants')
local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local Modifiers = require('Module:Modifiers')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Num = require('Module:Number')


p.EasterEggs = {'Amulet of Calculated Promotion', 'Clue Chasers Insignia', '8', 'Lemon', 'Easter Egg',
p.EasterEggs = {'Amulet of Calculated Promotion', 'Clue Chasers Insignia', '8', 'Lemon', 'Easter Egg',
Line 23: Line 25:
'Holiday Scarf', 'Gingerbread House', 'Gingerbread Man', 'Edible Candy Cane',
'Holiday Scarf', 'Gingerbread House', 'Gingerbread Man', 'Edible Candy Cane',
'Locked Chest', 'Locked Chest Key', 'Event Token (Holiday 2021)'}
'Locked Chest', 'Locked Chest Key', 'Event Token (Holiday 2021)'}
-- List of item IDs that should typically not be included within outputs, usually
-- because they are not fully implemented despite existing within the game data
p.HiddenItems = {}
local function populateHiddenItems()
local hiddenItems = GameData.getEntities('items',
function(item)
return item.name == nil or Shared.contains({'melvorTotH:Meteorite_Dust'}, item.id)
end
)
for _, item in ipairs(hiddenItems) do
table.insert(p.HiddenItems, item.id)
end
end
populateHiddenItems()


function p.getItemByID(ID)
function p.getItemByID(ID)
Line 29: Line 46:


function p.getItem(name)
function p.getItem(name)
name = string.gsub(name, "%%27", "'")
name = Shared.fixPagename(name)
name = string.gsub(name, "'", "'")
return GameData.getEntityByName('items', name)
return GameData.getEntityByName('items', name)
end
end


function p.getItems(checkFunc)
function p.getItems(checkFunc)
return GameData.getEntities('items', checkFunc)
return GameData.getEntities('items',
function(obj)
return not Shared.contains(p.HiddenItems, obj.id) and checkFunc(obj)
end
)
end
end


Line 78: Line 98:
end
end
elseif string.find(StatName, '^(.+)LevelRequired$') ~= nil and item.equipRequirements ~= nil then
elseif string.find(StatName, '^(.+)LevelRequired$') ~= nil and item.equipRequirements ~= nil then
local skillName = Shared.titleCase(string.match(StatName, '^(.+)LevelRequired$'))
local skillName = nil
if (string.find(StatName, '^(.+)Abyssal$')) then
skillName = Shared.titleCase(string.match(StatName, '^(.+)AbyssalLevelRequired$'))
else
skillName = Shared.titleCase(string.match(StatName, '^(.+)LevelRequired$'))
end
if skillName ~= nil then
if skillName ~= nil then
local skillID = Constants.getSkillID(skillName)
local skillID = Constants.getSkillID(skillName)
Line 85: Line 110:
if requirement.type == "SkillLevel" and requirement.skillID == skillID then
if requirement.type == "SkillLevel" and requirement.skillID == skillID then
result = requirement.level
result = requirement.level
break
end
if requirement.type == "AbyssalLevel" and requirement.skillID == skillID then
result = requirement.abyssalLevel
break
break
end
end
Line 112: Line 141:
if result == nil and ZeroIfNil then result = 0 end
if result == nil and ZeroIfNil then result = 0 end
return result
return result
end
function p.getItemValueByID(itemID)
local item = p.getItemByID(itemID)
if item == nil then
return 0
end
return p.getItemValue(item['name'])
end
function p.getItemValue(item)
if type(item) == 'string' then
-- Specific check if the item is GP (value of 1)
if Shared.compareString('GP', item, true)
or Shared.compareString('Gold Pieces', item, true) then
return 1
end
item = p.getItem(item)
end
if item then
return item.sellsFor
end
return nil
end
function p.getValueText(item, minQuantity, maxQuantity)
local minQ, maxQ = 1, 1
if type(minQuantity) == 'number' then
minQ = minQuantity
end
if type(maxQuantity) == 'number' then
maxQ = maxQuantity
else
maxQ = minQ
end
local amt = item.sellsFor or 0
local currID = item.sellsForCurrency or 'melvorD:GP'
return Icons._Currency(currID, amt * minQ, amt * maxQ)
end
-- Function already exists, but without frame.
-- Giving it a slightly different name since function overloading doesn't exist
function p.getItemSellsFor(frame)
local args = frame:getParent().args
return p._getItemSellsFor(args[1], args[2], args.round)
end
function p._getItemSellsFor(itemName, multiplier, rounding)
local itemValue = p.getItemValue(itemName)
multiplier = tonumber(multiplier) or 1
rounding = tonumber(rounding) or 0
if itemValue == nil then
error('No item named "' .. itemName .. '" exists in the data module')
end
return Num.round2(itemValue * multiplier, rounding)
end
end


Line 125: Line 216:
end
end
local result = p._getItemStat(item, StatName, ZeroIfNil)
local result = p._getItemStat(item, StatName, ZeroIfNil)
if formatNum then result = Shared.formatnum(result) end
if formatNum then result = Num.formatnum(result) end
return result
return result
end
end


--Gets the value of a given modifier for a given itemg
--Gets the value of a given modifier for a given item
--asString is false by default, when true it writes the full bonus text
--asString is false by default, when true it writes the full bonus text
function p._getItemModifier(item, modifier, skillID, asString)
function p._getItemModifier(item, modifier, skillID, asString)
Line 167: Line 258:


function p.hasCombatStats(item)
function p.hasCombatStats(item)
-- Checks if the combat stat is a valid, non-zero combat stat
-- Ensure that, only in the case where the item is a Familar AND
-- the checked stat is summoningMaxhit, the result is ignored.
local function isNonZeroStat(statName, statVal)
if statName == 'summoningMaxhit' and (p._canItemUseSlot(item, 'Summon1') or p._canItemUseSlot(item, 'Summon2')) then
return false
end
return statVal ~= 0
end
if item.equipmentStats ~= nil then
if item.equipmentStats ~= nil then
-- Ensure at least one stat has a non-zero value
-- Ensure at least one stat has a non-zero value
for statName, statVal in pairs(item.equipmentStats) do
for statName, statVal in pairs(item.equipmentStats) do
if statVal ~= 0 then
if isNonZeroStat(statName, statVal) then
return true
return true
end
end
end
end
end
end
return false
return false
end
end
Line 301: Line 403:
val1, val2 = levelReqs[1][skillID] or 0, levelReqs[2][skillID] or 0
val1, val2 = levelReqs[1][skillID] or 0, levelReqs[2][skillID] or 0
if val1 ~= val2 then
if val1 ~= val2 then
table.insert(changeArray, Shared.numStrWithSign(val1 - val2) .. ' ' .. Icons.Icon({skillData.data.name, type='skill', notext=true}) .. (statDef.suffix or ''))
table.insert(changeArray, Num.numStrWithSign(val1 - val2) .. ' ' .. Icons.Icon({skillData.data.name, type='skill', notext=true}) .. (statDef.suffix or ''))
end
end
end
end
Line 308: Line 410:
val1, val2 = equipStats[1][statDef.stat] or 0, equipStats[2][statDef.stat] or 0
val1, val2 = equipStats[1][statDef.stat] or 0, equipStats[2][statDef.stat] or 0
if val1 ~= val2 then
if val1 ~= val2 then
table.insert(changeArray, Shared.numStrWithSign(val1 - val2) .. (statDef.suffix or ''))
table.insert(changeArray, Num.numStrWithSign(val1 - val2) .. (statDef.suffix or ''))
end
end
end
end
Line 314: Line 416:


-- Include differences in modifiers
-- Include differences in modifiers
local modDiff = Constants.getModifiersText(Constants.getModifiersDifference(item2.modifiers, item1.modifiers))
-- TODO Implement getModifiersDifference
--local modDiff = Constants.getModifiersText(Constants.getModifiersDifference(item2.modifiers, item1.modifiers))
local modDiff = nil
if modDiff ~= nil and modDiff ~= '' then
if modDiff ~= nil and modDiff ~= '' then
table.insert(changeArray, modDiff)
table.insert(changeArray, modDiff)
Line 342: Line 446:
["Passive"] = 'Combat Passive Slot',
["Passive"] = 'Combat Passive Slot',
["Summon1"] = 'Summoning',
["Summon1"] = 'Summoning',
["Summon2"] = 'Summoning'
["Summon2"] = 'Summoning',
["Gem"] = "Gems_(Equipment)"
}
}
local slotText = {}
local slotText = {}
Line 377: Line 482:
-- For Summoning combat familiars, show the max hit
-- For Summoning combat familiars, show the max hit
if item.equipmentStats ~= nil and item.equipmentStats.summoningMaxhit ~= nil then
if item.equipmentStats ~= nil and item.equipmentStats.summoningMaxhit ~= nil then
table.insert(resultPart, "\r\n|-\r\n|'''Max Hit:''' " .. Shared.formatnum(item.equipmentStats.summoningMaxhit * 10))
table.insert(resultPart, "\r\n|-\r\n|'''Max Hit:''' " .. Num.formatnum(item.equipmentStats.summoningMaxhit * 10))
end
end
--For potions, show the number of charges
--For potions, show the number of charges
Line 390: Line 495:
if item.prayerPoints ~= nil then
if item.prayerPoints ~= nil then
table.insert(resultPart, "\r\n|-\r\n|'''"..Icons.Icon({'Prayer', type='skill'}).." Points:''' "..item.prayerPoints)
table.insert(resultPart, "\r\n|-\r\n|'''"..Icons.Icon({'Prayer', type='skill'}).." Points:''' "..item.prayerPoints)
end
if item.soulPoints ~= nil then
table.insert(resultPart, "\r\n|-\r\n|'''"..Icons.Icon({'Prayer', 'Soul', type='item', img='Lesser Soul'}).." Points:''' "..item.soulPoints)
end
end
--For items that provide runes, show which runes are provided
--For items that provide runes, show which runes are provided
Line 411: Line 519:
table.insert(resultPart, '<span style="color:green">Passive:</span><br/>')
table.insert(resultPart, '<span style="color:green">Passive:</span><br/>')
end
end
table.insert(resultPart, Constants.getModifiersText(item.modifiers, true, false, 10))
table.insert(resultPart, Modifiers.getModifiersText(item.modifiers, true, false, 10))
end
end
return table.concat(resultPart)
return table.concat(resultPart)
Line 484: Line 592:


function p.getItemGrid(frame)
function p.getItemGrid(frame)
local resultPart = {}
--melvorF, melvorD, melvorTotH, melvorAoD
table.insert(resultPart, '{|')
local dlcFunc = function(item, dlc)
for i, item in ipairs(GameData.rawData.items) do
local itemDLC = Shared.getLocalID(item.id)
if i % 17 == 1 then
if dlc == nil then
table.insert(resultPart, '\r\n|-\r\n|')
return true
else
end
table.insert(resultPart, '||')
if dlc == 'base' then
return itemDLC == 'melvorD' or itemDLC == 'melvorF'
end
if itemDLC == dlc then
return true
end
return false
end
-- Convert list of hidden items into a key/value structure, such that
-- lookups are more efficient than repeated calls to Shared.contains()
local hiddenItemIDs = {}
for i, itemID in ipairs(p.HiddenItems) do
hiddenItemIDs[itemID] = 1
end
 
local args = frame:getParent().args
local dlc = args[1] or args.DLC or args.dlc or nil
local columns = tonumber(args[2] or args.Columns or args.columns) or 17
local html = mw.html.create('table')
:addClass('wikitable lighttable individual')
 
local curRow = html:tag('tr')
local i = 0
for _, v in pairs(GameData.rawData.items) do
if hiddenItemIDs[v.id] == nil and dlcFunc(v, dlc) == true then
if i >= columns then
curRow = html:tag('tr')
i = 0
end
local cell = curRow:tag('td')
:css('height', '48px')
:css('width', '48px')
:css('padding', '0px')
cell:tag('div')
:css('padding', '8px')
:wikitext(Icons.Icon({v.name, type='item', notext=true, size='32'}))
-- Mod operator is slow. We use this instead
i = i + 1
end
end
table.insert(resultPart, 'style="padding:3px"|'..Icons.Icon({item.name, type='item', notext=true, size='40'}))
end
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
return tostring(html)
end
end


function p.getEquipRequirementRow(req)
function p.getEquipRequirementRow(req)
local result = ""
local result = ""
if req.type == "SkillLevel" then
if (req.type == "SkillLevel" or req.type == "AbyssalLevel") then
local pre = (req.type == "AbyssalLevel" and ' Abyssal') or ''
local skillName = Constants.getSkillName(req.skillID)
local skillName = Constants.getSkillName(req.skillID)
local skillIcon = Icons.Icon({skillName, type='skill', notext=true})
local skillIcon = Icons.Icon({skillName, type='skill', notext=true})
result = '\r\n!style="text-align:right;"| '..skillIcon..' Level Required'
result = '\r\n!style="text-align:right;"| '..skillIcon..pre..' Level Required'
result = result..'\r\n|style="text-align:right;"| '..req.level
result = result..'\r\n|style="text-align:right;"| '..req.level
elseif req.type == "DungeonCompletion" then
elseif (req.type == "DungeonCompletion" or req.type == "AbyssDepthCompletion") then
local dungeonName = GameData.getEntityByID("dungeons", req.dungeonID).name
local reqDefns = {
local dungeonIcon = Icons.Icon({dungeonName, type="dungeon", notext=true})
["DungeonCompletion"] = {
result = '\r\n!style="text-align:right;"| '..dungeonIcon..' Completions'
["dataKey"] = 'dungeons',
result = result..'\r\n|style="text-align:right;"| '..req.count
["IDKey"] = 'dungeonID',
["imgType"] = 'dungeon'
},
["AbyssDepthCompletion"] = {
["dataKey"] = 'abyssDepths',
["IDKey"] = 'depthID',
["imgType"] = 'combatArea'
}
}
local reqDefn = reqDefns[req.type]
if reqDefn ~= nil then
local area = GameData.getEntityByID(reqDefn.dataKey, req[reqDefn.IDKey])
if area == nil then
result = '\r\n!style="text-align:right;" colspan=2|' .. Shared.printError('Invalid area for requirement type "' .. req.type .. '"')
else
local areaIcon = Icons.Icon({area.name, type=reqDefn.imgType, notext=true})
result = '\r\n!style="text-align:right;"| '..areaIcon..' Completions'
result = result..'\r\n|style="text-align:right;"| '..Num.formatnum(req.count)
end
end
elseif req.type == "Completion" then
elseif req.type == "Completion" then
local ns = GameData.getEntityByName('namespaces', req.namespace)
local ns = GameData.getEntityByName('namespaces', req.namespace)
Line 522: Line 693:
end
end
return result
return result
end
function p._getItemResistance(item)
if item.sellsForCurrency == 'melvorItA:AbyssalPieces' then
return p._getItemStat(item, 'resistance', true), 'Abyssal Resistance'
else
return p._getItemStat(item, 'damageReduction', true), 'Damage Reduction'
end
end
end


Line 530: Line 709:
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end
local resistance, resistanceText = p._getItemResistance(item)


local ico = {
local ico = {
Line 538: Line 719:
["Ranged"] = Icons.Icon({'Ranged', type='skill', notext=true}),
["Ranged"] = Icons.Icon({'Ranged', type='skill', notext=true}),
["Strength"] = Icons.Icon({'Strength', type='skill', notext=true}),
["Strength"] = Icons.Icon({'Strength', type='skill', notext=true}),
["Slayer"] = Icons.Icon({'Slayer', type='skill', notext=true})
["Slayer"] = Icons.Icon({'Slayer', type='skill', notext=true}),
["Resistance"] = Icons.Icon({resistanceText, notext=true})
}
}
local reqCount = item.equipRequirements ~= nil and Shared.tableCount(item.equipRequirements) or 0
local reqCount = item.equipRequirements ~= nil and Shared.tableCount(item.equipRequirements) or 0
local emptyRow = '\r\n!colspan="2"|'
local emptyRow = '\r\n!colspan="2"|'
local damageType = p._getItemStat(item, 'damageType') == 'melvorItA:Abyssal' and 'Abyssal' or 'Normal'
local resultPart = {}
local resultPart = {}
Line 550: Line 733:


table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| Attack Speed')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| Attack Speed')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. Shared.round(p._getItemStat(item, 'attackSpeed', true) / 1000, 3, 1) .. 's')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. Num.round(p._getItemStat(item, 'attackSpeed', true) / 1000, 3, 1) .. 's')
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Defence'] .. ' Defence Bonus')
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Defence'] .. ' Defence Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'meleeDefenceBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'meleeDefenceBonus', true))
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| Damage Type')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. ico['Resistance'] .. damageType)
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Resistance'] .. resistanceText)
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. resistance .. '%')


table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| Attack Type')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| Attack Type')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'attackType'))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'attackType'))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Defence'] .. ' Damage Reduction')
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Ranged'] .. ' Defence Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'damageReduction', true) .. '%')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'rangedDefenceBonus', true))


table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Strength'] .. ' Strength Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Strength'] .. ' Strength Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'meleeStrengthBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'meleeStrengthBonus', true))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Ranged'] .. ' Defence Bonus')
table.insert(resultPart, '\r\n!style="text-align:right;border-bottom:solid thin black;"| ' .. ico['Magic'] .. ' Defence Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'rangedDefenceBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;border-bottom:solid thin black;"| ' .. p._getItemStat(item, 'magicDefenceBonus', true))


table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Stab Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Stab Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'stabAttackBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'stabAttackBonus', true))
table.insert(resultPart, '\r\n!style="text-align:right;border-bottom:solid thin black;"| ' .. ico['Magic'] .. ' Defence Bonus')
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Equip Requirements')
table.insert(resultPart, '\r\n|style="text-align:right;border-bottom:solid thin black;"| ' .. p._getItemStat(item, 'magicDefenceBonus', true))


table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Slash Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Slash Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'slashAttackBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'slashAttackBonus', true))
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Equip Requirements')
if reqCount > 0 then
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[1]))
else
table.insert(resultPart, '\r\n|colspan=2 style="text-align:right"|None')
end


table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Block Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Block Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'blockAttackBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'blockAttackBonus', true))
if reqCount > 0 then
if reqCount > 1 then
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[1]))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[2]))
else
else
table.insert(resultPart, '\r\n|colspan=2 style="text-align:right"|None')
table.insert(resultPart, emptyRow)
end
end


table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Ranged'] .. ' Attack Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Ranged'] .. ' Attack Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'rangedAttackBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'rangedAttackBonus', true))
if reqCount > 1 then
if reqCount > 2 then
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[2]))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[3]))
else
else
table.insert(resultPart, emptyRow)
table.insert(resultPart, emptyRow)
Line 591: Line 782:
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Ranged'] .. ' Strength Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Ranged'] .. ' Strength Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'rangedStrengthBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'rangedStrengthBonus', true))
if reqCount > 2 then
if reqCount > 3 then
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[3]))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[4]))
else
else
table.insert(resultPart, emptyRow)
table.insert(resultPart, emptyRow)
Line 599: Line 790:
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Magic'] .. ' Attack Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Magic'] .. ' Attack Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'magicAttackBonus', true))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'magicAttackBonus', true))
if reqCount > 3 then
if reqCount > 4 then
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[4]))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[5]))
else
else
table.insert(resultPart, emptyRow)
table.insert(resultPart, emptyRow)
Line 607: Line 798:
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Magic'] .. ' % Damage Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Magic'] .. ' % Damage Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'magicDamageBonus', true) .. '%')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'magicDamageBonus', true) .. '%')
if reqCount > 4 then
if reqCount > 5 then
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[5]))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[6]))
else
else
table.insert(resultPart, emptyRow)
table.insert(resultPart, emptyRow)
Line 615: Line 806:
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| Two Handed?')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| Two Handed?')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. (p._getItemStat(item, 'isTwoHanded') and 'Yes' or 'No'))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. (p._getItemStat(item, 'isTwoHanded') and 'Yes' or 'No'))
if reqCount > 5 then
if reqCount > 6 then
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[6]))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[6]))
else
else
table.insert(resultPart, emptyRow)
table.insert(resultPart, emptyRow)
end
end
 
--Add extra rows at the end for items that have more than 3 different requirements
--Add extra rows at the end for items that have more than 3 different requirements
if reqCount > 6 then
if reqCount > 7 then
for i = 7, reqCount, 1 do
for i = 8, reqCount, 1 do
table.insert(resultPart,"\r\n|-")
table.insert(resultPart,"\r\n|-")
table.insert(resultPart, emptyRow)
table.insert(resultPart, emptyRow)
Line 640: Line 831:
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end
local resistance, resistanceText = p._getItemResistance(item)


local ico = {
local ico = {
Line 648: Line 841:
["Ranged"] = Icons.Icon({'Ranged', type='skill', notext=true}),
["Ranged"] = Icons.Icon({'Ranged', type='skill', notext=true}),
["Strength"] = Icons.Icon({'Strength', type='skill', notext=true}),
["Strength"] = Icons.Icon({'Strength', type='skill', notext=true}),
["Slayer"] = Icons.Icon({'Slayer', type='skill', notext=true})
["Slayer"] = Icons.Icon({'Slayer', type='skill', notext=true}),
["Resistance"] = Icons.Icon({resistanceText,  notext=true}),
}
}
Line 666: Line 860:
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Stab Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Stab Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'stabAttackBonus', 0))
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'stabAttackBonus', 0))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Defence'] .. ' Damage Reduction')
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Resistance'] .. resistanceText)
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'damageReduction', true) .. '%')
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. resistance .. '%')


table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Slash Bonus')
table.insert(resultPart, '\r\n|-\r\n!style="text-align:right;"| ' .. ico['Combat'] .. ' Slash Bonus')
Line 850: Line 1,044:
table.insert(resultPart, '\r\n|}')
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
return table.concat(resultPart)
end
function p.getLifestealWeapons()
local items = p.getItems(function(item)
if item.specialAttacks ~= nil and not Shared.tableIsEmpty(item.specialAttacks) then
for i, spAttID in ipairs(item.specialAttacks) do
local spAtt = GameData.getEntityByID('attacks', spAttID)
if spAtt ~= nil then
return spAtt.lifesteal > 0
end
end
end
return false
end)
for i, item in ipairs(items) do
mw.log(item.name)
end
end
end


return p
return p