Module:Items/UseTables
From Melvor Idle
< Module:Items
Revision as of 21:08, 6 March 2021 by Falterfire (talk | contribs) (Added Gloves of Silence to the list of things that can be used for Thieving)
Documentation for this module may be created at Module:Items/UseTables/doc
local p = {} local MonsterData = mw.loadData('Module:Monsters/data') local ItemData = mw.loadData('Module:Items/data') local SkillData = mw.loadData('Module:Skills/data') local Constants = mw.loadData('Module:Constants/data') local Shared = require('Module:Shared') local Magic = require('Module:Magic') local Areas = require('Module:CombatAreas') local Items = require('Module:Items') local Icons = require('Module:Icons') --Brute forcing some item uses to make things easier local itemUseArray = { Agility = {}, Combat = {}, Cooking = {'Cooking Gloves', 'Crown of Rhaelyx'}, Crafting = {'Crown of Rhaelyx'}, 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'}, Mining = {'Mining Gloves', 'Gem Gloves'}, Prayer = {}, Runecrafting = {'Crown of Rhaelyx'}, Slayer = {}, Smithing = {'Smithing Gloves', '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' } function p._getItemUses(item, asList, addCategories) local useArray = {} local categoryArray = {} local chr = asList and '* ' or '' --Another fun one. This time getting all the different possible ways an item can be used --Before anything else, if this is a potion add it to the appropriate override section if item.herbloreMasteryID ~= nil then table.insert(itemUseArray[potionUseArray[item.herbloreMasteryID]], item.name) end --First things added to the list are non-skill things that are easy to check if item.equipmentSlot ~= nil or Shared.contains(itemUseArray.Combat, item.name) then if item.equipmentSlot ~= nil then --table.insert(categoryArray, '[[Category:'..Items.getEquipmentSlotName(item.equipmentSlot)..' Slot Items]]') end table.insert(useArray, chr..Icons.Icon({'Combat'})) end if item.healsFor ~= nil then table.insert(categoryArray, '[[Category:Food Items]]') table.insert(useArray, chr..'[[Food]]') end if item.dropTable ~= nil then table.insert(categoryArray, '[[Category:Openable Items]]') table.insert(useArray, chr..'[[Chest Drop Tables|Can Be Opened]]') end --Next, upgrading, crafting, herblore, fletching, and runecrafting since we have to sift through other items for these local canUpgrade = false local canCraft = false local canFletch = false local canRunecraft = false local canHerblore = false if item.trimmedItemID ~= nil then canUpgrade = true else for i, item2 in pairs(ItemData.Items) do if item2.itemsRequired ~= nil then for j, req in pairs(item2.itemsRequired) do if req[1] == item.id then canUpgrade = true break end end end if item2.craftReq ~= nil then for j, req in pairs(item2.craftReq) do if req.id == item.id then canCraft = true break end end end if item2.fletchReq ~= nil then for j, req in pairs(item2.fletchReq) do if req.id == item.id then canFletch = true break end end end if item2.runecraftReq ~= nil then for j, req in pairs(item2.runecraftReq) do if req.id == item.id then canRunecraft = true break end end end if item2.herbloreReq ~= nil then for j, req in pairs(item2.herbloreReq) do if req.id == item.id then canHerblore = true break end end end end end if canUpgrade then if item.canUpgrade or (item.type == 'Armour' and item.canUpgrade == nil) then table.insert(categoryArray, '[[Category:Upgradeable Items]]') end table.insert(useArray, chr..'[[Upgrading Items]]') end --Agility if Shared.contains(itemUseArray.Agility, item.name) then table.insert(useArray, chr..Icons.Icon({'Agility', type='skill'})) end --Cooking if item.cookedItemID ~= nil or Shared.contains(itemUseArray.Cooking, item.name) then table.insert(useArray, chr..Icons.Icon({'Cooking', type='skill'})) end --Crafting if canCraft or Shared.contains(itemUseArray.Crafting, item.name) then table.insert(useArray, chr..Icons.Icon({'Crafting', type='skill'})) end --Farming if item.grownItemID ~= nil or Shared.contains(itemUseArray.Farming, item.name) then table.insert(useArray, chr..Icons.Icon({'Farming', type='skill'})) end --Firemaking if item.firemakingID ~= nil or Shared.contains(itemUseArray.Firemaking, item.name) then table.insert(useArray, chr..Icons.Icon({'Firemaking', type='skill'})) end --Fishing if Shared.contains(itemUseArray.Fishing, item.name) then table.insert(useArray, chr..Icons.Icon({'Fishing', type='skill'})) end --Fletching if canFletch or Shared.contains(itemUseArray.Fletching, item.name) then table.insert(useArray, chr..Icons.Icon({'Fletching', type='skill'})) end --Herblore if canHerblore or Shared.contains(itemUseArray.Herblore, item.name) then table.insert(useArray, chr..Icons.Icon({'Herblore', type='skill'})) end --Mining if Shared.contains(itemUseArray.Mining, item.name) then table.insert(useArray, chr..Icons.Icon({'Mining', type='skill'})) end --Prayer if item.prayerPoints ~= nil or Shared.contains(itemUseArray.Prayer, item.name) then if item.prayerPoints ~= nil then table.insert(categoryArray, '[[Category:Buriable Items]]') end table.insert(useArray, chr..Icons.Icon({'Prayer', type='skill'})) end --Runecrafting if canRunecraft or Shared.contains(itemUseArray.Runecrafting, item.name) then table.insert(useArray, chr..Icons.Icon({'Runecrafting', type='skill'})) end --Slayer if item.slayerCost ~= nil or Shared.contains(itemUseArray.Slayer, item.name) then table.insert(useArray, chr..Icons.Icon({'Slayer', type='skill'})) end --Smithing if item.type == 'Bar' or item.type == 'Ore' or Shared.contains(itemUseArray.Smithing, item.name) then table.insert(useArray, chr..Icons.Icon({'Smithing', type='skill'})) end --Thieving if Shared.contains(itemUseArray.Thieving, item.name) then table.insert(useArray, chr..Icons.Icon({'Thieving', type='skill'})) end --Woodcutting if Shared.contains(itemUseArray.Woodcutting, item.name) then table.insert(useArray, chr..Icons.Icon({'Woodcutting', type='skill'})) end --Other odds and ends: --Mastery Tokens are tied to 'Mastery' if item.type == 'Token' then table.insert(useArray, chr..Icons.Icon({'Mastery'})) end --Skillcapes are tied to the appropriate skill --Except Max 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', 'Hitpoints Skillcape', 'Defence Skillcape'} if item.name == 'Max Skillcape' or item.name == 'Aorpheat's Signet Ring' or item.name == 'Cape of Completion' then table.insert(useArray, chr..'All skills') elseif item.name == 'Magic Skillcape' then table.insert(useArray, chr..Icons.Icon({'Magic', type='skill'})) table.insert(useArray, chr..Icons.Icon({'Alt. Magic', type='skill'})) elseif Shared.contains(item.name, 'Skillcape') and not Shared.contains(ignoreCapes, item.name) then local skillName = Shared.splitString(item.name, ' ')[1] table.insert(useArray, chr..Icons.Icon({skillName, type='skill'})) 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 table.insert(useArray, chr..'Powering '..Icons.Icon({'Crown of Rhaelyx', type='item'})) end local result = table.concat(useArray,'\r\n') if addCategories then result = result..table.concat(categoryArray, '') end return result 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 = {} local potTierMastery = {[0] = 0, [1] = 20, [2] = 50, [3] = 90} --First, loop through all items to find anything that can be made or upgraded into using our source for i, item2 in pairs(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 = 'None' --Potions do have upgrade requirements though if item2.potionTier ~= nil then rowReq = Icons._MasteryReq(item2.name, potTierMastery[item2.potionTier]) end table.insert(useArray, {item = item2, qty = 1, mats = mat, skill = 'Upgrade', req = rowReq, xp = xp, gp = item2.trimmedGPCost}) break end end end if item.name == 'Leather' and item2.buysForLeather ~= nil then local mat = {{id = item.id, qty = item2.buysForLeather}} local xp = 'N/A' local rowReq = 'None' table.insert(useArray, {item = item2, qty = 1, mats = mat, skill = 'Shop', req = rowReq, xp = xp, gp = item2.buysFor}) elseif item2.buysForItems ~= nil then for j, req in pairs(item2.buysForItems) do if req[1] == item.id then local mat = item2.buysForItems local xp = 'N/A' local rowReq = 'None' table.insert(useArray, {item = item2, qty = 1, mats = mat, skill = 'Shop', req = rowReq, xp = xp, gp = item2.buysForGP}) break end end end if item2.craftReq ~= nil then for j, req in pairs(item2.craftReq) do if req.id == item.id then local mat = item2.craftReq local xp = item2.craftingXP local rowReq = item2.craftingLevel local qty = item2.craftQty table.insert(useArray, {item = item2, qty = qty, mats = mat, skill = 'Crafting', req = rowReq, xp = xp}) break end end end if item2.fletchReq ~= nil then for j, req in pairs(item2.fletchReq) do if req.id == item.id then local xp = item2.fletchingXP local rowReq = item2.fletchingLevel --Arrow Shafts are special and have to be treated specially local qty = item2.fletchQty local mat = item2.fletchReq if item2.name == 'Arrow Shafts' then mat = {{id = item.id, qty = 1}} qty = qty + (qty * item.id) end table.insert(useArray, {item = item2, qty = qty, mats = mat, skill = 'Fletching', req = rowReq, xp = xp}) break end end end if item2.smithReq ~= nil then for j, req in pairs(item2.smithReq) do if req.id == item.id then local mat = item2.smithReq local xp = item2.smithingXP local rowReq = item2.smithingLevel local qty = item2.smithingQty table.insert(useArray, {item = item2, qty = qty, mats = mat, skill = 'Smithing', req = rowReq, xp = xp}) break end end end if item2.runecraftReq ~= nil then for j, req in pairs(item2.runecraftReq) do if req.id == item.id then local mat = item2.runecraftReq local xp = item2.runecraftingXP local rowReq = item2.runecraftingLevel local qty = item2.runecraftQty table.insert(useArray, {item = item2, qty = qty, mats = mat, skill = 'Runecrafting', req = rowReq, xp = xp}) break end end end if item2.herbloreReq ~= nil then for j, req in pairs(item2.herbloreReq) do if req.id == item.id then local potionData = SkillData.Herblore.ItemData[item2.herbloreMasteryID + 1] local mat = item2.herbloreReq local xp = potionData.herbloreXP --Potions do have upgrade requirements though local rowReq = Icons._SkillReq('Herblore', potionData.herbloreLevel) local masteryLvl = potTierMastery[item2.potionTier] if masteryLvl > 0 then rowReq = rowReq..'<br/>'..Icons._MasteryReq(item2.name, masteryLvl) end local reqVal = potionData.herbloreLevel + (masteryLvl * 0.01) table.insert(useArray, {item = item2, qty = 1, mats = mat, skill = 'Herblore', reqVal = reqVal, req = rowReq, xp = xp}) break end end end end 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 = 5 table.insert(useArray, {item = item2, qty = qty, mats = mat, skill = 'Farming', req = rowReq, xp = xp}) end if item.cookedItemID ~= nil then local item2 = Items.getItemByID(item.cookedItemID) local mat = {{id = item.id, qty = 1}} local xp = item.cookingXP local rowReq = item.cookingLevel local qty = 1 table.insert(useArray, {item = item2, qty = qty, mats = mat, skill = 'Cooking', req = rowReq, xp = xp}) end if item.burntItemID ~= nil then local item2 = Items.getItemByID(item.burntItemID) local mat = {{id = item.id, qty = 1}} local xp = 1 local rowReq = item.cookingLevel local qty = 1 table.insert(useArray, {item = item2, qty = qty, mats = mat, skill = 'Cooking', req = rowReq, xp = xp}) 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 spellUseTable = p._getSpellUseTable(item) local result = '' if Shared.tableCount(useArray) == 0 then if string.len(spellUseTable) > 0 then return '==Uses==\r\n==='..Icons.Icon({'Magic', type='skill', size='30'})..'===\r\n'..spellUseTable else return '' end end result = result..'{| class="wikitable sortable"' result = result..'\r\n!colspan=2|Item Created!!Type!!Requirements!!XP!!Ingredients' for i, row in pairs(useArray) do local qty = row.qty ~= nil and row.qty or 1 result = result..'\r\n|-\r\n|data-sort-value="'..row.item.name..'"|' result = result..Icons.Icon({row.item.name, type='item', notext=true, size=50})..'||' if qty > 1 then result = result.."'''"..qty.."x''' " end result = result..'[['..row.item.name..']]' if row.skill == 'Upgrade' then result = result..'||data-sort-value="Upgrade"|[[Upgrading Items|Upgrade]]' elseif row.skill == 'Shop' then result = result..'||data-sort-value="Shop"|[[Shop]]' else result = result..'||data-sort-value="'..row.skill..'"|'..Icons.Icon({row.skill, type='skill'}) end if type(row.req) == 'number' then result = result..'|| data-sort-value="'..row.req..'"|'..Icons._SkillReq(row.skill, row.req) elseif row.reqVal ~= nil then result = result..'|| data-sort-value="'..row.reqVal..'"|'..row.req else result = result..'||'..row.req end if type(row.xp) == 'string' then result = result..'||data-sort-value="0"|'..row.xp else result = result..'||data-sort-value="'..row.xp..'"|'..row.xp..' '..Icons.Icon({row.skill, type='skill', notext=true})..' XP' end result = result..'||' for i, mat in Shared.skpairs(row.mats) do local matID = mat.id ~= nil and mat.id or mat[1] local matQty = mat.qty ~= nil and mat.qty or mat[2] matItem = Items.getItemByID(matID) if i > 1 then result = result..'<br/>' end result = result..Icons.Icon({matItem.name, type='item', qty=matQty}) end if row.gp ~= nil then result = result..'<br/>'..Icons.GP(row.gp) end end result = result..'\r\n|}' if string.len(spellUseTable) > 0 then result = result..'\r\n==='..Icons.Icon({'Magic', type='skill', size='30'})..'===\r\n'..spellUseTable end return '==Uses==\r\n'..result 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 result = '{|class="wikitable sortable"\r\n!colspan="2"|Spell' result = result..'!!Requirements' result = result..'!!Type!!style="width:275px"|Description' result = result..'!!Runes' for i, spell in pairs(spellList) do local rowTxt = '\r\n|-\r\n|data-sort-value="'..spell.name..'"|' if spell.type == 'Auroras' then rowTxt = rowTxt..Icons.Icon({spell.name, type='aurora', notext=true, size=50}) elseif spell.type == 'Curses' then rowTxt = rowTxt..Icons.Icon({spell.name, type='curse', notext=true, size=50}) else rowTxt = rowTxt..Icons.Icon({spell.name, type='spell', notext=true, size=50}) end rowTxt = rowTxt..'||[['..spell.name..']]' rowTxt = rowTxt..'||data-sort-value="'..spell.magicLevelRequired..'"|'..Icons._SkillReq('Magic', spell.magicLevelRequired) --Handle required items/dungeon clears if spell.requiredItem ~= nil and spell.requiredItem >= 0 then local reqItem = Items.getItemByID(spell.requiredItem) rowTxt = rowTxt..'<br/>'..Icons.Icon({reqItem.name, type='item', notext=true})..' equipped' end if spell.requiredDungeonCompletion ~= nil then local dung = Areas.getAreaByID('dungeon', spell.requiredDungeonCompletion[1]) rowTxt = rowTxt..'<br/>'..Icons.Icon({dung.name, type='dungeon', notext=true, qty=spell.requiredDungeonCompletion[2]})..' Clears' end rowTxt = rowTxt..'||data-sort-value="'..Magic.getSpellTypeIndex(spell.type)..'"|' rowTxt = rowTxt..Magic.getSpellTypeLink(spell.type) if spell.type == 'Spells' then rowTxt = rowTxt..'||Combat spell with a max hit of '..(spell.maxHit * 10) else rowTxt = rowTxt..'||'..spell.description end rowTxt = rowTxt..'||style="text-align:center"|' rowTxt = rowTxt..Magic._getSpellRunes(spell) result = result..rowTxt end --Add the table end and add the table to the result string result = result..'\r\n|}' return result 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 return p