Module:Navboxes: Difference between revisions
From Melvor Idle
(getPotionNavbox: Link to general potion pages rather than tier I potion specifically) |
(Use tabs instead of spaces for indentation) |
||
Line 13: | Line 13: | ||
function p.getFarmingNavbox(frame) | function p.getFarmingNavbox(frame) | ||
local resultPart = {} | |||
local seedsTable = {} | |||
local produceTable = {} | |||
for i, item in ipairs(ItemData.Items) do | |||
if item.farmingLevel ~= nil then | |||
local tier = item.tier | |||
if seedsTable[tier] == nil then | |||
-- Initialise tier tables | |||
seedsTable[tier] = {} | |||
produceTable[tier] = {} | |||
end | |||
if item.grownItemID ~= nil then | |||
local grownItem = Items.getItemByID(item.grownItemID) | |||
if grownItem ~= nil then | |||
table.insert(produceTable[tier], { ["name"] = grownItem.name, ["level"] = item.farmingLevel }) | |||
end | |||
end | |||
table.insert(seedsTable[tier], { ["name"] = item.name, ["level"] = item.farmingLevel }) | |||
end | |||
end | |||
-- Generate output table | |||
table.insert(resultPart, '{| class="wikitable mw-collapsible" style="margin:auto; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n!colspan="2" style="padding-left:64px;"|' .. Icons.Icon({'Farming', type='skill'})) | |||
local getItemList = function(itemTable) | |||
local listPart = {} | |||
for i, item in ipairs(itemTable) do | |||
table.insert(listPart, Icons.Icon({item.name, type='item'})) | |||
end | |||
return table.concat(listPart, ' • ') | |||
end | |||
local sortFunc = function(a, b) return (a.level == b.level and a.name < b.name) or a.level < b.level end | |||
-- Determine tier list & order in which tiers will be listed in output | |||
local tierList = {} | |||
for tier, seeds in pairs(seedsTable) do | |||
table.insert(tierList, tier) | |||
end | |||
table.sort(tierList, function(a, b) return a < b end) | |||
-- Generate table section for each tier | |||
for i, tier in pairs(tierList) do | |||
-- Sort tables by Farming level order | |||
table.sort(seedsTable[tier], sortFunc) | |||
table.sort(produceTable[tier], sortFunc) | |||
table.insert(resultPart, '\r\n|-\r\n!colspan="2"| ' .. tier .. 's') | |||
table.insert(resultPart, '\r\n|-\r\n!scope="row"| Seeds') | |||
table.insert(resultPart, '\r\n|style="text-align:center;"| ' .. getItemList(seedsTable[tier])) | |||
table.insert(resultPart, '\r\n|-\r\n!scope="row"| Produce') | |||
table.insert(resultPart, '\r\n|style="text-align:center;"| ' .. getItemList(produceTable[tier])) | |||
end | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getFoodNavbox(frame) | function p.getFoodNavbox(frame) | ||
local foundIDs, cookedFood, harvestedFood, otherFood = {}, {}, {}, {} | |||
-- Hide Lemon cake | |||
foundIDs[1029] = true | |||
foundIDs[1061] = true | |||
-- Harvested food first | |||
for i, item in ipairs(ItemData.Items) do | |||
if item.grownItemID ~= nil then | |||
local grownItem = Items.getItemByID(item.grownItemID) | |||
if grownItem ~= nil and grownItem.canEat then | |||
table.insert(harvestedFood, { ["name"] = grownItem.name, ["order"] = item.farmingLevel }) | |||
foundIDs[grownItem.id] = true | |||
end | |||
end | |||
end | |||
-- Any cooked & other food | |||
for i, item in ipairs(ItemData.Items) do | |||
-- If an item can be eaten then it must be food | |||
if foundIDs[i - 1] == nil and item.canEat then | |||
if item.cookingCategory ~= nil then | |||
-- Item is cooked, such food items are split by category | |||
if cookedFood[item.cookingCategory + 1] == nil then | |||
cookedFood[item.cookingCategory + 1] = {} | |||
end | |||
local perfectName = nil | |||
if item.perfectItem ~= nil then | |||
local perfectItem = Items.getItemByID(item.perfectItem) | |||
if perfectItem ~= nil then | |||
perfectName = perfectItem.name | |||
foundIDs[item.perfectItem] = true | |||
end | |||
end | |||
table.insert(cookedFood[item.cookingCategory + 1], { ["name"] = item.name, ["order"] = item.cookingLevel, ["perfectName"] = perfectName }) | |||
else | |||
-- Item cannot be cooked or grown, but can be eaten | |||
table.insert(otherFood, { ["name"] = item.name, ["order"] = item.id }) | |||
end | |||
foundIDs[i - 1] = true | |||
end | |||
end | |||
-- Sort food lists | |||
local sortFunc = function(a, b) return (a.order == b.order and a.name < b.name) or a.order < b.order end | |||
for i, items in pairs(cookedFood) do | |||
table.sort(cookedFood[i], sortFunc) | |||
end | |||
table.sort(harvestedFood, sortFunc) | |||
table.sort(otherFood, sortFunc) | |||
-- Generate food lists for final output | |||
local cookingCatHeader = { | |||
Icons.Icon({'Normal Cooking Fire', 'Cooking Fire', type='upgrade', nolink=true}), | |||
Icons.Icon({'Basic Furnace', 'Furnace', type='upgrade', nolink=true}), | |||
Icons.Icon({'Basic Pot', 'Pot', type='upgrade', nolink=true}) | |||
} | |||
local getFoodList = function(foodTable) | |||
local listPart = {} | |||
for i, food in ipairs(foodTable) do | |||
local foodText = Icons.Icon({food.name, type='item'}) | |||
if food.perfectName ~= nil then | |||
foodText = Icons.Icon({food.perfectName, type='item', notext=true}) .. ' ' .. foodText | |||
end | |||
table.insert(listPart, foodText) | |||
end | |||
return table.concat(listPart, ' • ') | |||
end | |||
local resultPart = {} | |||
table.insert(resultPart, '{| class="wikitable mw-collapsible" style="margin:0 auto 10px; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n|-\r\n!style="background-color:#275C87;color:#FFFFFF;padding-left:64px;" colspan="2"| [[File:Crab_(item).svg|25px|link=Food]] [[Food]]') | |||
table.insert(resultPart, '\r\n|-\r\n!colspan="2"| Cooked') | |||
for catID, foodTable in ipairs(cookedFood) do | |||
table.insert(resultPart, '\r\n|-\r\n!scope="row"| ' .. cookingCatHeader[catID]) | |||
table.insert(resultPart, '\r\n|style="text-align:center;"| ' .. getFoodList(foodTable)) | |||
end | |||
table.insert(resultPart, '\r\n|-\r\n!colspan="2"| Harvested') | |||
table.insert(resultPart, '\r\n|-\r\n|colspan="2" style="text-align:center;"| ' .. getFoodList(harvestedFood)) | |||
table.insert(resultPart, '\r\n|-\r\n!colspan="2"| Other') | |||
table.insert(resultPart, '\r\n|-\r\n|colspan="2" style="text-align:center;"| ' .. getFoodList(otherFood)) | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getPotionNavbox(frame) | function p.getPotionNavbox(frame) | ||
local catList = { | |||
{ ["categoryID"] = 0, ["name"] = 'Combat' }, | |||
{ ["categoryID"] = 1, ["name"] = 'Skill' } | |||
} | |||
table.sort(catList, function(a, b) return a.name < b.name end) | |||
-- Compile list of potions to be included | |||
local potList = {} | |||
for i, potData in ipairs(SkillData.Herblore.ItemData) do | |||
if potList[potData.category] == nil then | |||
potList[potData.category] = {} | |||
end | |||
local potFirstItem = Items.getItemByID(potData.itemID[1]) | |||
local potName = string.gsub(potFirstItem.name, ' Potion [IV]+$', '') | |||
table.insert(potList[potData.category], { ["name"] = potName, ["order"] = potData.level, ["img"] = potFirstItem.name }) | |||
end | |||
local resultPart = {} | |||
-- Generate table header | |||
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n!colspan=2|' .. Icons.Icon({ 'Herblore', 'Potions', type='skill' })) | |||
-- Generate section for each category of potions | |||
for i, catData in ipairs(catList) do | |||
-- Compile list of potions | |||
local potListText = {} | |||
table.sort(potList[catData.categoryID], function(a, b) return (a.order == b.order and a.name < b.name) or a.order < b.order end) | |||
for j, potData in ipairs(potList[catData.categoryID]) do | |||
table.insert(potListText, Icons.Icon({ potData.name .. ' Potion', potData.name, img=potData.img, type='item' })) | |||
end | |||
table.insert(resultPart, '\r\n|-\r\n! ' .. catData.name .. ' Potions') | |||
table.insert(resultPart, '\r\n|class="center" style="vertical-align:middle;"| ' .. table.concat(potListText, ' • ')) | |||
end | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getPrayerNavbox(frame) | function p.getPrayerNavbox(frame) | ||
local prayerList = {} | |||
for i, prayer in Shared.skpairs(SkillData.Prayer) do | |||
table.insert(prayerList, { ["name"] = prayer.name, ["order"] = prayer.prayerLevel }) | |||
end | |||
table.sort(prayerList, function(a, b) | |||
if a.order == b.order then | |||
return a.name < b.name | |||
else | |||
return a.order < b.order | |||
end | |||
end) | |||
local prayerListText = {} | |||
for i, prayer in ipairs(prayerList) do | |||
table.insert(prayerListText, Icons.Icon({ prayer.name, type='prayer' })) | |||
end | |||
local resultPart = {} | |||
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n!'..Icons.Icon({'Prayer', 'Prayers', type='skill'})) | |||
table.insert(resultPart, '\r\n|-\r\n|style="text-align:center;"| ' .. table.concat(prayerListText, ' • ')) | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getRuneNavbox(frame) | function p.getRuneNavbox(frame) | ||
-- Assumes all runes are from Runecrafting, which may need revising in future updates | |||
local runeList = { ["Standard"] = {}, ["Combination"] = {} } | |||
for i, item in ipairs(ItemData.Items) do | |||
if item.category == 'Runecrafting' and item.type ~= nil and item.type == 'Rune' and item.runecraftingLevel ~= nil then | |||
local runeType = (type(item.providesRune) == 'table' and Shared.tableCount(item.providesRune) > 1 and 'Combination') or 'Standard' | |||
table.insert(runeList[runeType], { ["name"] = item.name, ["order"] = item.runecraftingLevel }) | |||
end | |||
end | |||
local resultPart = {} | |||
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n!colspan="2"|[[File:Air_Rune_(item).svg|25px|link=Runes]] [[Runes]]') | |||
for i, cat in ipairs({'Standard', 'Combination'}) do | |||
table.sort(runeList[cat], function(a, b) return (a.order == b.order and a.name < b.name) or a.order < b.order end) | |||
table.insert(resultPart, '\r\n|-\r\n!scope="row"|' .. cat .. ' Runes') | |||
local listPart = {} | |||
for j, rune in ipairs(runeList[cat]) do | |||
table.insert(listPart, Icons.Icon({rune.name, type='item'})) | |||
end | |||
table.insert(resultPart, '\r\n|style="text-align:center;"|'..table.concat(listPart, ' • ')) | |||
end | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getSkillcapeNavbox(frame) | function p.getSkillcapeNavbox(frame) | ||
local capeList = Shop.getPurchases(function(cat, purch) return cat == 'Skillcapes' end) | |||
table.sort(capeList, function(a, b) | |||
if a.cost.gp == b.cost.gp then | |||
return a.name < b.name | |||
else | |||
return a.cost.gp < b.cost.gp | |||
end | |||
end) | |||
local capeText = {} | |||
for i, purch in ipairs(capeList) do | |||
if purch.contains ~= nil and purch.contains.items ~= nil then | |||
local item = Items.getItemByID(purch.contains.items[1][1]) | |||
if item ~= nil then | |||
table.insert(capeText, Icons.Icon({item.name, type='item'})) | |||
end | |||
end | |||
end | |||
local resultPart = {} | |||
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n![[File:Cape_of_Completion_(item).svg|25px|link=Skillcapes]] [[Skillcapes]]') | |||
table.insert(resultPart, '\r\n|-\r\n|style="text-align:center;"|'..table.concat(capeText, ' • ')) | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getSpellNavbox(frame) | function p.getSpellNavbox(frame) | ||
local spellTable = { ["standard"] = {}, ["curse"] = {}, ["aurora"] = {}, ["ancient"] = {}, ["alt"] = {} } | |||
local catData = { | |||
{ ["name"] = 'standard', ["header"] = '[[Magic#Standard_Magic|Standard Spells]]', ["imgType"] = 'spell' }, | |||
{ ["name"] = 'curse', ["header"] = '[[Magic#Curses|Curses]]', ["imgType"] = 'curse' }, | |||
{ ["name"] = 'aurora', ["header"] = '[[Magic#Auroras|Auroras]]', ["imgType"] = 'aurora' }, | |||
{ ["name"] = 'ancient', ["header"] = '[[Magic#Ancient_Magicks|Ancient Magicks]]', ["imgType"] = 'spell' }, | |||
{ ["name"] = 'alt', ["header"] = '[[Alternative_Magic|Alt Magic]]', ["imgType"] = 'spell' }, | |||
} | |||
for i, spell in ipairs(MagicData.Spells) do | |||
table.insert(spellTable['standard'], { ["name"] = spell.name, ["order"] = spell.level }) | |||
end | |||
for i, spell in ipairs(MagicData.Curses) do | |||
table.insert(spellTable['curse'], { ["name"] = spell.name, ["order"] = spell.level }) | |||
end | |||
for i, spell in ipairs(MagicData.Auroras) do | |||
table.insert(spellTable['aurora'], { ["name"] = spell.name, ["order"] = spell.level }) | |||
end | |||
for i, spell in ipairs(MagicData.Ancient) do | |||
table.insert(spellTable['ancient'], { ["name"] = spell.name, ["order"] = spell.level }) | |||
end | |||
for i, spell in ipairs(MagicData.AltMagic) do | |||
table.insert(spellTable['alt'], { ["name"] = spell.name, ["order"] = spell.level }) | |||
end | |||
local getSpellList = function(spellTable, imgType) | |||
local listPart = {} | |||
for i, obj in ipairs(spellTable) do | |||
table.insert(listPart, Icons.Icon({obj.name, type=imgType})) | |||
end | |||
return table.concat(listPart, ' • ') | |||
end | |||
local resultPart = {} | |||
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n!colspan=2|[[File:Magic_(skill).svg|25px|link=Spells]] [[Spells]]') | |||
for i, catDefn in ipairs(catData) do | |||
table.sort(spellTable[catDefn.name], function(a, b) | |||
if a.order == b.order then | |||
return a.name < b.name | |||
else | |||
return a.order < b.order | |||
end | |||
end) | |||
table.insert(resultPart, '\r\n|-\r\n!scope="row"| ' .. catDefn.header) | |||
table.insert(resultPart, '\r\n|style="text-align:center;| ' .. getSpellList(spellTable[catDefn.name], catDefn.imgType)) | |||
end | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
function p.getFamiliarNavbox(frame) | function p.getFamiliarNavbox(frame) | ||
local familiars = Items.getItems(function(item) return item.type == 'Familiar' end) | |||
table.sort(familiars, function(a, b) return a.summoningLevel < b.summoningLevel end) | |||
local result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"' | |||
result = result..'\r\n!colspan=2|[[File:Summoning_(skill).svg|25px|link=Summoning]] [[Summoning|Summoning Familiars]]' | |||
local iconArray = {} | |||
for i, fam in Shared.skpairs(familiars) do | |||
table.insert(iconArray, Icons.Icon({fam.name, type='item'})) | |||
end | |||
result = result..'\r\n|-\r\n|style="text-align:center;"|'..table.concat(iconArray, ' • ') | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p.getThievingNavbox() | function p.getThievingNavbox() | ||
local returnPart = {} | |||
-- Create table header | |||
table.insert(returnPart, '{| class="wikitable" style="text-align:center; clear:both; margin:auto; margin-bottom:1em;"') | |||
table.insert(returnPart, '|-\r\n!' .. Icons.Icon({'Thieving', type='skill', notext=true}) .. '[[Thieving|Thieving Targets]]') | |||
table.insert(returnPart, '|-\r\n|') | |||
local npcData = {} | |||
for i, npc in ipairs(SkillData.Thieving.NPCs) do | |||
table.insert(npcData, {["level"] = npc.level, ["name"] = npc.name}) | |||
end | |||
table.sort(npcData, function(a, b) return a.level < b.level end) | |||
local npcList = {} | |||
-- Create row for each NPC | |||
for i, npc in ipairs(npcData) do | |||
table.insert(npcList, Icons.Icon({npc.name, type='thieving'})) | |||
end | |||
table.insert(returnPart, table.concat(npcList, ' • ')) | |||
table.insert(returnPart, '|}') | |||
return table.concat(returnPart, '\r\n') | |||
end | end | ||
function p.getFishingNavbox() | function p.getFishingNavbox() | ||
local categoryHeader = {} | |||
local categoryItems = {} | |||
local addCatData = function(cat, catLink, itemName, itemOrder) | |||
if categoryItems[cat] == nil then | |||
-- Initialise category | |||
table.insert(categoryHeader, { ["name"] = cat, ["link"] = catLink }) | |||
categoryItems[cat] = {} | |||
end | |||
table.insert(categoryItems[cat], { ["name"] = itemName, ["order"] = itemOrder }) | |||
end | |||
-- Identify fishing catchable items | |||
local fishingToItemID = {} | |||
local junkItems = {} | |||
local specialItems = {} | |||
for i, item in ipairs(ItemData.Items) do | |||
if item.fishingID ~= nil then | |||
-- Create FishingID to item map | |||
fishingToItemID[item.fishingID] = item | |||
elseif item.category == 'Fishing' and item.type == 'Junk' then | |||
table.insert(junkItems, item) | |||
elseif item.fishingCatchWeight ~= nil then | |||
table.insert(specialItems, item) | |||
end | |||
end | |||
-- Fishing areas | |||
-- Iterate through all fishing areas, identifying fish within each | |||
for i, area in ipairs(SkillData.Fishing.Areas) do | |||
for j, fishID in ipairs(area.fish) do | |||
local fishItem = fishingToItemID[fishID] | |||
if fishItem ~= nil then | |||
addCatData(area.name, 'Fishing#Fishing Areas', fishItem.name, fishItem.fishingLevel) | |||
end | |||
end | |||
end | |||
-- Junk items | |||
for i, item in ipairs(junkItems) do | |||
addCatData('Junk', 'Fishing#Junk', item.name, 1) | |||
end | |||
-- Special items | |||
for i, item in ipairs(specialItems) do | |||
addCatData('Special Items', 'Fishing#Special', item.name, 1 / (item.fishingCatchWeight or 1)) | |||
end | |||
local resultPart = {} | |||
-- Generate navbox header | |||
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"') | |||
table.insert(resultPart, '\r\n|-\r\n!colspan="2" | ' .. Icons.Icon({'Fishing', type='skill'})) | |||
-- Generate section for each fishing area, junk, and special | |||
for i, cat in ipairs(categoryHeader) do | |||
local itemList = {} | |||
if categoryItems[cat.name] ~= nil then | |||
table.sort(categoryItems[cat.name], function(a, b) return (a.order == b.order and a.name < b.name) or a.order < b.order end) | |||
for j, item in ipairs(categoryItems[cat.name]) do | |||
table.insert(itemList, Icons.Icon({item.name, type='item'})) | |||
end | |||
end | |||
table.insert(resultPart, '\r\n|-\r\n!class="center" style="min-width:140px" | [[' .. (cat.link or cat.name) .. '|' .. cat.name .. ']]') | |||
table.insert(resultPart, '\r\n| class="center" style="vertical-align:middle;" | ' .. table.concat(itemList, ' • ')) | |||
end | |||
table.insert(resultPart, '\r\n|}') | |||
return table.concat(resultPart) | |||
end | end | ||
return p | return p |
Revision as of 22:21, 6 January 2022
Documentation for this module may be created at Module:Navboxes/doc
-- New module to stop navbox generators cluttering other modules
local p = {}
local SkillData = mw.loadData('Module:Skills/data')
local MagicData = mw.loadData('Module:Magic/data')
local ItemData = mw.loadData('Module:Items/data')
local Shared = require('Module:Shared')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Shop = require('Module:Shop')
function p.getFarmingNavbox(frame)
local resultPart = {}
local seedsTable = {}
local produceTable = {}
for i, item in ipairs(ItemData.Items) do
if item.farmingLevel ~= nil then
local tier = item.tier
if seedsTable[tier] == nil then
-- Initialise tier tables
seedsTable[tier] = {}
produceTable[tier] = {}
end
if item.grownItemID ~= nil then
local grownItem = Items.getItemByID(item.grownItemID)
if grownItem ~= nil then
table.insert(produceTable[tier], { ["name"] = grownItem.name, ["level"] = item.farmingLevel })
end
end
table.insert(seedsTable[tier], { ["name"] = item.name, ["level"] = item.farmingLevel })
end
end
-- Generate output table
table.insert(resultPart, '{| class="wikitable mw-collapsible" style="margin:auto; clear:both; width: 100%"')
table.insert(resultPart, '\r\n!colspan="2" style="padding-left:64px;"|' .. Icons.Icon({'Farming', type='skill'}))
local getItemList = function(itemTable)
local listPart = {}
for i, item in ipairs(itemTable) do
table.insert(listPart, Icons.Icon({item.name, type='item'}))
end
return table.concat(listPart, ' • ')
end
local sortFunc = function(a, b) return (a.level == b.level and a.name < b.name) or a.level < b.level end
-- Determine tier list & order in which tiers will be listed in output
local tierList = {}
for tier, seeds in pairs(seedsTable) do
table.insert(tierList, tier)
end
table.sort(tierList, function(a, b) return a < b end)
-- Generate table section for each tier
for i, tier in pairs(tierList) do
-- Sort tables by Farming level order
table.sort(seedsTable[tier], sortFunc)
table.sort(produceTable[tier], sortFunc)
table.insert(resultPart, '\r\n|-\r\n!colspan="2"| ' .. tier .. 's')
table.insert(resultPart, '\r\n|-\r\n!scope="row"| Seeds')
table.insert(resultPart, '\r\n|style="text-align:center;"| ' .. getItemList(seedsTable[tier]))
table.insert(resultPart, '\r\n|-\r\n!scope="row"| Produce')
table.insert(resultPart, '\r\n|style="text-align:center;"| ' .. getItemList(produceTable[tier]))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getFoodNavbox(frame)
local foundIDs, cookedFood, harvestedFood, otherFood = {}, {}, {}, {}
-- Hide Lemon cake
foundIDs[1029] = true
foundIDs[1061] = true
-- Harvested food first
for i, item in ipairs(ItemData.Items) do
if item.grownItemID ~= nil then
local grownItem = Items.getItemByID(item.grownItemID)
if grownItem ~= nil and grownItem.canEat then
table.insert(harvestedFood, { ["name"] = grownItem.name, ["order"] = item.farmingLevel })
foundIDs[grownItem.id] = true
end
end
end
-- Any cooked & other food
for i, item in ipairs(ItemData.Items) do
-- If an item can be eaten then it must be food
if foundIDs[i - 1] == nil and item.canEat then
if item.cookingCategory ~= nil then
-- Item is cooked, such food items are split by category
if cookedFood[item.cookingCategory + 1] == nil then
cookedFood[item.cookingCategory + 1] = {}
end
local perfectName = nil
if item.perfectItem ~= nil then
local perfectItem = Items.getItemByID(item.perfectItem)
if perfectItem ~= nil then
perfectName = perfectItem.name
foundIDs[item.perfectItem] = true
end
end
table.insert(cookedFood[item.cookingCategory + 1], { ["name"] = item.name, ["order"] = item.cookingLevel, ["perfectName"] = perfectName })
else
-- Item cannot be cooked or grown, but can be eaten
table.insert(otherFood, { ["name"] = item.name, ["order"] = item.id })
end
foundIDs[i - 1] = true
end
end
-- Sort food lists
local sortFunc = function(a, b) return (a.order == b.order and a.name < b.name) or a.order < b.order end
for i, items in pairs(cookedFood) do
table.sort(cookedFood[i], sortFunc)
end
table.sort(harvestedFood, sortFunc)
table.sort(otherFood, sortFunc)
-- Generate food lists for final output
local cookingCatHeader = {
Icons.Icon({'Normal Cooking Fire', 'Cooking Fire', type='upgrade', nolink=true}),
Icons.Icon({'Basic Furnace', 'Furnace', type='upgrade', nolink=true}),
Icons.Icon({'Basic Pot', 'Pot', type='upgrade', nolink=true})
}
local getFoodList = function(foodTable)
local listPart = {}
for i, food in ipairs(foodTable) do
local foodText = Icons.Icon({food.name, type='item'})
if food.perfectName ~= nil then
foodText = Icons.Icon({food.perfectName, type='item', notext=true}) .. ' ' .. foodText
end
table.insert(listPart, foodText)
end
return table.concat(listPart, ' • ')
end
local resultPart = {}
table.insert(resultPart, '{| class="wikitable mw-collapsible" style="margin:0 auto 10px; clear:both; width: 100%"')
table.insert(resultPart, '\r\n|-\r\n!style="background-color:#275C87;color:#FFFFFF;padding-left:64px;" colspan="2"| [[File:Crab_(item).svg|25px|link=Food]] [[Food]]')
table.insert(resultPart, '\r\n|-\r\n!colspan="2"| Cooked')
for catID, foodTable in ipairs(cookedFood) do
table.insert(resultPart, '\r\n|-\r\n!scope="row"| ' .. cookingCatHeader[catID])
table.insert(resultPart, '\r\n|style="text-align:center;"| ' .. getFoodList(foodTable))
end
table.insert(resultPart, '\r\n|-\r\n!colspan="2"| Harvested')
table.insert(resultPart, '\r\n|-\r\n|colspan="2" style="text-align:center;"| ' .. getFoodList(harvestedFood))
table.insert(resultPart, '\r\n|-\r\n!colspan="2"| Other')
table.insert(resultPart, '\r\n|-\r\n|colspan="2" style="text-align:center;"| ' .. getFoodList(otherFood))
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getPotionNavbox(frame)
local catList = {
{ ["categoryID"] = 0, ["name"] = 'Combat' },
{ ["categoryID"] = 1, ["name"] = 'Skill' }
}
table.sort(catList, function(a, b) return a.name < b.name end)
-- Compile list of potions to be included
local potList = {}
for i, potData in ipairs(SkillData.Herblore.ItemData) do
if potList[potData.category] == nil then
potList[potData.category] = {}
end
local potFirstItem = Items.getItemByID(potData.itemID[1])
local potName = string.gsub(potFirstItem.name, ' Potion [IV]+$', '')
table.insert(potList[potData.category], { ["name"] = potName, ["order"] = potData.level, ["img"] = potFirstItem.name })
end
local resultPart = {}
-- Generate table header
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"')
table.insert(resultPart, '\r\n!colspan=2|' .. Icons.Icon({ 'Herblore', 'Potions', type='skill' }))
-- Generate section for each category of potions
for i, catData in ipairs(catList) do
-- Compile list of potions
local potListText = {}
table.sort(potList[catData.categoryID], function(a, b) return (a.order == b.order and a.name < b.name) or a.order < b.order end)
for j, potData in ipairs(potList[catData.categoryID]) do
table.insert(potListText, Icons.Icon({ potData.name .. ' Potion', potData.name, img=potData.img, type='item' }))
end
table.insert(resultPart, '\r\n|-\r\n! ' .. catData.name .. ' Potions')
table.insert(resultPart, '\r\n|class="center" style="vertical-align:middle;"| ' .. table.concat(potListText, ' • '))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getPrayerNavbox(frame)
local prayerList = {}
for i, prayer in Shared.skpairs(SkillData.Prayer) do
table.insert(prayerList, { ["name"] = prayer.name, ["order"] = prayer.prayerLevel })
end
table.sort(prayerList, function(a, b)
if a.order == b.order then
return a.name < b.name
else
return a.order < b.order
end
end)
local prayerListText = {}
for i, prayer in ipairs(prayerList) do
table.insert(prayerListText, Icons.Icon({ prayer.name, type='prayer' }))
end
local resultPart = {}
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"')
table.insert(resultPart, '\r\n!'..Icons.Icon({'Prayer', 'Prayers', type='skill'}))
table.insert(resultPart, '\r\n|-\r\n|style="text-align:center;"| ' .. table.concat(prayerListText, ' • '))
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getRuneNavbox(frame)
-- Assumes all runes are from Runecrafting, which may need revising in future updates
local runeList = { ["Standard"] = {}, ["Combination"] = {} }
for i, item in ipairs(ItemData.Items) do
if item.category == 'Runecrafting' and item.type ~= nil and item.type == 'Rune' and item.runecraftingLevel ~= nil then
local runeType = (type(item.providesRune) == 'table' and Shared.tableCount(item.providesRune) > 1 and 'Combination') or 'Standard'
table.insert(runeList[runeType], { ["name"] = item.name, ["order"] = item.runecraftingLevel })
end
end
local resultPart = {}
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"')
table.insert(resultPart, '\r\n!colspan="2"|[[File:Air_Rune_(item).svg|25px|link=Runes]] [[Runes]]')
for i, cat in ipairs({'Standard', 'Combination'}) do
table.sort(runeList[cat], function(a, b) return (a.order == b.order and a.name < b.name) or a.order < b.order end)
table.insert(resultPart, '\r\n|-\r\n!scope="row"|' .. cat .. ' Runes')
local listPart = {}
for j, rune in ipairs(runeList[cat]) do
table.insert(listPart, Icons.Icon({rune.name, type='item'}))
end
table.insert(resultPart, '\r\n|style="text-align:center;"|'..table.concat(listPart, ' • '))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getSkillcapeNavbox(frame)
local capeList = Shop.getPurchases(function(cat, purch) return cat == 'Skillcapes' end)
table.sort(capeList, function(a, b)
if a.cost.gp == b.cost.gp then
return a.name < b.name
else
return a.cost.gp < b.cost.gp
end
end)
local capeText = {}
for i, purch in ipairs(capeList) do
if purch.contains ~= nil and purch.contains.items ~= nil then
local item = Items.getItemByID(purch.contains.items[1][1])
if item ~= nil then
table.insert(capeText, Icons.Icon({item.name, type='item'}))
end
end
end
local resultPart = {}
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"')
table.insert(resultPart, '\r\n![[File:Cape_of_Completion_(item).svg|25px|link=Skillcapes]] [[Skillcapes]]')
table.insert(resultPart, '\r\n|-\r\n|style="text-align:center;"|'..table.concat(capeText, ' • '))
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getSpellNavbox(frame)
local spellTable = { ["standard"] = {}, ["curse"] = {}, ["aurora"] = {}, ["ancient"] = {}, ["alt"] = {} }
local catData = {
{ ["name"] = 'standard', ["header"] = '[[Magic#Standard_Magic|Standard Spells]]', ["imgType"] = 'spell' },
{ ["name"] = 'curse', ["header"] = '[[Magic#Curses|Curses]]', ["imgType"] = 'curse' },
{ ["name"] = 'aurora', ["header"] = '[[Magic#Auroras|Auroras]]', ["imgType"] = 'aurora' },
{ ["name"] = 'ancient', ["header"] = '[[Magic#Ancient_Magicks|Ancient Magicks]]', ["imgType"] = 'spell' },
{ ["name"] = 'alt', ["header"] = '[[Alternative_Magic|Alt Magic]]', ["imgType"] = 'spell' },
}
for i, spell in ipairs(MagicData.Spells) do
table.insert(spellTable['standard'], { ["name"] = spell.name, ["order"] = spell.level })
end
for i, spell in ipairs(MagicData.Curses) do
table.insert(spellTable['curse'], { ["name"] = spell.name, ["order"] = spell.level })
end
for i, spell in ipairs(MagicData.Auroras) do
table.insert(spellTable['aurora'], { ["name"] = spell.name, ["order"] = spell.level })
end
for i, spell in ipairs(MagicData.Ancient) do
table.insert(spellTable['ancient'], { ["name"] = spell.name, ["order"] = spell.level })
end
for i, spell in ipairs(MagicData.AltMagic) do
table.insert(spellTable['alt'], { ["name"] = spell.name, ["order"] = spell.level })
end
local getSpellList = function(spellTable, imgType)
local listPart = {}
for i, obj in ipairs(spellTable) do
table.insert(listPart, Icons.Icon({obj.name, type=imgType}))
end
return table.concat(listPart, ' • ')
end
local resultPart = {}
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"')
table.insert(resultPart, '\r\n!colspan=2|[[File:Magic_(skill).svg|25px|link=Spells]] [[Spells]]')
for i, catDefn in ipairs(catData) do
table.sort(spellTable[catDefn.name], function(a, b)
if a.order == b.order then
return a.name < b.name
else
return a.order < b.order
end
end)
table.insert(resultPart, '\r\n|-\r\n!scope="row"| ' .. catDefn.header)
table.insert(resultPart, '\r\n|style="text-align:center;| ' .. getSpellList(spellTable[catDefn.name], catDefn.imgType))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
function p.getFamiliarNavbox(frame)
local familiars = Items.getItems(function(item) return item.type == 'Familiar' end)
table.sort(familiars, function(a, b) return a.summoningLevel < b.summoningLevel end)
local result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"'
result = result..'\r\n!colspan=2|[[File:Summoning_(skill).svg|25px|link=Summoning]] [[Summoning|Summoning Familiars]]'
local iconArray = {}
for i, fam in Shared.skpairs(familiars) do
table.insert(iconArray, Icons.Icon({fam.name, type='item'}))
end
result = result..'\r\n|-\r\n|style="text-align:center;"|'..table.concat(iconArray, ' • ')
result = result..'\r\n|}'
return result
end
function p.getThievingNavbox()
local returnPart = {}
-- Create table header
table.insert(returnPart, '{| class="wikitable" style="text-align:center; clear:both; margin:auto; margin-bottom:1em;"')
table.insert(returnPart, '|-\r\n!' .. Icons.Icon({'Thieving', type='skill', notext=true}) .. '[[Thieving|Thieving Targets]]')
table.insert(returnPart, '|-\r\n|')
local npcData = {}
for i, npc in ipairs(SkillData.Thieving.NPCs) do
table.insert(npcData, {["level"] = npc.level, ["name"] = npc.name})
end
table.sort(npcData, function(a, b) return a.level < b.level end)
local npcList = {}
-- Create row for each NPC
for i, npc in ipairs(npcData) do
table.insert(npcList, Icons.Icon({npc.name, type='thieving'}))
end
table.insert(returnPart, table.concat(npcList, ' • '))
table.insert(returnPart, '|}')
return table.concat(returnPart, '\r\n')
end
function p.getFishingNavbox()
local categoryHeader = {}
local categoryItems = {}
local addCatData = function(cat, catLink, itemName, itemOrder)
if categoryItems[cat] == nil then
-- Initialise category
table.insert(categoryHeader, { ["name"] = cat, ["link"] = catLink })
categoryItems[cat] = {}
end
table.insert(categoryItems[cat], { ["name"] = itemName, ["order"] = itemOrder })
end
-- Identify fishing catchable items
local fishingToItemID = {}
local junkItems = {}
local specialItems = {}
for i, item in ipairs(ItemData.Items) do
if item.fishingID ~= nil then
-- Create FishingID to item map
fishingToItemID[item.fishingID] = item
elseif item.category == 'Fishing' and item.type == 'Junk' then
table.insert(junkItems, item)
elseif item.fishingCatchWeight ~= nil then
table.insert(specialItems, item)
end
end
-- Fishing areas
-- Iterate through all fishing areas, identifying fish within each
for i, area in ipairs(SkillData.Fishing.Areas) do
for j, fishID in ipairs(area.fish) do
local fishItem = fishingToItemID[fishID]
if fishItem ~= nil then
addCatData(area.name, 'Fishing#Fishing Areas', fishItem.name, fishItem.fishingLevel)
end
end
end
-- Junk items
for i, item in ipairs(junkItems) do
addCatData('Junk', 'Fishing#Junk', item.name, 1)
end
-- Special items
for i, item in ipairs(specialItems) do
addCatData('Special Items', 'Fishing#Special', item.name, 1 / (item.fishingCatchWeight or 1))
end
local resultPart = {}
-- Generate navbox header
table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"')
table.insert(resultPart, '\r\n|-\r\n!colspan="2" | ' .. Icons.Icon({'Fishing', type='skill'}))
-- Generate section for each fishing area, junk, and special
for i, cat in ipairs(categoryHeader) do
local itemList = {}
if categoryItems[cat.name] ~= nil then
table.sort(categoryItems[cat.name], function(a, b) return (a.order == b.order and a.name < b.name) or a.order < b.order end)
for j, item in ipairs(categoryItems[cat.name]) do
table.insert(itemList, Icons.Icon({item.name, type='item'}))
end
end
table.insert(resultPart, '\r\n|-\r\n!class="center" style="min-width:140px" | [[' .. (cat.link or cat.name) .. '|' .. cat.name .. ']]')
table.insert(resultPart, '\r\n| class="center" style="vertical-align:middle;" | ' .. table.concat(itemList, ' • '))
end
table.insert(resultPart, '\r\n|}')
return table.concat(resultPart)
end
return p