17,101
edits
(_getOtherItemBoxText: Add max hit for Summoning familiars) |
(getStatChangeString: Re-structure for potential performance benefits, and correct issue where certain skills may be omitted) |
||
Line 25: | Line 25: | ||
function p.getItemByID(ID) | function p.getItemByID(ID) | ||
return GameData.getEntityByID('items', ID) | |||
end | end | ||
Line 31: | Line 31: | ||
name = string.gsub(name, "%%27", "'") | name = string.gsub(name, "%%27", "'") | ||
name = string.gsub(name, "'", "'") | name = string.gsub(name, "'", "'") | ||
return GameData.getEntityByName('items', name) | |||
end | end | ||
function p.getItems(checkFunc) | function p.getItems(checkFunc) | ||
return GameData.getEntities('items', checkFunc) | |||
end | end | ||
Line 66: | Line 66: | ||
--Special Overrides: | --Special Overrides: | ||
-- Equipment stats first | -- Equipment stats first | ||
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 | -- Item can be equipped as a weapon but has no attack speed, so use default of 4000ms | ||
result = 4000 | result = 4000 | ||
Line 82: | Line 82: | ||
local skillID = Constants.getSkillID(skillName) | local skillID = Constants.getSkillID(skillName) | ||
if skillID ~= nil then | if skillID ~= nil then | ||
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 136: | Line 136: | ||
skillID = nil | skillID = nil | ||
elseif string.find(skillID, ':') == nil then | elseif string.find(skillID, ':') == nil then | ||
-- Try to find a skill ID if it looks like a skill name has been passed | |||
skillID = Constants.getSkillID(skillID) | skillID = Constants.getSkillID(skillID) | ||
end | end | ||
Line 167: | Line 167: | ||
function p.hasCombatStats(item) | function p.hasCombatStats(item) | ||
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 statVal ~= 0 then | ||
return true | |||
end | |||
end | end | ||
end | end | ||
Line 181: | Line 181: | ||
--Function true if an item has at least one level requirement to equip | --Function true if an item has at least one level requirement to equip | ||
if item.equipRequirements ~= nil then | 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 | |||
return false | |||
end | end | ||
Line 208: | Line 208: | ||
function p._getWeaponAttackType(item) | function p._getWeaponAttackType(item) | ||
if (item.validSlots ~= nil and Shared.contains(item.validSlots, 'Weapon')) or | |||
(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 226: | Line 226: | ||
return p._getWeaponAttackType(item) | return p._getWeaponAttackType(item) | ||
end | end | ||
local statChangeDefs = { | |||
{ | |||
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' | |||
} | |||
} | |||
-- Produces a list of stat & modifier changes between two items of equipmednt | -- Produces a list of stat & modifier changes between two items of equipmednt | ||
Line 231: | Line 277: | ||
local changeArray = {} | local changeArray = {} | ||
local | local equipStats = { | ||
type(item1.equipmentStats) == 'table' and item1.equipmentStats or {}, | |||
if val2 == | 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 | if val1 ~= val2 then | ||
table.insert(changeArray, Shared.numStrWithSign(val1 - val2) .. (statDef.suffix or '')) | |||
end | end | ||
end | end | ||
end | end | ||
Line 313: | Line 363: | ||
table.insert(resultPart, "\r\n|-\r\n|'''Special Attack:'''") | table.insert(resultPart, "\r\n|-\r\n|'''Special Attack:'''") | ||
for i, spAttID in ipairs(item.specialAttacks) do | for i, spAttID in ipairs(item.specialAttacks) do | ||
local spAtt = GameData.getEntityByID('attacks', spAttID) | |||
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 | end | ||
Line 378: | Line 428: | ||
function p._getItemCategories(item) | function p._getItemCategories(item) | ||
local resultPart = {} | local resultPart = {} | ||
local isEquipment = item.validSlots ~= nil or item.occupiesSlots ~= nil or item.equipmentStats ~= nil | |||
local category = p._getItemStat(item, 'category', false) | |||
if category ~= nil and category ~= 'Skills' then | if category ~= nil and category ~= 'Skills' then | ||
table.insert(resultPart, '[[Category:'..category..']]') | |||
end | |||
if item.type ~= nil then | if item.type ~= nil then | ||
table.insert(resultPart, '[[Category:'..item.type..']]') | |||
end | |||
if isEquipment and item.tier ~= nil then | 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 | 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 677: | Line 727: | ||
:tag('th'):wikitext('ItemName'):done() | :tag('th'):wikitext('ItemName'):done() | ||
:tag('th'):wikitext('GPValue'):done() | :tag('th'):wikitext('GPValue'):done() | ||
for i, item in ipairs(GameData.rawData.items) do | for i, item in ipairs(GameData.rawData.items) do | ||
resultTable:tag('tr') | resultTable:tag('tr') | ||
Line 694: | Line 744: | ||
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 | ||
return Icons.getExpansionIcon(item.id) | return Icons.getExpansionIcon(item.id) | ||
end | end | ||
Line 704: | Line 754: | ||
table.insert(resultPart, Icons.Icon({'Smithing', type='skill', notext=true})) | table.insert(resultPart, Icons.Icon({'Smithing', type='skill', notext=true})) | ||
table.insert(resultPart, ' Smithable Armour Sets') | table.insert(resultPart, ' Smithable Armour Sets') | ||
local metalTypes = {'Bronze', 'Iron', 'Steel', 'Mithril', {'Adamant', 'Adamantite'}, {'Rune', 'Runite'}, {'Dragon', 'Dragonite'}, | local metalTypes = {'Bronze', 'Iron', 'Steel', 'Mithril', {'Adamant', 'Adamantite'}, {'Rune', 'Runite'}, {'Dragon', 'Dragonite'}, | ||
{'Corundum', 'Corundumite', TotH = true}, {'Augite', 'Augite', TotH = true}, {'Divine', 'Divinite', TotH = true}} | {'Corundum', 'Corundumite', TotH = true}, {'Augite', 'Augite', TotH = true}, {'Divine', 'Divinite', TotH = true}} | ||
Line 726: | Line 776: | ||
table.insert(resultPart, " "..metalName) | table.insert(resultPart, " "..metalName) | ||
table.insert(resultPart, "\r\n|") | table.insert(resultPart, "\r\n|") | ||
for j, piece in ipairs(pieces) do | for j, piece in ipairs(pieces) do | ||
if j > 1 then | if j > 1 then | ||
Line 743: | Line 793: | ||
end | end | ||
end | end | ||
table.insert(resultPart, '\r\n|}') | table.insert(resultPart, '\r\n|}') | ||
return table.concat(resultPart) | return table.concat(resultPart) | ||
Line 754: | Line 804: | ||
table.insert(resultPart, Icons.Icon({'Crafting', type='skill', notext=true})) | table.insert(resultPart, Icons.Icon({'Crafting', type='skill', notext=true})) | ||
table.insert(resultPart, ' Craftable Armour Sets') | table.insert(resultPart, ' Craftable Armour Sets') | ||
local leatherTypes = {'Leather', 'Hard Leather'} | local leatherTypes = {'Leather', 'Hard Leather'} | ||
local leatherPieces = {"Cowl", "Body", "Chaps", "Gloves", "Vambraces", "Boots"} | local leatherPieces = {"Cowl", "Body", "Chaps", "Gloves", "Vambraces", "Boots"} | ||
Line 770: | Line 820: | ||
end | end | ||
end | end | ||
local materialTypes = {{'Green D-hide', 'Green Dragonhide'}, {'Blue D-hide', 'Blue Dragonhide'}, {'Red D-hide', 'Red Dragonhide'}, {'Black D-hide', 'Black Dragonhide'}, | 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"} | local pieces = {"Body", "Chaps", "Vambraces", "Shield"} | ||
for i, material in ipairs(materialTypes) do | for i, material in ipairs(materialTypes) do | ||
Line 786: | Line 836: | ||
table.insert(resultPart, " "..craftName) | table.insert(resultPart, " "..craftName) | ||
table.insert(resultPart, "\r\n|") | table.insert(resultPart, "\r\n|") | ||
for j, piece in ipairs(pieces) do | for j, piece in ipairs(pieces) do | ||
if j > 1 then | if j > 1 then | ||
Line 797: | Line 847: | ||
end | end | ||
end | end | ||
table.insert(resultPart, '\r\n|}') | table.insert(resultPart, '\r\n|}') | ||
return table.concat(resultPart) | return table.concat(resultPart) |