Anonymous

Module:Items: Difference between revisions

From Melvor Idle
Add gem link to gem equipment slot
(_getOtherItemBoxText: Amend links to equipment pages)
(Add gem link to gem equipment slot)
(7 intermediate revisions by 3 users not shown)
Line 25: Line 25:


function p.getItemByID(ID)
function p.getItemByID(ID)
    return GameData.getEntityByID('items', 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)
return GameData.getEntityByName('items', name)
end
end


function p.getItems(checkFunc)
function p.getItems(checkFunc)
    return GameData.getEntities('items', 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
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
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
for i, requirement in ipairs(item.equipRequirements) do
                    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
break
                    end
end
                end
end
end
end
end
end
Line 112: Line 112:
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 136: Line 154:
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
-- 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 185:


function p.hasCombatStats(item)
function p.hasCombatStats(item)
    if 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
if isNonZeroStat(statName, statVal) then
                return true
return true
            end
end
end
end
end
end
return false
return false
end
end
Line 181: Line 210:
--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
for idx, requirement in ipairs(item.equipRequirements) do
            if requirement.type == 'SkillLevel' and requirement.level > 1 then
if requirement.type == 'SkillLevel' and requirement.level > 1 then
                return true
return true
            end
end
        end
end
    end
end
    return false
return false
end
end


Line 208: Line 237:


function p._getWeaponAttackType(item)
function p._getWeaponAttackType(item)
    if (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 226: Line 255:
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 306:
local changeArray = {}
local changeArray = {}


local getSpecificStatString = function(val1, val2, subStr)
local equipStats = {
if val1 == nil then val1 = 0 end
type(item1.equipmentStats) == 'table' and item1.equipmentStats or {},
if val2 == nil then val2 = 0 end
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
local txt = string.gsub(subStr, '{V}', Shared.numStrWithSign(val1 - val2))
table.insert(changeArray, Shared.numStrWithSign(val1 - val2) .. (statDef.suffix or ''))
table.insert(changeArray, txt)
end
end
end
end
--Unfortunately just gonna have to manually check all the changes I think...
local statList = {
-- {'statName', 'statDescription'}
{'stabAttackBonus', '{V} '..Icons.Icon({'Melee', notext=true})..' Stab Bonus'},
{'slashAttackBonus', '{V} '..Icons.Icon({'Melee', notext=true})..' Slash Bonus'},
{'blockAttackBonus', '{V} '..Icons.Icon({'Melee', notext=true})..' Block Bonus'},
{'meleeStrengthBonus', '{V} '..Icons.Icon({'Strength', type='skill', notext=true})..' Strength Bonus'},
{'rangedStrengthBonus', '{V} '..Icons.Icon({'Ranged', type='skill', notext=true})..' Strength Bonus'},
{'magicStrengthBonus', '{V}% '..Icons.Icon({'Magic', type='skill', notext=true})..' Damage Bonus'},
{'meleeDefenceBonus', '{V} '..Icons.Icon({'Defence', type='skill', notext=true})..' Defence Bonus'},
{'rangedDefenceBonus', '{V} '..Icons.Icon({'Ranged', type='skill', notext=true})..' Defence Bonus'},
{'magicDefenceBonus', '{V} '..Icons.Icon({'Magic', type='skill', notext=true})..' Defence Bonus'},
{'damageReduction', '{V}% Damage Reduction'},
{'attackLevelRequired', '{V} '..Icons.Icon({'Attack', type='skill', notext=true})..' Level Required'},
{'defenceLevelRequired', '{V} '..Icons.Icon({'Defence', type='skill', notext=true})..' Level Required'},
{'rangedLevelRequired', '{V} '..Icons.Icon({'Ranged', type='skill', notext=true})..' Level Required'},
{'magicLevelRequired', '{V} '..Icons.Icon({'Magic', type='skill', notext=true})..' Level Required'},
}
for i, stat in ipairs(statList) do
getSpecificStatString(p._getItemStat(item1, stat[1]), p._getItemStat(item2, stat[1]), stat[2])
end
end


Line 292: Line 371:
["Passive"] = 'Combat Passive Slot',
["Passive"] = 'Combat Passive Slot',
["Summon1"] = 'Summoning',
["Summon1"] = 'Summoning',
["Summon2"] = 'Summoning'
["Summon2"] = 'Summoning',
["Gem"] = "Gems_(Equipment)"
}
}
local slotText = {}
local slotText = {}
Line 313: Line 393:
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)
local spAtt = GameData.getEntityByID('attacks', spAttID)
            if spAtt ~= nil then
if spAtt ~= nil then
            local spAttChance = spAtt.defaultChance
local spAttChance = spAtt.defaultChance
            if type(item.overrideSpecialChances) == 'table' and item.overrideSpecialChances[i] ~= nil then
if type(item.overrideSpecialChances) == 'table' and item.overrideSpecialChances[i] ~= nil then
            spAttChance = item.overrideSpecialChances[i]
spAttChance = item.overrideSpecialChances[i]
            end
end
            local spAttDesc = string.gsub(spAtt.description, '<Attack> ', '')
local spAttDesc = string.gsub(spAtt.description, '<Attack> ', '')
    table.insert(resultPart, '\r\n* ' .. spAttChance .. '% chance for ' .. spAtt.name .. ':')
table.insert(resultPart, '\r\n* ' .. spAttChance .. '% chance for ' .. spAtt.name .. ':')
    table.insert(resultPart, '\r\n** ' .. spAttDesc)
table.insert(resultPart, '\r\n** ' .. spAttDesc)
            end
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
Line 374: Line 458:
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 isEquipment = item.validSlots ~= nil or item.occupiesSlots ~= nil or item.equipmentStats ~= nil
    local category = p._getItemStat(item, 'category', false)
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..']]')
table.insert(resultPart, '[[Category:'..category..']]')
    end
end
if item.type ~= nil then
if item.type ~= nil then
        table.insert(resultPart, '[[Category:'..item.type..']]')
table.insert(resultPart, '[[Category:'..item.type..']]')
    end
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..']]')
table.insert(resultPart, '[[Category:'..Shared.titleCase(item.tier)..' '..item.type..']]')
    end
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]]')
table.insert(resultPart, '[[Category:Items With Special Attacks]]')
    end
end
if item.validSlots ~= nil then
if item.validSlots ~= nil then
local slotRemap = {
local slotRemap = {
Line 673: Line 757:
: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 690: Line 774:
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 700: Line 784:
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 722: Line 806:
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 739: Line 823:
end
end
end
end
 
table.insert(resultPart, '\r\n|}')
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
return table.concat(resultPart)
Line 750: Line 834:
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 766: Line 850:
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}}
{'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 782: Line 866:
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 793: Line 877:
end
end
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