12,867
edits
Falterfire (talk | contribs) (more right-aligning) |
(_getItemUseTable: Support GP & SC in various artisan skills) |
||
(23 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local ItemData = mw.loadData('Module:Items/data') | local ItemData = mw.loadData('Module:Items/data') | ||
local SkillData = mw.loadData('Module:Skills/data') | local SkillData = mw.loadData('Module:Skills/data') | ||
Line 14: | Line 13: | ||
local Shop = require('Module:Shop') | local Shop = require('Module:Shop') | ||
local SkillEnum = mw.loadData('Module:Constants/data').skill | |||
--Brute forcing some item uses to make things easier | --Brute forcing some item uses to make things easier | ||
local itemUseArray = { | local itemUseArray = { | ||
Agility = {}, | |||
Astrology = {'Stardust', 'Golden Stardust'}, | |||
Attack = {}, | |||
Combat = {'Gold Emerald Ring', 'Obsidian Cape', 'Throwing Power Gloves'}, | |||
Cooking = {'Cooking Gloves', 'Crown of Rhaelyx'}, | |||
Crafting = {'Crown of Rhaelyx'}, | |||
Defence = {}, | |||
Farming = {'Compost', 'Weird Gloop', 'Bob's Rake'}, | |||
Firemaking = {'Crown of Rhaelyx'}, | |||
Fishing = {'Amulet of Fishing', 'Message in a Bottle', 'Barbarian Gloves'}, | |||
Fletching = {'Crown of Rhaelyx'}, | |||
Herblore = {'Crown of Rhaelyx'}, | |||
Hitpoints = {}, | |||
Magic = {}, | |||
Mining = {'Mining Gloves', 'Gem Gloves'}, | |||
Prayer = {}, | |||
Ranged = {}, | |||
Runecrafting = {'Crown of Rhaelyx'}, | |||
Slayer = {}, | |||
Smithing = {'Smithing Gloves', 'Crown of Rhaelyx'}, | |||
Strength = {}, | |||
Summoning = {'Crown of Rhaelyx'}, | |||
Thieving = {'Chapeau Noir', 'Thieving Gloves', 'Gloves of Silence'}, | |||
Woodcutting = {}, | |||
} | |||
local potionUseArray = { | local potionUseArray = { | ||
[0] = 'Combat', | |||
[1] = 'Combat', | |||
[2] = 'Combat', | |||
[3] = 'Combat', | |||
[4] = 'Combat', | |||
[5] = 'Combat', | |||
[6] = 'Combat', | |||
[7] = 'Woodcutting', | |||
[8] = 'Fishing', | |||
[9] = 'Firemaking', | |||
[10] = 'Cooking', | |||
[11] = 'Mining', | |||
[12] = 'Smithing', | |||
[13] = 'Thieving', | |||
[14] = 'Farming', | |||
[15] = 'Fletching', | |||
[16] = 'Crafting', | |||
[17] = 'Runecrafting', | |||
[18] = 'Herblore', | |||
[19] = 'Combat', | |||
[20] = 'Combat', | |||
[21] = 'Combat', | |||
[22] = 'Combat', | |||
[23] = 'Combat', | |||
[24] = 'Agility', | |||
[25] = 'Summoning', | |||
[26] = 'Combat', | |||
[27] = 'Combat', | |||
[28] = 'Combat', | |||
[29] = 'Astrology' | |||
} | } | ||
function p._getItemUses(item, asList, addCategories) | function p._getItemUses(item, asList, addCategories) | ||
-- Another fun one. This time getting all the different possible ways an item can be used | |||
local categoryArray = {} | |||
local skillUses = {} | |||
local otherUses = {} | |||
local otherUseText = { | |||
["Combat"] = Icons.Icon({'Combat'}), | |||
["Upgrade"] = '[[Upgrading Items]]', | |||
["Food"] = '[[Food]]', | |||
["Chest"] = '[[Chest Drop Tables|Can Be Opened]]', | |||
["Mastery"] = Icons.Icon({'Mastery'}), | |||
["AllSkills"] = 'All skills', | |||
["AltMagic"] = Icons.Icon({'Alt. Magic', type='skill'}), | |||
["ChargeStone"] = 'Powering ' .. Icons.Icon({'Crown of Rhaelyx', type='item'}), | |||
["Shop"] = Icons.Icon({'Shop'}) | |||
} | |||
local addUse = function(useName) | |||
local skillID = (type(useName) == 'number' and useName) or SkillEnum[useName] | |||
if type(skillID) == 'number' then | |||
if skillUses[skillID] == nil then | |||
skillUses[skillID] = Constants.getSkillName(skillID) | |||
end | |||
elseif not otherUses[useName] then | |||
otherUses[useName] = true | |||
end | |||
end | |||
local hasUse = function(useName) | |||
local skillID = (type(useName) == 'number' and useName) or SkillEnum[useName] | |||
if type(skillID) == 'number' then | |||
return (skillUses[skillID] ~= nil) or false | |||
else | |||
return otherUses[useName] or false | |||
end | |||
end | |||
-- Check for any overrides within itemUseArray | |||
for useName, itemList in pairs(itemUseArray) do | |||
if Shared.contains(itemList, item.name) then | |||
addUse(useName) | |||
end | |||
end | |||
-- If this is a potion add it to the appropriate uses table | |||
if type(item.masteryID) == 'table' and item.masteryID[1] == SkillEnum.Herblore then | |||
-- Default to 'Combat' if unknown | |||
local potionUse = potionUseArray[item.masteryID[2]] or 'Combat' | |||
addUse(potionUseArray[item.masteryID[2]] or 'Combat') | |||
end | |||
-- If the item has any modifiers that affect a given skill, add it to those tables | |||
-- Added an exception for Mastery Tokens since they were being incorrectly flagged as usable for all skills | |||
if item.modifiers ~= nil and (item.isToken == nil or not item.isToken) then | |||
local skillArray = Constants.getModifierSkills(item.modifiers) | |||
for i, skillName in ipairs(skillArray) do | |||
addUse(skillName) | |||
end | |||
end | |||
--First things added to the list are non-skill things that are easy to check | |||
if not hasUse('Combat') and (Items.hasCombatStats(item) or item.specialAttacks ~= nil) then | |||
addUse('Combat') | |||
end | |||
-- Check if the item is an entry requirement for any Slayer area | |||
if not hasUse(SkillEnum.Slayer) and item.isEquipment then | |||
local slayerAreas = Areas.getAreas(function(area) return area.type == 'slayer' and type(area.entryRequirements) == 'table' end) | |||
for i, area in pairs(slayerAreas) do | |||
for j, req in pairs(area.entryRequirements) do | |||
if req.type == "SlayerItem" and req.itemID == item.id then | |||
addUse(SkillEnum.Slayer) | |||
break | |||
end | |||
end | |||
if hasUse(SkillEnum.Slayer) then | |||
break | |||
end | |||
end | |||
end | |||
-- Can the item be upgraded, or is it part of an upgrade recipe? | |||
if item.canUpgrade then | |||
addUse('Upgrade') | |||
else | |||
for i, item2 in pairs(ItemData.Items) do | |||
if item2.itemsRequired ~= nil then | |||
for j, req in ipairs(item2.itemsRequired) do | |||
if req[1] == item.id then | |||
addUse('Upgrade') | |||
break | |||
end | |||
end | |||
if hasUse('Upgrade') then | |||
break | |||
end | |||
end | |||
end | |||
end | |||
if hasUse('Upgrade') then | |||
table.insert(categoryArray, '[[Category:Upgradeable Items]]') | |||
end | |||
if item.healsFor ~= nil then | |||
table.insert(categoryArray, '[[Category:Food Items]]') | |||
addUse('Food') | |||
end | |||
if item.canOpen then | |||
table.insert(categoryArray, '[[Category:Openable Items]]') | |||
addUse('Chest') | |||
end | |||
-- Cooking, Smithing, Fletching, Crafting, Runecrafting, Herblore | |||
-- All have somewhat consistent recipe data structures | |||
local recipeSkillIDs = { | |||
SkillEnum.Cooking, | |||
SkillEnum.Smithing, | |||
SkillEnum.Fletching, | |||
SkillEnum.Crafting, | |||
SkillEnum.Runecrafting, | |||
SkillEnum.Herblore | |||
} | |||
for i, recipeSkillID in ipairs(recipeSkillIDs) do | |||
if not hasUse(recipeSkillID) then | |||
local recipeKey = (recipeSkillID == SkillEnum.Herblore and 'Potions') or 'Recipes' | |||
local skillName = Constants.getSkillName(recipeSkillID) | |||
-- Iterate over all recipes for the current skill | |||
for j, recipe in ipairs(SkillData[skillName][recipeKey]) do | |||
for k, itemCost in ipairs(recipe.itemCosts) do | |||
if itemCost.id == item.id then | |||
addUse(recipeSkillID) | |||
break | |||
end | |||
end | |||
-- Some items (such as Arrow shafts) have multiple recipes | |||
if not hasUse(recipeSkillID) and type(recipe.alternativeCosts) == 'table' then | |||
for k, altCost in ipairs(recipe.alternativeCosts) do | |||
for m, itemCost in ipairs(altCost.itemCosts) do | |||
if itemCost.id == item.id then | |||
addUse(recipeSkillID) | |||
break | |||
end | |||
end | |||
if hasUse(recipeSkillID) then | |||
break | |||
end | |||
end | |||
end | |||
if hasUse(recipeSkillID) then | |||
break | |||
end | |||
end | |||
end | |||
end | |||
-- Firemaking | |||
if not hasUse(SkillEnum.Firemaking) and type(item.masteryID) == 'table' and item.masteryID[1] == SkillEnum.Firemaking then | |||
addUse(SkillEnum.Firemaking) | |||
end | |||
-- Farming | |||
if not hasUse(SkillEnum.Farming) and item.grownItemID ~= nil then | |||
addUse(SkillEnum.Farming) | |||
end | |||
-- Agility | |||
if not hasUse(SkillEnum.Agility) and Shared.tableCount(Agility.getObstaclesForItem(item.id)) > 0 then | |||
addUse(SkillEnum.Agility) | |||
end | |||
-- Summoning | |||
if not hasUse(SkillEnum.Summoning) then | |||
for i, recipe in ipairs(SkillData.Summoning.Marks) do | |||
-- Tablets & Non-shard items | |||
if recipe.itemID == item.id or Shared.contains(recipe.nonShardItemCosts, item.id) then | |||
addUse(SkillEnum.Summoning) | |||
break | |||
else | |||
-- Shards | |||
for j, itemCost in ipairs(recipe.itemCosts) do | |||
if itemCost.id == item.id then | |||
addUse(SkillEnum.Summoning) | |||
break | |||
end | |||
end | |||
if hasUse(SkillEnum.Summoning) then | |||
break | |||
end | |||
end | |||
end | |||
end | |||
-- Prayer | |||
if item.prayerPoints ~= nil then | |||
table.insert(categoryArray, '[[Category:Buriable Items]]') | |||
if not hasUse(SkillEnum.Prayer) then | |||
addUse(SkillEnum.Prayer) | |||
end | |||
end | |||
-- Magic | |||
if not (hasUse('Magic') and hasUse('AltMagic')) then | |||
-- First check if the item its self is used in any spells | |||
local spellList = Magic.getSpellsForItem(item.id, true) | |||
for i, spell in ipairs(spellList) do | |||
local useKey = (spell.type == 'AltMagic' and 'AltMagic' or 'Magic') | |||
if not hasUse(useKey) then | |||
addUse(useKey) | |||
end | |||
end | |||
-- Check if the item provides runes, if it does check where they are used also | |||
if item.providesRune ~= nil then | |||
for i, runeID in ipairs(item.providesRune) do | |||
if hasUse('Magic') and hasUse('AltMagic') then | |||
break | |||
else | |||
local spellList = Magic.getSpellsForItem(runeID, false) | |||
for j, spell in ipairs(spellList) do | |||
local useKey = (spell.type == 'AltMagic' and 'AltMagic' or 'Magic') | |||
if not hasUse(useKey) then | |||
addUse(useKey) | |||
end | |||
end | |||
end | |||
end | |||
end | |||
end | |||
-- Other odds and ends: | |||
-- Mastery Tokens are tied to 'Mastery' | |||
if item.isToken and item.skill ~= nil then | |||
addUse('Mastery') | |||
end | |||
-- Skillcapes are tied to the appropriate skill | |||
-- Except Maximum Skillcape, which is tied to all skills. (And so is the Signet Ring) | |||
-- And combat skillcapes, since combat skills don't get special treatment | |||
local ignoreCapes = {'Ranged Skillcape', 'Attack Skillcape', 'Strength Skillcape', 'HP Skillcape', 'Defence Skillcape'} | |||
if Shared.contains({'Maximum Skillcape', "Aorpheat's Signet Ring", 'Ring of Wealth', 'Cape of Completion'}, item.name) then | |||
addUse('AllSkills') | |||
elseif item.name == 'Magic Skillcape' then | |||
addUse(SkillEnum.Magic) | |||
addUse('AltMagic') | |||
elseif Shared.contains(item.name, 'Skillcape') and not Shared.contains(ignoreCapes, item.name) then | |||
local skillName = Shared.splitString(item.name, ' ')[1] | |||
addUse(skillName) | |||
end | |||
if Shared.contains(item.name, 'Skillcape') or item.name == 'Cape of Completion' then | |||
table.insert(categoryArray, '[[Category:Skillcapes]]') | |||
end | |||
--Special note for Charge Stone of Rhaelyx | |||
if item.name == 'Charge Stone of Rhaelyx' then | |||
addUse('ChargeStone') | |||
end | |||
--Some items are needed to make shop purchases | |||
local shopArray = Shop.getItemCostArray(item.id) | |||
if Shared.tableCount(shopArray) > 0 then | |||
addUse('Shop') | |||
end | |||
-- Generate result text | |||
local useArray = {} | |||
local prefix, delim = asList and '* ' or '', asList and '\r\n' or '<br/>' | |||
for skillID, skillName in Shared.spairs(skillUses, function(t, a, b) return t[a] < t[b] end) do | |||
table.insert(useArray, prefix .. Icons.Icon({skillName, type='skill'})) | |||
end | |||
for use, _ in Shared.skpairs(otherUses) do | |||
table.insert(useArray, prefix .. (otherUseText[use] or use)) | |||
end | |||
return table.concat(useArray, delim) .. (addCategories and table.concat(categoryArray, '') or '') | |||
end | end | ||
function p.getItemUses(frame) | function p.getItemUses(frame) | ||
local itemName = frame.args ~= nil and frame.args[1] or frame | |||
local item = Items.getItem(itemName) | |||
local addCategories = false | |||
local asList = true | |||
if frame.args ~= nil then | |||
addCategories = frame.args.addCategories ~= nil and frame.args.addCategories ~= '' and frame.args.addCategories ~= 'false' | |||
asList = frame.args.addCategories == nil or frame.args.addCategories == '' or frame.args.addCategories == 'true' | |||
end | |||
if item == nil then | |||
return "ERROR: No item named "..itemName.." exists in the data module" | |||
end | |||
return p._getItemUses(item, asList, addCategories) | |||
end | end | ||
function p._getItemUseTable(item) | function p._getItemUseTable(item) | ||
local useArray = {} | |||
-- Loop through all items to find anything that can be upgraded using our source | |||
for i, item2 in ipairs(ItemData.Items) do | |||
if item2.itemsRequired ~= nil then | |||
for j, req in pairs(item2.itemsRequired) do | |||
if req[1] == item.id then | |||
local mat = item2.itemsRequired | |||
local xp = 'N/A' | |||
local rowReq = nil | |||
--Potions do have upgrade requirements though | |||
if item2.potionTier ~= nil then | |||
rowReq = Icons._MasteryReq(item2.name, SkillData.Herblore.TierMasteryLevels[item2.potionTier + 1]) | |||
end | |||
table.insert(useArray, {item = {id = item2.id, name = item2.name}, qty = 1, mats = mat, skill = 'Upgrade', req = rowReq, xp = xp, gp = item2.trimmedGPCost}) | |||
break | |||
end | |||
end | |||
end | |||
end | |||
-- Cooking, Smithing, Fletching, Crafting, Runecrafting, Herblore | |||
-- All have somewhat consistent recipe data structures | |||
local recipeSkillIDs = { | |||
SkillEnum.Cooking, | |||
SkillEnum.Smithing, | |||
SkillEnum.Fletching, | |||
SkillEnum.Crafting, | |||
SkillEnum.Runecrafting, | |||
SkillEnum.Herblore | |||
} | |||
for i, recipeSkillID in ipairs(recipeSkillIDs) do | |||
local skillName = Constants.getSkillName(recipeSkillID) | |||
local recipeKey = (recipeSkillID == SkillEnum.Herblore and 'Potions') or 'Recipes' | |||
-- Iterate over all recipes for the current skill | |||
for j, recipe in ipairs(SkillData[skillName][recipeKey]) do | |||
local costLists = {recipe.alternativeCosts or {}, {{["itemCosts"] = recipe.itemCosts}}} | |||
for k, costList in pairs(costLists) do | |||
for m, costDef in pairs(costList) do | |||
for n, itemCost in ipairs(costDef.itemCosts) do | |||
if itemCost.id == item.id then | |||
local recipeItemIDs = nil | |||
if recipeSkillID == SkillEnum.Herblore then | |||
recipeItemIDs = recipe.potionIDs | |||
elseif recipeSkillID == SkillEnum.Cooking then | |||
recipeItemIDs = {recipe.itemID, recipe.perfectCookID} | |||
else | |||
recipeItemIDs = {recipe.itemID} | |||
end | |||
for o, recipeItemID in ipairs(recipeItemIDs) do | |||
local recipeItem = Items.getItemByID(recipeItemID) | |||
if recipeItem ~= nil then | |||
local itemDef = {id = recipe.itemID, name = recipeItem.name} | |||
local qty = (recipe.baseQuantity or 1) * (costDef.quantityMultiplier or 1) | |||
local rowReq = recipe.level | |||
local reqVal = nil | |||
if recipeSkillID == SkillEnum.Herblore then | |||
-- Herblore may also have a mastery requirement | |||
local masteryLvl = SkillData.Herblore.TierMasteryLevels[o] | |||
if masteryLvl ~= nil and masteryLvl > 1 then | |||
local masteryReq = Icons._MasteryReq(recipeItem.name, masteryLvl) | |||
reqVal = rowReq + masteryLvl * 0.01 | |||
rowReq = Icons._SkillReq(skillName, rowReq) .. '<br/>' .. masteryReq | |||
end | |||
end | |||
table.insert(useArray, {item = itemDef, qty = qty, mats = costDef.itemCosts, gp = recipe.gpCost, sc = recipe.scCost, skill = skillName, reqVal = reqVal, req = rowReq, xp = recipe.baseXP}) | |||
end | |||
end | |||
break | |||
end | |||
end | |||
end | |||
end | |||
end | |||
end | |||
-- Farming | |||
if item.grownItemID ~= nil then | |||
local item2 = Items.getItemByID(item.grownItemID) | |||
local mat = {{id = item.id, qty = item.seedsRequired}} | |||
local xp = item.farmingXP | |||
local rowReq = item.farmingLevel | |||
local qty = (item.tier ~= nil and item.tier == 'Tree' and 35 or 15) | |||
table.insert(useArray, {item = {id = item2.id, name = item2.name}, qty = qty, mats = mat, skill = 'Farming', req = rowReq, xp = xp}) | |||
end | |||
-- Agility | |||
local obstacles = Agility.getObstaclesForItem(item.id) | |||
for i, obstacle in ipairs(obstacles) do | |||
local itemCosts = {} | |||
for j, itemDef in ipairs(obstacle.cost.items) do | |||
table.insert(itemCosts, {id = itemDef[1], qty = itemDef[2]}) | |||
end | |||
local req = Agility._getObstacleRequirements(obstacle) | |||
--local objType = (obstacle.category == nil and 'Pillar') or 'Obstacle' | |||
table.insert(useArray, {item = {id = obstacle.id, name = obstacle.name}, qty = 1, mats = itemCosts, gp = obstacle.cost.gp, sc = obstacle.cost.slayerCoins, skill = 'Agility', req = req, type = 'skill'}) | |||
end | |||
-- Summoning | |||
for i, recipe in ipairs(SkillData.Summoning.Marks) do | |||
local recipeGPCost = SkillData.Summoning.RecipeGPCost | |||
local useShards = false | |||
local recipeItem = nil | |||
for j, itemCost in ipairs(recipe.itemCosts) do | |||
if itemCost.id == item.id then | |||
useShards = true | |||
break | |||
end | |||
end | |||
-- Non-shard items | |||
for j, nonShardItemID in ipairs(recipe.nonShardItemCosts) do | |||
if useShards or nonShardItemID == item.id then | |||
-- Item is used in this particular synergy recipe | |||
if recipeItem == nil then | |||
recipeItem = Items.getItemByID(recipe.itemID) | |||
end | |||
local nonShardItem = Items.getItemByID(nonShardItemID) | |||
local itemValue = math.max(nonShardItem.sellsFor, 20) | |||
local nonShardQty = math.max(1, math.floor(recipeGPCost / itemValue)) | |||
local recipeCosts = Shared.clone(recipe.itemCosts) | |||
table.insert(recipeCosts, {id = nonShardItemID, qty = nonShardQty}) | |||
table.insert(useArray, {item = {id = recipe.itemID, name = recipeItem.name}, qty = recipe.baseQuantity, mats = recipeCosts, gp = recipe.gpCost, sc = recipe.scCost, skill = 'Summoning', req = recipe.level, xp = recipe.baseXP}) | |||
end | |||
end | |||
end | |||
--Handle shop purchases using Module:Shop | |||
local shopUses = Shop.getItemCostArray(item.id) | |||
for i, purchase in ipairs(shopUses) do | |||
local rowReq = Shop.getRequirementString(purchase.unlockRequirements) | |||
local iconType = (purchase.contains.items ~= nil and Shared.tableCount(purchase.contains.items) > 0) and 'item' or 'upgrade' | |||
table.insert(useArray, {item = {name = purchase.name}, qty = 1, mats = purchase.cost.items, skill = 'Shop', req = rowReq, xp = 'N/A', gp = purchase.cost.gp, type = iconType}) | |||
end | |||
--Finally build the table using what we've learned | |||
table.sort(useArray, function(a, b) | |||
local aReqVal = a.reqVal ~= nil and a.reqVal or a.req | |||
local bReqVal = b.reqVal ~= nil and b.reqVal or b.req | |||
if a.skill ~= b.skill then | |||
return a.skill < b.skill | |||
elseif type(aReqVal) ~= type(bReqVal) then | |||
return tostring(aReqVal) < tostring(bReqVal) | |||
elseif aReqVal ~= bReqVal then | |||
return aReqVal < bReqVal | |||
else | |||
return a.item.name < b.item.name | |||
end | |||
end) | |||
local resultPart = {} | |||
if Shared.tableCount(useArray) > 0 then | |||
local typeTextList = { | |||
["Shop"] = Icons.Icon({'Shop'}), | |||
["Upgrade"] = '[[Upgrading Items|Upgrade]]' | |||
} | |||
-- Header | |||
table.insert(resultPart, '{| class="wikitable stickyHeader sortable"') | |||
table.insert(resultPart, '\r\n|- class="headerRow-0"') | |||
table.insert(resultPart, '\r\n!colspan=2|Item Created!!Type!!Requirements!!XP!!Ingredients') | |||
-- Rows | |||
for i, row in ipairs(useArray) do | |||
local qty = row.qty ~= nil and row.qty or 1 | |||
local iconType = row.type ~= nil and row.type or 'item' | |||
local iconName = row.item.name | |||
if row.skill == 'Agility' then | |||
iconName = 'Agility' | |||
end | |||
local typeName = row.skill ~= nil and row.skill or '' | |||
local typeText = typeTextList[typeName] or Icons.Icon({typeName, type='skill'}) or '' | |||
local reqVal, reqText = row.reqVal, 'None' | |||
if type(row.req) == 'number' then | |||
reqVal = row.req | |||
reqText = Icons._SkillReq(typeName, row.req) | |||
elseif type(row.req) == 'string' then | |||
reqText = row.req | |||
end | |||
local xpVal, xpText = 0, 'N/A' | |||
if type(row.xp) == 'string' then | |||
xpText = row.xp | |||
elseif type(row.xp) == 'number' then | |||
xpVal = row.xp | |||
xpText = Shared.formatnum(row.xp) .. ' ' .. Icons.Icon({typeName, type='skill', notext=true}) .. ' XP' | |||
end | |||
local matRow = {} | |||
if type(row.mats) == 'table' then | |||
for j, itemCost in ipairs(row.mats) do | |||
local matItemID = itemCost.id or itemCost[1] or -1 | |||
local matItem = Items.getItemByID(matItemID) | |||
local matQty = itemCost.qty or itemCost[2] or 1 | |||
if matItem == nil then | |||
table.insert(matRow, 'ERROR: Failed to find item with ID ' .. itemCost.id .. '[[Category:Pages with script errors]]') | |||
elseif type(matQty) == 'number' then | |||
table.insert(matRow, Icons.Icon({matItem.name, type='item', qty=matQty})) | |||
else | |||
table.insert(matRow, Icons.Icon({matItem.name, type='item'})) | |||
end | |||
end | |||
end | |||
if row.gp ~= nil and row.gp > 0 then | |||
table.insert(matRow, Icons.GP(row.gp)) | |||
end | |||
if row.sc ~= nil and row.sc > 0 then | |||
table.insert(matRow, Icons.SC(row.sc)) | |||
end | |||
-- Item created | |||
table.insert(resultPart, '\r\n|-\r\n|data-sort-value="' .. row.item.name .. '"| ') | |||
table.insert(resultPart, Icons.Icon({iconName, row.item.name, type=iconType, notext=true, size=50})) | |||
table.insert(resultPart, '\r\n| ') | |||
if qty > 1 then | |||
table.insert(resultPart, "'''" .. Shared.formatnum(qty) .. "x''' ") | |||
end | |||
table.insert(resultPart, Icons.Icon({iconName, row.item.name, type=iconType, noicon=true})) | |||
-- Type | |||
table.insert(resultPart, '\r\n|data-sort-value="' .. typeName .. '"| ' .. typeText) | |||
-- Requirements | |||
table.insert(resultPart, '\r\n|style="text-align:right;"') | |||
if row.reqVal ~= nil then | |||
table.insert(resultPart, ' data-sort-value="' .. reqVal .. '"') | |||
end | |||
table.insert(resultPart, '| ' .. reqText) | |||
-- XP | |||
table.insert(resultPart, '\r\n|style="text-align:right;" data-sort-value="' .. xpVal .. '"| ' .. xpText) | |||
-- Ingredients | |||
table.insert(resultPart, '\r\n| ' .. table.concat(matRow, '<br/>')) | |||
end | |||
table.insert(resultPart, '\r\n|}') | |||
end | |||
local spellUseTable = p._getSpellUseTable(item) | |||
if spellUseTable ~= nil and spellUseTable ~= '' then | |||
table.insert(resultPart, '\r\n===' .. Icons.Icon({'Magic', type='skill', size=30}) .. '===\r\n' .. spellUseTable) | |||
end | |||
if Shared.tableCount(resultPart) == 0 then | |||
return '' | |||
else | |||
return '==Uses==\r\n' .. table.concat(resultPart) | |||
end | |||
end | end | ||
function p.getItemUseTable(frame) | function p.getItemUseTable(frame) | ||
local itemName = frame.args ~= nil and frame.args[1] or frame | |||
local item = Items.getItem(itemName) | |||
if item == nil then | |||
return "ERROR: No item named "..itemName.." exists in the data module" | |||
end | |||
return p._getItemUseTable(item) | |||
end | end | ||
function p._getSpellUseTable(item) | function p._getSpellUseTable(item) | ||
local spellList = Magic.getSpellsForItem(item.id, true) | |||
--Bail immediately if no spells are found | |||
if Shared.tableCount(spellList) == 0 then | |||
return '' | |||
end | |||
local resultPart = {} | |||
table.insert(resultPart, '{|class="wikitable sortable"\r\n!colspan="2"|Spell') | |||
table.insert(resultPart, '!!Requirements') | |||
table.insert(resultPart, '!!Type!!style="width:275px"|Description') | |||
table.insert(resultPart, '!!Runes') | |||
for i, spell in pairs(spellList) do | |||
local rowPart = {} | |||
table.insert(rowPart, '\r\n|-\r\n|data-sort-value="'..spell.name..'"|') | |||
local iconType = (spell.type == 'Auroras' and 'aurora') or (spell.type == 'Curses' and 'curse') or 'spell' | |||
table.insert(rowPart, Icons.Icon({spell.name, type=iconType, notext=true, size=50})) | |||
table.insert(rowPart, '||'..Icons.Icon({spell.name, type=iconType, noicon=true})) | |||
table.insert(rowPart, '||data-sort-value="'..spell.level..'"|'..Icons._SkillReq('Magic', spell.level)) | |||
--Handle required items/dungeon clears | |||
if spell.requiredItem ~= nil and spell.requiredItem >= 0 then | |||
local reqItem = Items.getItemByID(spell.requiredItem) | |||
table.insert(rowPart, '<br/>'..Icons.Icon({reqItem.name, type='item', notext=true})..' equipped') | |||
end | |||
if spell.requiredDungeonCompletion ~= nil then | |||
local dung = Areas.getAreaByID('dungeon', spell.requiredDungeonCompletion[1]) | |||
table.insert(rowPart, '<br/>'..Icons.Icon({dung.name, type='dungeon', notext=true, qty=spell.requiredDungeonCompletion[2]})..' Clears') | |||
end | |||
table.insert(rowPart, '||data-sort-value="'..Magic.getSpellTypeIndex(spell.type)..'"|') | |||
table.insert(rowPart, Magic.getSpellTypeLink(spell.type)) | |||
table.insert(rowPart, '||'..Magic._getSpellStat(spell, 'description')) | |||
table.insert(rowPart, '||style="text-align:center"|') | |||
table.insert(rowPart, Magic._getSpellRunes(spell)) | |||
table.insert(resultPart, table.concat(rowPart)) | |||
end | |||
--Add the table end and add the table to the result string | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getSpellUseTable(frame) | function p.getSpellUseTable(frame) | ||
local itemName = frame.args ~= nil and frame.args[1] or frame | |||
local item = Items.getItem(itemName) | |||
if item == nil then | |||
return "ERROR: No item named "..itemName.." exists in the data module" | |||
end | |||
return p._getSpellUseTable(item) | |||
end | |||
--[==[ | |||
-- Uncomment this block and execute 'p.test()' within the debug console | |||
-- to test after making changes | |||
function p.test() | |||
local checkItems = { | |||
'Gold Bar', | |||
'Raw Shrimp', | |||
'Coal Ore', | |||
'Rune Platebody', | |||
'Arrow Shafts', | |||
'Garum Seeds', | |||
'Rune Essence', | |||
'Runite Bar', | |||
'Water Rune', | |||
'Steam Rune', | |||
'Controlled Heat Potion II', | |||
'Wolf', | |||
'Cyclops', | |||
'Leprechaun', | |||
'Redwood Logs', | |||
'Carrot Cake', | |||
'Carrot Cake (Perfect)', | |||
'Mantalyme Herb', | |||
'Carrot', | |||
'Topaz', | |||
'Rune Essence', | |||
'Infernal Claw', | |||
'Chapeau Noir', | |||
'Stardust', | |||
'Rope', | |||
'Ancient Ring of Mastery', | |||
'Mysterious Stone', | |||
'Mastery Token (Cooking)', | |||
'Gem Gloves', | |||
'Basic Bag' | |||
} | |||
local checkFuncs = { | |||
p.getItemUses, | |||
p.getItemUseTable | |||
} | |||
local errCount = 0 | |||
for i, item in ipairs(checkItems) do | |||
local param = {args={item}} | |||
mw.log('=' .. item .. '=') | |||
for j, func in ipairs(checkFuncs) do | |||
local callSuccess, retVal = pcall(func, param) | |||
if not callSuccess then | |||
errCount = errCount + 1 | |||
mw.log('Error with item "' .. item .. '": ' .. retVal) | |||
else | |||
mw.log(retVal) | |||
end | |||
end | |||
end | |||
if errCount == 0 then | |||
mw.log('Test successful') | |||
else | |||
mw.log('Test failed with ' .. errCount .. ' failures') | |||
end | |||
end | end | ||
--]==] | |||
return p | return p |