Module:Navboxes
From Melvor Idle
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')
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 result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"'
result = result..'\r\n!colspan=2|'..Icons.Icon({'Herblore', 'Potions', type='skill'})
local CombatPots = {}
local SkillPots = {}
for i, potData in Shared.skpairs(SkillData.Herblore.ItemData) do
if potData.category == 0 then
table.insert(CombatPots, Icons.Icon({potData.name, type='item', img=(potData.name..' I')}))
else
if potData.name == 'Bird Nests Potion' then
table.insert(SkillPots, Icons.Icon({"Bird Nest Potion", type='item', img="Bird Nest Potion I"}))
else
table.insert(SkillPots, Icons.Icon({potData.name, type='item', img=(potData.name..' I')}))
end
end
end
result = result..'\r\n|-\r\n!Combat Potions\r\n|class="center" style="vertical-align:middle;"'
result = result..'|'..table.concat(CombatPots, ' • ')
result = result..'\r\n|-\r\n!Skill Potions\r\n|class="center" style="vertical-align:middle;"'
result = result..'|'..table.concat(SkillPots, ' • ')
result = result..'\r\n|}'
return result
end
function p.getPrayerNavbox(frame)
local prayers = {}
for i, prayer in Shared.skpairs(SkillData.Prayer) do
table.insert(prayers, Icons.Icon({prayer.name, type="prayer"}))
end
local result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"'
result = result..'\r\n!'..Icons.Icon({'Prayer', 'Prayers', type='skill'})
result = result..'\r\n|-\r\n|style="text-align:center;"|'..table.concat(prayers, ' • ')
result = result..'\r\n|}'
return result
end
function p.getRuneNavbox(frame)
local standardRunes = {}
local combinationRunes = {}
for i, item in pairs(ItemData.Items) do
if (i >= 390 and i < 400) or (i >= 821 and i < 825) then
table.insert(standardRunes, Icons.Icon({item.name, type='item'}))
elseif i >= 825 and i < 831 then
table.insert(combinationRunes, Icons.Icon({item.name, type='item'}))
end
end
local result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"'
result = result..'\r\n!colspan="2"|[[File:Air_Rune_(item).svg|25px|link=Runes]] [[Runes]]'
result = result..'\r\n|-\r\n!scope="row"|Standard Runes'
result = result..'\r\n|style="text-align:center;"|'..table.concat(standardRunes, ' • ')
result = result..'\r\n|-\r\n!scope="row"|Combination Runes'
result = result..'\r\n|style="text-align:center;"|'..table.concat(combinationRunes, ' • ')
result = result..'\r\n|}'
return result
end
function p.getSkillcapeNavbox(frame)
local capeList = {}
for i, item in pairs(ItemData.Items) do
if Shared.contains(item.name, 'Skillcape') or item.name == 'Cape of Completion' then
table.insert(capeList, Icons.Icon({item.name, type='item'}))
end
end
table.sort(capeList, function(a,b)
return a < b
end)
local result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"'
result = result..'\r\n![[File:Cape_of_Completion_(item).svg|25px|link=Skillcapes]] [[Skillcapes]]'
result = result..'\r\n|-\r\n|style="text-align:center;"|'..table.concat(capeList, ' • ')
result = result..'\r\n|}'
return result
end
function p.getSpellNavbox(frame)
local spells = {}
local curses = {}
local auroras = {}
local ancients = {}
local altmagic = {}
for i, spell in Shared.skpairs(MagicData.Spells) do
table.insert(spells, Icons.Icon({spell.name, type='spell'}))
end
for i, spell in Shared.skpairs(MagicData.Curses) do
table.insert(curses, Icons.Icon({spell.name, type='curse'}))
end
for i, spell in Shared.skpairs(MagicData.Auroras) do
table.insert(auroras, Icons.Icon({spell.name, type='aurora'}))
end
for i, spell in Shared.skpairs(MagicData.Ancient) do
table.insert(ancients, Icons.Icon({spell.name, type='spell'}))
end
for i, spell in Shared.skpairs(MagicData.AltMagic) do
table.insert(altmagic, Icons.Icon({spell.name, type='spell'}))
end
local result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"'
result = result..'\r\n!colspan=2|[[File:Magic_(skill).svg|25px|link=Spells]] [[Spells]]'
result = result..'\r\n|-\r\n!scope="row"|[[Magic#Standard_Magic|Standard Spells]]'
result = result..'\r\n|style="text-align:center;|'..table.concat(spells, ' • ')
result = result..'\r\n|-\r\n!scope="row"|[[Magic#Curses|Curses]]'
result = result..'\r\n|style="text-align:center;|'..table.concat(curses, ' • ')
result = result..'\r\n|-\r\n!scope="row"|[[Magic#Auroras|Auroras]]'
result = result..'\r\n|style="text-align:center;|'..table.concat(auroras, ' • ')
result = result..'\r\n|-\r\n!scope="row"|[[Magic#Ancient_Magicks|Ancient Magicks]]'
result = result..'\r\n|style="text-align:center;|'..table.concat(ancients, ' • ')
result = result..'\r\n|-\r\n!scope="row"|[[Alternative_Magic|Alt Magic]]'
result = result..'\r\n|style="text-align:center;|'..table.concat(altmagic, ' • ')
result = result..'\r\n|}'
return result
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
return p