|
|
(2 intermediate revisions by one other user not shown) |
Line 1: |
Line 1: |
| local p = {}
| |
|
| |
|
| local ItemData = mw.loadData('Module:Sandbox/Items/data')
| |
| local SkillData = mw.loadData('Module:Sandbox/Skills/data')
| |
|
| |
| local Constants = require('Module:Constants')
| |
| local Shared = require('Module:Shared')
| |
| local Magic = require('Module:Magic')
| |
| local Areas = require('Module:Sandbox/CombatAreas')
| |
| local Items = require('Module:Sandbox/Items')
| |
| local Icons = require('Module:Icons')
| |
| local Agility = require('Module:Sandbox/Skills/Agility')
| |
| local Shop = require('Module:Sandbox/Shop')
| |
|
| |
| local SkillEnum = mw.loadData('Module:Constants/data').skill
| |
|
| |
| --Brute forcing some item uses to make things easier
| |
| local itemUseArray = {
| |
| Agility = {},
| |
| Astrology = {'Stardust', 'Golden Stardust'},
| |
| Attack = {},
| |
| Combat = {'Gold Emerald Ring'},
| |
| 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'},
| |
| 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 = {
| |
| [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)
| |
| -- 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' and skillUses[skillID] == nil then
| |
| skillUses[skillID] = Constants.getSkillName(skillID)
| |
| 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
| |
|
| |
| -- 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', '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 use, _ in Shared.skpairs(otherUses) do
| |
| table.insert(useArray, prefix .. (otherUseText[use] or use))
| |
| end
| |
| 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
| |
|
| |
| return table.concat(useArray, delim) .. (addCategories and table.concat(categoryArray, '') or '')
| |
| end
| |
|
| |
| 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
| |
|
| |
| 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, 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(item.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 useArray = nil
| |
| 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
| |
|
| |
| 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
| |
|
| |
| function p._getSpellUseTable(item)
| |
| local spellList = Magic.getSpellsForRune(item.id)
| |
| --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
| |
|
| |
| 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'
| |
| }
| |
| 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
| |
| --]==]
| |
|
| |
| return p
| |