Anonymous

Module:Items: Difference between revisions

From Melvor Idle
Add gem link to gem equipment slot
(specifically excluding it from adding the Skills category to items)
(Add gem link to gem equipment slot)
(23 intermediate revisions by 3 users not shown)
Line 7: Line 7:


local GameData = require('Module:GameData')
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')
Line 26: Line 25:


function p.getItemByID(ID)
function p.getItemByID(ID)
    return GameData.getEntityByID('items', ID)
return GameData.getEntityByID('items', ID)
end
end


Line 32: 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
 
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
return item.validSlots ~= nil and Shared.contains(item.validSlots, equipSlot)
end
 
function p._getItemEquipSlot(item)
--Function to return the (non-Passive) equipment slot that an item occupies
if type(item) == 'string' then
item = p.getItem(item)
end
if item == nil or item.validSlots == nil then
return 'Invalid'
end
for i, slot in pairs(item.validSlots) do
if slot ~= 'Passive' then
return slot
end
end
end
end


Line 43: 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 59: 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 89: 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 99: 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 106: 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, skillID, asString)
function p._getItemModifier(item, modifier, skillID, asString)
Line 113: 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 144: 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 158: 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 178: Line 230:
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 185: 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.occupies, '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 199: 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
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
function p.getStatChangeString(item1, item2)
local changeArray = {}
local equipStats = {
type(item1.equipmentStats) == 'table' and item1.equipmentStats or {},
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
-- Include differences in modifiers
local modDiff = Constants.getModifiersText(Constants.getModifiersDifference(item2.modifiers, item1.modifiers))
if modDiff ~= nil and modDiff ~= '' then
table.insert(changeArray, modDiff)
end
return table.concat(changeArray, '<br/>')
end
end


Line 207: Line 354:
local 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
local slotLinkMap = {
local slotLinkMap = {
["Helmet"] = 'Equipment#Helmets',
["Helmet"] = 'Helmets',
["Platebody"] = 'Equipment#Platebodies',
["Platebody"] = 'Platebodies',
["Platelegs"] = 'Equipment#Platelegs',
["Platelegs"] = 'Platelegs',
["Boots"] = 'Equipment#Boots',
["Boots"] = 'Boots',
["Weapon"] = 'Equipment#Weapons',
["Weapon"] = 'Weapons',
["Shield"] = 'Equipment#Offhand',
["Shield"] = 'Shields',
["Amulet"] = 'Equipment#Amulets',
["Amulet"] = 'Amulets',
["Ring"] = 'Equipment#Rings',
["Ring"] = 'Rings',
["Gloves"] = 'Equipment#Gloves',
["Gloves"] = 'Gloves',
["Quiver"] = 'Equipment#Ammunition',
["Quiver"] = 'Ammunition',
["Cape"] = 'Equipment#Capes',
["Cape"] = 'Capes',
["Consumable"] = 'Equipment#Consumables',
["Consumable"] = 'Consumables',
["Passive"] = 'Combat Passive Slot',
["Passive"] = 'Combat Passive Slot',
["Summon1"] = 'Summoning',
["Summon1"] = 'Summoning',
["Summon2"] = 'Summoning'
["Summon2"] = 'Summoning',
["Gem"] = "Gems_(Equipment)"
}
}
local slotText = {}
local slotText = {}
Line 232: Line 381:
else
else
table.insert(slotText, '[[' .. slotLink .. '|' .. slot .. ']]')
table.insert(slotText, '[[' .. slotLink .. '|' .. slot .. ']]')
end
if slot == 'Passive' then
isPassive = true
end
end
end
end
Line 240: 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 263: 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 not Shared.tableIsEmpty(item.modifiers) 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, false, 10))
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 275: Line 450:
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 283: 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 332: 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


Line 366: Line 541:
result = result..'\r\n|style="text-align:right;"| '..req.count
result = result..'\r\n|style="text-align:right;"| '..req.count
elseif req.type == "Completion" then
elseif req.type == "Completion" then
local compName = ""
local ns = GameData.getEntityByName('namespaces', req.namespace)
if req.namespace == "melvorBaseGame" then
if ns == nil then
compName = "Base Game"
return '\r\n!style="text-align:right;" colspan=2|' .. Shared.printError('Invalid namespace for completion requirement "' .. req.namespace .. '"')
elseif req.namespace == "melvorTotH" then
compName = "Throne of the Herald"
else
else
return '\r\n!style="text-align:right;" colspan=2|ERROR: Invalid namespace for completion requirement "..req.namespace.."[[Category:Pages with script errors]]'
result = '\r\n!style="text-align:right;"| ' .. ns.displayName .. ' Completion'
result = result .. '\r\n|style="text-align:right;"| ' .. req.percent .. '%'
end
end
result = '\r\n!style="text-align:right;"| '..compName..' Completion'
result = result..'\r\n|style="text-align:right;"| '..req.percent..'%'
else
else
return '\r\n!style="text-align:right;" colspan=2|ERROR: Invalid equip requirement type "..req.type.."[[Category:Pages with script errors]]'
return '\r\n!style="text-align:right;" colspan=2|' .. Shared.printError('Invalid equip requirement type "' .. req.type .. '"')
end
end
return result
return result
Line 386: 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


Line 496: 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


Line 585: 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 600: Line 772:
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 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|}')
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)
return Icons.getExpansionIcon(item.id)
for i, item in ipairs(items) do
mw.log(item.name)
end
end
end


return p
return p
915

edits