Anonymous

Module:Items: Difference between revisions

From Melvor Idle
Add gem link to gem equipment slot
(Fixed indenting)
(Add gem link to gem equipment slot)
(59 intermediate revisions by 3 users not shown)
Line 6: Line 6:
local p = {}
local p = {}


local ItemData = mw.loadData('Module:Items/data')
local GameData = require('Module:GameData')
 
local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')


p.EasterEggs = {'Amulet of Calculated Promotion', 'Clue Chasers Insignia', '8', 'Lemon', 'Easter Egg', 'Abnormal Log', 'Red Herring', 'Cool Glasses'}
p.EasterEggs = {'Amulet of Calculated Promotion', 'Clue Chasers Insignia', '8', 'Lemon', 'Easter Egg',
'Abnormal Log', 'Red Herring', 'Cool Glasses'}
p.EventItems = {'Christmas Cracker', 'Christmas Coal', 'Christmas Sweater',
p.EventItems = {'Christmas Cracker', 'Christmas Coal', 'Christmas Sweater',
'Christmas Wreath', 'Candy Cane', 'Santa Hat',
'Christmas Wreath', 'Candy Cane', 'Santa Hat',
Line 18: Line 18:
'Event Clue 3', 'Event Clue 4', 'Candle', 'Cake Base',
'Event Clue 3', 'Event Clue 4', 'Candle', 'Cake Base',
'Magical Flavouring', 'Magical Icing', 'Birthday Cake',
'Magical Flavouring', 'Magical Icing', 'Birthday Cake',
'Purple Party Hat', 'Birthday Token'}
'Purple Party Hat', 'Birthday Token', 'Christmas Present (Yellow)',
p.OtherShopItems = {'Cooking Gloves', 'Mining Gloves', 'Gem Gloves', 'Smithing Gloves', 'Thieving Gloves'}
'Christmas Present (Blue)', 'Christmas Present (Green)', 'Christmas Present (White)',
--This is hardcoded, so there's no easy way to scrape it. Hopefully it doesn't change
'Christmas Present (Purple)', 'Christmas Present (Standard)', 'Event Token - Holiday 2021',
p.GemTable = {["Topaz"] = {name = 'Topaz', id = 128, chance = 50},
'Holiday Scarf', 'Gingerbread House', 'Gingerbread Man', 'Edible Candy Cane',
            ["Sapphire"] = {name = "Sapphire", id = 129, chance = 17.5},
'Locked Chest', 'Locked Chest Key', 'Event Token (Holiday 2021)'}
            ["Ruby"] = {name = "Ruby", id = 130, chance = 17.5},
            ["Emerald"] = {name = "Emerald", id = 131, chance = 10},
            ["Diamond"] = {name = "Diamond", id = 132, chance = 5}}
--The base chance to receive a gem while mining
p.GemChance = .01
--The number of different fishing junk items
p.junkCount = 8
--Items (aside from bars & gems) which can be created via Alt Magic
p.AltMagicProducts = {'Rune Essence', 'Bones', 'Holy Dust'}
--The kinds of gloves with cost & charges
p.GloveTable = {['Cooking Gloves'] = {cost=50000, charges=500},
              ['Mining Gloves'] = {cost=75000, charges=500},
              ['Smithing Gloves'] = {cost=100000, charges=500},
              ['Thieving Gloves'] = {cost=100000, charges=500},
              ['Gem Gloves'] = {cost=500000, charges=2000}}
 
 
p.specialFishWt = 6722
p.specialFishLoot = {{128, 2000}, {129, 1600}, {130, 1400}, {131, 1000}, {132, 400}, {667, 10}, {668, 10}, {902, 1}, {670, 1}, {669, 50}, {120, 250}}
 
function p.buildSpecialFishingTable()
--This shouldn't ever be included in a page
--This is for generating the above 'specialFishLoot' variable if it ever needs to change
--To re-run, edit the module, type in "console.log(p.buildSpecialFishingTable())" and copy+paste the result as the new value of the variable
--Also gives you the total fishing weight for saving time later
local lootArray = {}
local totalWt = 0
 
for i, item in pairs(ItemData.Items) do
if item.fishingCatchWeight ~= nil then
totalWt = totalWt + item.fishingCatchWeight
table.insert(lootArray, '{'..(i - 1)..', '..item.fishingCatchWeight..'}')
end
end
 
local result = 'p.specialFishWt = '..totalWt..'\r\n'
result = result..'p.specialFishLoot = {'..table.concat(lootArray, ', ')..'}'
return result
end


function p.getItemByID(ID)
function p.getItemByID(ID)
local result = Shared.clone(ItemData.Items[ID + 1])
return GameData.getEntityByID('items', ID)
if result ~= nil then
result.id = ID
end
return result
end
end


function p.getItem(name)
function p.getItem(name)
local result = nil
name = string.gsub(name, "%%27", "'")
name = string.gsub(name, "%%27", "'")
name = string.gsub(name, "'", "'")
name = string.gsub(name, "'", "'")
for i, item in pairs(ItemData.Items) do
return GameData.getEntityByName('items', name)
local itemName = string.gsub(item.name, '#', '')
end
if(name == itemName) then
 
result = Shared.clone(item)
function p.getItems(checkFunc)
--Make sure every item has an id, and account for Lua being 1-index
return GameData.getEntities('items', checkFunc)
result.id = i - 1
end
break
 
end
function p._canItemUseSlot(item, equipSlot)
--Function to easily check if an item can fit in a given equipment slot
--Ex: p._canItemUseSlot({Bronze Platebody}, 'Platebody') returns true
if type(item) == 'string' then
item = p.getItem(item)
end
end
return result
return item.validSlots ~= nil and Shared.contains(item.validSlots, equipSlot)
end
end


function p.getItems(checkFunc)
function p._getItemEquipSlot(item)
local result = {}
--Function to return the (non-Passive) equipment slot that an item occupies
for i, item in pairs(ItemData.Items) do
if type(item) == 'string' then
if checkFunc(item) then
item = p.getItem(item)
local newItem = Shared.clone(item)
end
newItem.id = i - 1
if item == nil or item.validSlots == nil then
table.insert(result, newItem)
return 'Invalid'
end
for i, slot in pairs(item.validSlots) do
if slot ~= 'Passive' then
return slot
end
end
end
end
return result
end
end


Line 103: Line 66:
--Special Overrides:
--Special Overrides:
-- Equipment stats first
-- Equipment stats first
if Shared.contains(ItemData.EquipmentStatKeys, StatName) and item.equipmentStats ~= nil then
if item.equipmentStats ~= nil and item.equipmentStats[StatName] ~= nil then
result = item.equipmentStats[StatName]
result = item.equipmentStats[StatName]
elseif StatName == 'attackSpeed' and item.validSlots ~= nil and Shared.contains(item.validSlots, 'Weapon') then
-- Item can be equipped as a weapon but has no attack speed, so use default of 4000ms
result = 4000
elseif StatName == 'isTwoHanded' then
elseif StatName == 'isTwoHanded' then
if item.validSlots ~= nil and item.occupiesSlots ~= nil then
if item.validSlots ~= nil and item.occupiesSlots ~= nil then
Line 111: Line 77:
result = false
result = false
end
end
elseif string.find(StatName, '^(.+)LevelRequired$') ~= nil and item.equipRequirements ~= nil and item.equipRequirements.Level ~= nil then
elseif string.find(StatName, '^(.+)LevelRequired$') ~= nil and item.equipRequirements ~= nil then
local skillName = Shared.titleCase(string.match(StatName, '^(.+)LevelRequired$'))
local skillName = Shared.titleCase(string.match(StatName, '^(.+)LevelRequired$'))
if skillName ~= nil then
if skillName ~= nil then
local skillID = Constants.getSkillID(skillName)
local skillID = Constants.getSkillID(skillName)
if skillID ~= nil then
if skillID ~= nil then
  result = item.equipRequirements.Level[skillID]
for i, requirement in ipairs(item.equipRequirements) do
if requirement.type == "SkillLevel" and requirement.skillID == skillID then
result = requirement.level
break
end
end
end
end
end
end
Line 122: Line 93:
result = p._getWeaponAttackType(item)
result = p._getWeaponAttackType(item)
elseif StatName == 'description' then
elseif StatName == 'description' then
result = item.description
result = item.customDescription
if result == nil or result == '' then result = 'No Description' end
if result == nil or result == '' then result = 'No Description' end
elseif StatName == 'completionReq' then
elseif StatName == 'completionReq' then
Line 132: Line 103:
elseif StatName == 'slayerBonusXP' then
elseif StatName == 'slayerBonusXP' then
return p._getItemModifier(item, 'increasedSkillXP', 'Slayer', false)
return p._getItemModifier(item, 'increasedSkillXP', 'Slayer', false)
elseif StatName == 'hasCombatStats' then
return tostring(p.hasCombatStats(item) or p._hasLevelRequirements(item))
elseif StatName == 'category' then
-- Some categories have a namespace for some reason, remove it
local _, localID = GameData.getLocalID(result)
return localID
end
end
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.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
end


Line 145: Line 140:
local item = p.getItem(ItemName)
local item = p.getItem(ItemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..ItemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. ItemName .. '" exists in the data module')
end
end
local result = p._getItemStat(item, StatName, ZeroIfNil)
local result = p._getItemStat(item, StatName, ZeroIfNil)
Line 152: Line 147:
end
end


--Gets the value of a given modifier for a given item
--Gets the value of a given modifier for a given itemg
--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, skill, asString)
function p._getItemModifier(item, modifier, skillID, asString)
if asString == nil then asString = false end
if asString == nil then asString = false end
if skill == '' then
if skillID == '' then
skill = nil
skillID = nil
elseif type(skill) == 'string' then
elseif string.find(skillID, ':') == nil then
skill = Constants.getSkillID(skill)
-- Try to find a skill ID if it looks like a skill name has been passed
skillID = Constants.getSkillID(skillID)
end
end


Line 167: Line 163:
if type(item.modifiers[modifier]) == 'table' then
if type(item.modifiers[modifier]) == 'table' then
for i, subVal in Shared.skpairs(item.modifiers[modifier]) do
for i, subVal in Shared.skpairs(item.modifiers[modifier]) do
if subVal[1] == skill then
if subVal[1] == skillID then
  result = subVal[2]
result = subVal[2]
  break
break
end
end
end
end
Line 178: Line 174:


if asString then
if asString then
if skill ~= nil then
if skillID ~= nil then
return Constants._getModifierText(modifier, {skill, result})
return Constants._getModifierText(modifier, {skillID, result})
else
else
return Constants._getModifierText(modifier, result)
return Constants._getModifierText(modifier, result)
Line 189: Line 185:


function p.hasCombatStats(item)
function p.hasCombatStats(item)
if item.isEquipment or (item.validSlots == nil and item.equipmentStats ~= nil) then
-- 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.
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
-- 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 return true end
if isNonZeroStat(statName, statVal) then
return true
end
end
end
 
return false
end
 
function p._hasLevelRequirements(item)
--Function true if an item has at least one level requirement to equip
if item.equipRequirements ~= nil then
for idx, requirement in ipairs(item.equipRequirements) do
if requirement.type == 'SkillLevel' and requirement.level > 1 then
return true
end
end
end
end
end
Line 204: Line 225:
local asString = frame.args ~= nil and frame.args[4] or frame[4]
local asString = frame.args ~= nil and frame.args[4] or frame[4]
if asString ~= nil then
if asString ~= nil then
if string.upper(asString) == 'FALSE' then
asString = (string.upper(asString) ~= 'FALSE')
asString = false
else
asString = true
end
end
end


local item = p.getItem(itemName)
local item = p.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


Line 220: Line 237:


function p._getWeaponAttackType(item)
function p._getWeaponAttackType(item)
if item.isEquipment == true and (item.validSlots ~= nil and Shared.contains(item.validSlots, 'Weapon')) or
if (item.validSlots ~= nil and Shared.contains(item.validSlots, 'Weapon')) or
(item.occupiesSlots ~= nil and Shared.contains(item.occupiesSlots, 'Weapon')) then
(item.occupiesSlots ~= nil and Shared.contains(item.occupiesSlots, 'Weapon')) then
if Shared.contains({'melee', 'ranged', 'magic'}, item.attackType) then
if Shared.contains({'melee', 'ranged', 'magic'}, item.attackType) then
local iconType = item.attackType ~= 'melee' and 'skill' or nil
local iconType = item.attackType ~= 'melee' and 'skill' or nil
Line 234: Line 251:
local item = p.getItem(itemName)
local item = p.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..ItemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end
return p._getWeaponAttackType(item)
return p._getWeaponAttackType(item)
end
end


function p.getPotionTable(frame)
local statChangeDefs = {
local potionName = frame.args ~= nil and frame.args[1] or frame
{
local tiers = {'I', 'II', 'III', 'IV'}
stat = 'stabAttackBonus',
suffix = ' ' .. Icons.Icon({'Melee', notext=true}) .. ' Stab Bonus'
},
{
stat = 'slashAttackBonus',
suffix =  ' ' .. Icons.Icon({'Melee', notext=true}) .. ' Slash Bonus'
},
{
stat = 'blockAttackBonus',
suffix = ' ' .. Icons.Icon({'Melee', notext=true}) .. ' Block Bonus'
},
{
stat = 'meleeStrengthBonus',
suffix = ' ' .. Icons.Icon({'Strength', type='skill', notext=true}) .. ' Strength Bonus'
},
{
stat = 'rangedStrengthBonus',
suffix =  ' ' .. Icons.Icon({'Ranged', type='skill', notext=true}) .. ' Strength Bonus'
},
{
stat = 'magicStrengthBonus',
suffix = '% ' .. Icons.Icon({'Magic', type='skill', notext=true}) .. ' Damage Bonus'
},
{
stat = 'meleeDefenceBonus',
suffix = ' ' .. Icons.Icon({'Defence', type='skill', notext=true}) .. ' Defence Bonus' },
{
stat = 'rangedDefenceBonus',
suffix = ' ' .. Icons.Icon({'Ranged', type='skill', notext=true}) .. ' Defence Bonus'
},
{
stat = 'magicDefenceBonus',
suffix = ' ' .. Icons.Icon({'Magic', type='skill', notext=true}) .. ' Defence Bonus'
},
{
stat = 'damageReduction',
suffix = '% Damage Reduction'
},
{
stat = 'levelRequired',
suffix = ' Level Required'
}
}


local resultPart = {}
-- Produces a list of stat & modifier changes between two items of equipmednt
table.insert(resultPart, '{| class="wikitable"')
function p.getStatChangeString(item1, item2)
table.insert(resultPart, '\r\n!Potion!!Tier!!Charges!!Effect')
local changeArray = {}


local tier1potion = p.getItem(potionName..' I')
local equipStats = {
if tier1potion == nil then
type(item1.equipmentStats) == 'table' and item1.equipmentStats or {},
return 'ERROR: No potion named "' .. potionName .. '" was found[[Category:Pages with script errors]]'
type(item2.equipmentStats) == 'table' and item2.equipmentStats or {}
}
for i, statDef in ipairs(statChangeDefs) do
local val1, val2 = 0, 0
if statDef.stat == 'levelRequired' then
-- Iterate over equipment stats for both items, determining level requirements
local levelReqs = {}
for itemNum, item in ipairs({item1, item2}) do
levelReqs[itemNum] = {}
if item.equipRequirements ~= nil then
for j, req in ipairs(item.equipRequirements) do
if req.type == 'SkillLevel' then
levelReqs[itemNum][req.skillID] = req.level
end
end
end
end
-- Iterate over all skills, checking if there are requirements for these in either skill
for j, skillData in ipairs(GameData.rawData.skillData) do
local skillID = skillData.skillID
val1, val2 = levelReqs[1][skillID] or 0, levelReqs[2][skillID] or 0
if val1 ~= val2 then
table.insert(changeArray, Shared.numStrWithSign(val1 - val2) .. ' ' .. Icons.Icon({skillData.data.name, type='skill', notext=true}) .. (statDef.suffix or ''))
end
end
else
-- Equipment stats
val1, val2 = equipStats[1][statDef.stat] or 0, equipStats[2][statDef.stat] or 0
if val1 ~= val2 then
table.insert(changeArray, Shared.numStrWithSign(val1 - val2) .. (statDef.suffix or ''))
end
end
end
end
for i, tier in pairs(tiers) do
 
local tierName = potionName..' '..tier
-- Include differences in modifiers
local potion = p.getItemByID(tier1potion.id + i - 1)
local modDiff = Constants.getModifiersText(Constants.getModifiersDifference(item2.modifiers, item1.modifiers))
if potion ~= nil then
if modDiff ~= nil and modDiff ~= '' then
table.insert(resultPart, '\r\n|-')
table.insert(changeArray, modDiff)
table.insert(resultPart, '\r\n|'..Icons.Icon({tierName, type='item', notext=true, size='60'}))
table.insert(resultPart, '||'..Icons.Icon({tierName, tier, type='item', noicon=true}))
table.insert(resultPart, '||'..potion.potionCharges..'||'..potion.description)
end
end
end


table.insert(resultPart, '\r\n|}')
return table.concat(changeArray, '<br/>')
return table.concat(resultPart)
end
end


function p._getOtherItemBoxText(item)
function p._getOtherItemBoxText(item)
resultPart = {}
local resultPart = {}
--For equipment, show the slot they go in
--For equipment, show the slot they go in
local isPassive = false
if item.validSlots ~= nil then
if item.validSlots ~= nil then
table.insert(resultPart, "\r\n|-\r\n|'''Equipment Slot:''' "..table.concat(item.validSlots, ', '))
local slotLinkMap = {
["Helmet"] = 'Helmets',
["Platebody"] = 'Platebodies',
["Platelegs"] = 'Platelegs',
["Boots"] = 'Boots',
["Weapon"] = 'Weapons',
["Shield"] = 'Shields',
["Amulet"] = 'Amulets',
["Ring"] = 'Rings',
["Gloves"] = 'Gloves',
["Quiver"] = 'Ammunition',
["Cape"] = 'Capes',
["Consumable"] = 'Consumables',
["Passive"] = 'Combat Passive Slot',
["Summon1"] = 'Summoning',
["Summon2"] = 'Summoning',
["Gem"] = "Gems_(Equipment)"
}
local slotText = {}
for i, slot in ipairs(item.validSlots) do
local slotLink = slotLinkMap[slot]
if slotLink == nil then
table.insert(slotText, slot)
else
table.insert(slotText, '[[' .. slotLink .. '|' .. slot .. ']]')
end
if slot == 'Passive' then
isPassive = true
end
end
table.insert(resultPart, "\r\n|-\r\n|'''Equipment Slot:''' "..table.concat(slotText, ', '))
end
end
--For weapons with a special attack, show the details
--For weapons with a special attack, show the details
if item.hasSpecialAttack then
if item.specialAttacks ~= nil and not Shared.tableIsEmpty(item.specialAttacks) then
table.insert(resultPart, "\r\n|-\r\n|'''Special Attack:'''")
table.insert(resultPart, "\r\n|-\r\n|'''Special Attack:'''")
for i, spAtt in ipairs(item.specialAttacks) do
for i, spAttID in ipairs(item.specialAttacks) do
table.insert(resultPart, '\r\n* ' .. spAtt.defaultChance .. '% chance for ' .. spAtt.name .. ':')
local spAtt = GameData.getEntityByID('attacks', spAttID)
table.insert(resultPart, '\r\n** ' .. spAtt.description)
if spAtt ~= nil then
local spAttChance = spAtt.defaultChance
if type(item.overrideSpecialChances) == 'table' and item.overrideSpecialChances[i] ~= nil then
spAttChance = item.overrideSpecialChances[i]
end
local spAttDesc = string.gsub(spAtt.description, '<Attack> ', '')
table.insert(resultPart, '\r\n* ' .. spAttChance .. '% chance for ' .. spAtt.name .. ':')
table.insert(resultPart, '\r\n** ' .. spAttDesc)
end
end
end
end
-- For Summoning combat familiars, show the max hit
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))
end
end
--For potions, show the number of charges
--For potions, show the number of charges
if item.potionCharges ~= nil then
if item.charges ~= nil then
table.insert(resultPart, "\r\n|-\r\n|'''Charges:''' "..item.potionCharges)
table.insert(resultPart, "\r\n|-\r\n|'''Charges:''' "..item.charges)
end
end
--For food, show how much it heals for
--For food, show how much it heals for
Line 291: Line 420:
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
--For items that provide runes, show which runes are provided
if item.providedRunes ~= nil then
table.insert(resultPart, "\r\n|-\r\n|'''Runes Provided:''' ")
local runeLines = {}
local sortVal = ''
for j, runePair in pairs(item.providedRunes) do
local runeID = runePair.id
local qty = runePair.quantity
local rune = p.getItemByID(runeID)
sortVal = sortVal..rune.name..qty
table.insert(runeLines, Icons.Icon({rune.name, type='item', qty=qty}))
end
table.insert(resultPart, table.concat(runeLines, ', '))
end
end
--For items with modifiers, show what those are
--For items with modifiers, show what those are
if item.modifiers ~= nil and Shared.tableCount(item.modifiers) > 0 then
if item.modifiers ~= nil and not Shared.tableIsEmpty(item.modifiers) then
table.insert(resultPart, "\r\n|-\r\n|'''Modifiers:'''\r\n"..Constants.getModifiersText(item.modifiers, true))
table.insert(resultPart, "\r\n|-\r\n|'''Modifiers:'''\r\n")
if isPassive then
table.insert(resultPart, '<span style="color:green">Passive:</span><br/>')
end
table.insert(resultPart, Constants.getModifiersText(item.modifiers, true, false, 10))
end
end
return table.concat(resultPart)
return table.concat(resultPart)
Line 302: Line 449:
local itemName = frame.args ~= nil and frame.args[1] or frame
local itemName = frame.args ~= nil and frame.args[1] or frame
local item = p.getItem(itemName)
local item = p.getItem(itemName)
local asList = false
if frame.args ~= nil then
asList = frame.args.asList ~= nil and frame.args.asList ~= '' and frame.args.asList ~= 'false'
end
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


return p._getOtherItemBoxText(item, asList)
return p._getOtherItemBoxText(item)
end
end


function p._getItemCategories(item)
function p._getItemCategories(item)
local resultPart = {}
local resultPart = {}
if item.category ~= nil then table.insert(resultPart, '[[Category:'..item.category..']]') end
local isEquipment = item.validSlots ~= nil or item.occupiesSlots ~= nil or item.equipmentStats ~= nil
if item.type ~= nil then table.insert(resultPart, '[[Category:'..item.type..']]') end
local category = p._getItemStat(item, 'category', false)
if item.tier ~= nil then table.insert(resultPart, '[[Category:'..Shared.titleCase(item.tier)..' '..item.type..']]') end
if category ~= nil and category ~= 'Skills' then
if item.hasSpecialAttack then table.insert(resultPart, '[[Category:Items With Special Attacks]]') end
table.insert(resultPart, '[[Category:'..category..']]')
end
if item.type ~= nil then
table.insert(resultPart, '[[Category:'..item.type..']]')
end
if isEquipment and item.tier ~= nil then
table.insert(resultPart, '[[Category:'..Shared.titleCase(item.tier)..' '..item.type..']]')
end
if item.specialAttacks ~= nil and not Shared.tableIsEmpty(item.specialAttacks) then
table.insert(resultPart, '[[Category:Items With Special Attacks]]')
end
if item.validSlots ~= nil then
if item.validSlots ~= nil then
local slotRemap = {
local slotRemap = {
Line 342: Line 495:
for modName, val in pairs(item.modifiers) do
for modName, val in pairs(item.modifiers) do
if Shared.contains(modsDL, modName) then
if Shared.contains(modsDL, modName) then
  table.insert(resultPart, '[[Category:Double Loot Chance Items]]')
table.insert(resultPart, '[[Category:Double Loot Chance Items]]')
  break
break
end
end
end
end
Line 354: Line 507:
local item = p.getItem(itemName)
local item = p.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


return p._getItemCategories(item)
return p._getItemCategories(item)
end
function p.getSkillcapeTable(frame)
local skillName = frame.args ~= nil and frame.args[1] or frame
local cape = p.getItem(skillName..' Skillcape')
local resultPart = {}
table.insert(resultPart, '{| class="wikitable"\r\n')
table.insert(resultPart, '!Skillcape!!Name!!Effect')
table.insert(resultPart, '\r\n|-\r\n|'..Icons.Icon({cape.name, type='item', size='60', notext=true}))
table.insert(resultPart, '||'..Icons.Icon({cape.name, type='item', noicon=true})..'||'..cape.description)
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
end


Line 375: Line 516:
local resultPart = {}
local resultPart = {}
table.insert(resultPart, '{|')
table.insert(resultPart, '{|')
for i, item in Shared.skpairs(ItemData.Items) do
for i, item in ipairs(GameData.rawData.items) do
if i % 17 == 1 then
if i % 17 == 1 then
table.insert(resultPart, '\r\n|-\r\n|')
table.insert(resultPart, '\r\n|-\r\n|')
Line 387: Line 528:
end
end


function p.getSpecialAttackTable(frame)
function p.getEquipRequirementRow(req)
local spAttTable = {}
local result = ""
 
if req.type == "SkillLevel" then
for i, item in Shared.skpairs(ItemData.Items) do
local skillName = Constants.getSkillName(req.skillID)
if item.hasSpecialAttack then
local skillIcon = Icons.Icon({skillName, type='skill', notext=true})
for i, spAtt in ipairs(item.specialAttacks) do
result = '\r\n!style="text-align:right;"| '..skillIcon..' Level Required'
  if spAttTable[spAtt.id] == nil then spAttTable[spAtt.id] = {sortName=item.name, defn = spAtt, Icons = {}} end
result = result..'\r\n|style="text-align:right;"| '..req.level
  table.insert(spAttTable[spAtt.id].Icons, Icons.Icon({item.name, type='item'}))
elseif req.type == "DungeonCompletion" then
end
local dungeonName = GameData.getEntityByID("dungeons", req.dungeonID).name
local dungeonIcon = Icons.Icon({dungeonName, type="dungeon", notext=true})
result = '\r\n!style="text-align:right;"| '..dungeonIcon..' Completions'
result = result..'\r\n|style="text-align:right;"| '..req.count
elseif req.type == "Completion" then
local ns = GameData.getEntityByName('namespaces', req.namespace)
if ns == nil then
return '\r\n!style="text-align:right;" colspan=2|' .. Shared.printError('Invalid namespace for completion requirement "' .. req.namespace .. '"')
else
result = '\r\n!style="text-align:right;"| ' .. ns.displayName .. ' Completion'
result = result .. '\r\n|style="text-align:right;"| ' .. req.percent .. '%'
end
end
else
return '\r\n!style="text-align:right;" colspan=2|' .. Shared.printError('Invalid equip requirement type "' .. req.type .. '"')
end
end
 
return result
local resultPart = {}
table.insert(resultPart, '{|class="wikitable sortable stickyHeader"')
table.insert(resultPart, '\r\n|-class="headerRow-0"')
table.insert(resultPart, '\r\n!style="min-width:180px"|Weapon(s)!!Name!!Chance!!Effect')
for i, spAttData in Shared.skpairs(spAttTable) do
local spAtt = spAttData.defn
table.sort(spAttData.Icons, function(a, b) return a < b end)
table.insert(resultPart, '\r\n|-')
table.insert(resultPart, '\r\n|data-sort-value="'..spAttData.sortName..'"|'..table.concat(spAttData.Icons, '<br/>'))
table.insert(resultPart, '||'..spAtt.name..'||data-sort-value="'..spAtt.defaultChance..'"|'..spAtt.defaultChance..'%')
table.insert(resultPart, '||'..spAtt.description)
end
table.insert(resultPart, '\r\n|}')
 
return table.concat(resultPart)
end
end


Line 420: Line 558:
local item = p.getItem(itemName)
local item = p.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end
 
local ico = {
local ico = {
["Attack"] = Icons.Icon({'Attack', type='skill', notext=true}),
["Attack"] = Icons.Icon({'Attack', type='skill', notext=true}),
Line 432: Line 570:
["Slayer"] = Icons.Icon({'Slayer', type='skill', notext=true})
["Slayer"] = Icons.Icon({'Slayer', type='skill', notext=true})
}
}
local reqCount = item.equipRequirements ~= nil and Shared.tableCount(item.equipRequirements) or 0
local emptyRow = '\r\n!colspan="2"|'
local resultPart = {}
local resultPart = {}
table.insert(resultPart, '{| class="wikitable"\r\n|-\r\n!colspan="4" style="border-bottom:solid medium black;"| Weapon Stats')
table.insert(resultPart, '{| class="wikitable"\r\n|-\r\n!colspan="4" style="border-bottom:solid medium black;"| Weapon Stats')
table.insert(resultPart, '\r\n|-\r\n!colspan="2" style="border-bottom:solid thin black;"| Offensive Stats')
table.insert(resultPart, '\r\n|-\r\n!colspan="2" style="border-bottom:solid thin black;"| Offensive Stats')
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Defensive Stats')
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Defensive Stats')
 
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;"| ' .. Shared.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;"| 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['Defence'] .. ' Damage Reduction')
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, 'damageReduction', 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;"| ' .. ico['Ranged'] .. ' 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;"| ' .. p._getItemStat(item, 'rangedDefenceBonus', 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!style="text-align:right;border-bottom:solid thin black;"| ' .. ico['Magic'] .. ' Defence Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;border-bottom:solid thin black;"| ' .. p._getItemStat(item, 'magicDefenceBonus', 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'] .. ' 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;"| Other')
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Equip Requirements')
 
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))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Slayer'] .. ' Bonus Slayer XP')
if reqCount > 0 then
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'slayerBonusXP', true) .. '%')
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['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))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Attack'] .. ' Level Required')
if reqCount > 1 then
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'attackLevelRequired', true))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[2]))
else
table.insert(resultPart, emptyRow)
end
 
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))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Ranged'] .. ' Level Required')
if reqCount > 2 then
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'rangedLevelRequired', true))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[3]))
else
table.insert(resultPart, emptyRow)
end
 
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))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Magic'] .. ' Level Required')
if reqCount > 3 then
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'magicLevelRequired', true))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[4]))
else
table.insert(resultPart, emptyRow)
end
 
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) .. '%')
table.insert(resultPart, '\r\n!style="text-align:right;"| Two Handed?')
if reqCount > 4 then
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[5]))
else
table.insert(resultPart, emptyRow)
end
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
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[6]))
else
table.insert(resultPart, emptyRow)
end
--Add extra rows at the end for items that have more than 3 different requirements
if reqCount > 6 then
for i = 7, reqCount, 1 do
table.insert(resultPart,"\r\n|-")
table.insert(resultPart, emptyRow)
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[i]))
end
end
table.insert(resultPart, '\r\n|}')
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
return table.concat(resultPart)
Line 494: Line 668:
local item = p.getItem(itemName)
local item = p.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end
 
local ico = {
local ico = {
["Attack"] = Icons.Icon({'Attack', type='skill', notext=true}),
["Attack"] = Icons.Icon({'Attack', type='skill', notext=true}),
Line 506: Line 680:
["Slayer"] = Icons.Icon({'Slayer', type='skill', notext=true})
["Slayer"] = Icons.Icon({'Slayer', type='skill', notext=true})
}
}
local reqCount = item.equipRequirements ~= nil and Shared.tableCount(item.equipRequirements) or 0
local emptyRow = '\r\n!colspan="2"|'
local resultPart = {}
local resultPart = {}
table.insert(resultPart, '{| class="wikitable"\r\n|-\r\n!colspan="4" style="border-bottom:solid medium black;"| Armour Stats')
table.insert(resultPart, '{| class="wikitable"\r\n|-\r\n!colspan="4" style="border-bottom:solid medium black;"| Armour Stats')
table.insert(resultPart, '\r\n|-\r\n!colspan="2" style="border-bottom:solid thin black;"| Offensive Stats')
table.insert(resultPart, '\r\n|-\r\n!colspan="2" style="border-bottom:solid thin black;"| Offensive Stats')
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Defensive Stats')
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Defensive Stats')
 
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['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;"| ' .. 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['Defence'] .. ' Damage Reduction')
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, 'damageReduction', 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!style="text-align:right;"| ' .. ico['Ranged'] .. ' Defence Bonus')
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, 'rangedDefenceBonus', 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['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))
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;border-bottom:solid thin black;"| ' .. ico['Magic'] .. ' Defence Bonus')
table.insert(resultPart, '\r\n|style="text-align:right;border-bottom:solid thin black;"| ' .. p._getItemStat(item, 'magicDefenceBonus', 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['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))
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Other')
table.insert(resultPart, '\r\n!colspan="2" style="border-bottom:solid thin black;"| Equip Requirements')
 
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))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Slayer'] .. ' Bonus Slayer XP')
if reqCount > 0 then
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'slayerBonusXP', true) .. '%')
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['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))
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Defence'] .. ' Level Required')
if reqCount > 1 then
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'defenceLevelRequired', true))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[2]))
else
table.insert(resultPart, emptyRow)
end
 
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) .. '%')
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Ranged'] .. ' Level Required')
if reqCount > 2 then
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'rangedLevelRequired', true))
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[3]))
else
table.insert(resultPart, '\r\n|-\r\n| colspan="2"|')
table.insert(resultPart, emptyRow)
table.insert(resultPart, '\r\n!style="text-align:right;"| ' .. ico['Magic'] .. ' Level Required')
end
table.insert(resultPart, '\r\n|style="text-align:right;"| ' .. p._getItemStat(item, 'magicLevelRequired', true))
--Add extra rows at the end for items that have more than 3 different requirements
if reqCount > 3 then
for i = 4, reqCount, 1 do
table.insert(resultPart, "\r\n|-")
table.insert(resultPart, emptyRow)
table.insert(resultPart, p.getEquipRequirementRow(item.equipRequirements[i]))
end
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getItemDataExport(frame)
local resultTable = mw.html.create('table')
resultTable:addClass('wikitable')
resultTable:tag('tr'):addClass('headerRow-0')
:tag('th'):wikitext('ItemID'):done()
:tag('th'):wikitext('ItemName'):done()
:tag('th'):wikitext('GPValue'):done()
for i, item in ipairs(GameData.rawData.items) do
resultTable:tag('tr')
:tag('td'):wikitext(item.id):done()
:tag('td'):wikitext(item.name):done()
:tag('td'):wikitext(item.sellsFor):done()
end
return tostring(resultTable)
end
--Returns the expansion icon for the item if it has one
function p.getExpansionIcon(frame)
local itemName = frame.args ~= nil and frame.args[1] or frame
local item = p.getItem(itemName)
if item == nil then
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
return Icons.getExpansionIcon(item.id)
end
function p.buildSmithableArmourNav(frame)
local resultPart = {}
table.insert(resultPart, '{| class="wikitable mw-collapsible navigation-not-searchable" style="margin:auto; clear:both; width: 100%"')
table.insert(resultPart, '\r\n!colspan = 2 style="background-color:#275C87;color:#FFFFFF;min-width:730px;"|')
table.insert(resultPart, Icons.Icon({'Smithing', type='skill', notext=true}))
table.insert(resultPart, ' Smithable Armour Sets')
local metalTypes = {'Bronze', 'Iron', 'Steel', 'Mithril', {'Adamant', 'Adamantite'}, {'Rune', 'Runite'}, {'Dragon', 'Dragonite'},
{'Corundum', 'Corundumite', TotH = true}, {'Augite', 'Augite', TotH = true}, {'Divine', 'Divinite', TotH = true}}
local pieces = {"Helmet", "Platebody", "Platelegs", "Boots", "Shield"}
for i, metal in ipairs(metalTypes) do
local metalName, barName
local isTotH = false
if type(metal) == 'table' then
metalName = metal[1]
barName = metal[2]..' Bar'
isTotH = metal.TotH ~= nil and metal.TotH
else
metalName = metal
barName = metal..' Bar'
end
table.insert(resultPart, '\r\n|-\r\n!')
if isTotH then
table.insert(resultPart, Icons.TotH())
end
table.insert(resultPart, Icons.Icon({barName, type="item", notext=true}))
table.insert(resultPart, " "..metalName)
table.insert(resultPart, "\r\n|")
for j, piece in ipairs(pieces) do
if j > 1 then
table.insert(resultPart, ' • ')
end
table.insert(resultPart, '<span style="display:inline-block">')
table.insert(resultPart, Icons.Icon({metalName..' '..piece, piece, type='item'}))
if isTotH then
table.insert(resultPart, ' '..Icons.Icon({'(I) '..metalName..' '..piece, '(I)', type='item'}))
table.insert(resultPart, ' '..Icons.Icon({'(P) '..metalName..' '..piece, '(P)', type='item'}))
else
table.insert(resultPart, ' '..Icons.Icon({'(S) '..metalName..' '..piece, '(S)', type='item'}))
table.insert(resultPart, ' '..Icons.Icon({'(G) '..metalName..' '..piece, '(G)', type='item'}))
end
table.insert(resultPart, '</span>')
end
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.buildCraftableArmourNav(frame)
local resultPart = {}
table.insert(resultPart, '{| class="wikitable mw-collapsible"')
table.insert(resultPart, '\r\n!colspan = 2 style="background-color:#275C87;color:#FFFFFF;min-width:730px;"|')
table.insert(resultPart, Icons.Icon({'Crafting', type='skill', notext=true}))
table.insert(resultPart, ' Craftable Armour Sets')
local leatherTypes = {'Leather', 'Hard Leather'}
local leatherPieces = {"Cowl", "Body", "Chaps", "Gloves", "Vambraces", "Boots"}
table.insert(resultPart, '\r\n|-\r\n!')
table.insert(resultPart, Icons.Icon({'Leather', type='item', notext=true}))
table.insert(resultPart, ' Leather')
for i, material in pairs(leatherTypes) do
if i > 1 then table.insert(resultPart, '\r\n|-\r\n!Hard Leather') end
table.insert(resultPart, '\r\n|')
for j, piece in ipairs(leatherPieces) do
if j > 1 then
table.insert(resultPart, ' • ')
end
table.insert(resultPart, Icons.Icon({material..' '..piece, piece, type='item'}))
end
end
local materialTypes = {{'Green D-hide', 'Green Dragonhide'}, {'Blue D-hide', 'Blue Dragonhide'}, {'Red D-hide', 'Red Dragonhide'}, {'Black D-hide', 'Black Dragonhide'},
{'Elderwood', 'Elderwood Logs', TotH = true}, {'Revenant', 'Revenant Logs', TotH = true}, {'Carrion', 'Carrion Logs', TotH = true}}
local pieces = {"Body", "Chaps", "Vambraces", "Shield"}
for i, material in ipairs(materialTypes) do
local isTotH = false
local craftName = material[1]
local matName = material[2]
isTotH = material.TotH ~= nil and material.TotH
table.insert(resultPart, '\r\n|-\r\n!')
if isTotH then
table.insert(resultPart, Icons.TotH())
end
table.insert(resultPart, Icons.Icon({matName, type="item", notext=true}))
table.insert(resultPart, " "..craftName)
table.insert(resultPart, "\r\n|")
for j, piece in ipairs(pieces) do
if j > 1 then
table.insert(resultPart, ' • ')
end
table.insert(resultPart, '<span style="display:inline-block">')
table.insert(resultPart, Icons.Icon({craftName..' '..piece, piece, type='item'}))
table.insert(resultPart, ' '..Icons.Icon({'(U) '..craftName..' '..piece, '(U)', type='item'}))
table.insert(resultPart, '</span>')
end
end
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
915

edits