Module:Navboxes: Difference between revisions

From Melvor Idle
(getFarmingNavbox: Revise implementation, ensure all seeds and the grown result of all seeds is included)
(getRuneNavbox: Order results by level & improve resilience against future rune additions; getSkillcapeNavbox: Include missing max cape & consistency with shop table; getFishingNavbox: Implement to replace manually maintained table)
Line 10: Line 10:
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Items = require('Module:Items')
local Shop = require('Module:Shop')


function p.getFarmingNavbox(frame)
function p.getFarmingNavbox(frame)
Line 199: Line 200:


function p.getRuneNavbox(frame)
function p.getRuneNavbox(frame)
   local standardRunes = {}
  -- Assumes all runes are from Runecrafting, which may need revising in future updates
  local combinationRunes = {}
   local runeList = { ["Standard"] = {}, ["Combination"] = {} }
   for i, item in pairs(ItemData.Items) do
   for i, item in ipairs(ItemData.Items) do
     if (i >= 390 and i < 400) or (i >= 821 and i < 825) then
     if item.category == 'Runecrafting' and item.type ~= nil and item.type == 'Rune' and item.runecraftingLevel ~= nil then
     table.insert(standardRunes, Icons.Icon({item.name, type='item'}))
      local runeType = (type(item.providesRune) == 'table' and Shared.tableCount(item.providesRune) > 1 and 'Combination') or 'Standard'
     elseif i >= 825 and i < 831 then
      table.insert(runeList[runeType], { ["name"] = item.name, ["order"] = item.runecraftingLevel })
     table.insert(combinationRunes, Icons.Icon({item.name, type='item'}))
     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
     end
    table.insert(resultPart, '\r\n|style="text-align:center;"|'..table.concat(listPart, ' • '))
   end
   end
   local result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"'
   table.insert(resultPart, '\r\n|}')
  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'
   return table.concat(resultPart)
  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
end


function p.getSkillcapeNavbox(frame)
function p.getSkillcapeNavbox(frame)
   local capeList = {}
   local capeList = Shop.getPurchases(function(cat, purch) return cat == 'Skillcapes' end)
   for i, item in pairs(ItemData.Items) do
  table.sort(capeList, function(a, b)
     if Shared.contains(item.name, 'Skillcape') or item.name == 'Cape of Completion' then
                        if a.cost.gp == b.cost.gp then
    table.insert(capeList, Icons.Icon({item.name, type='item'}))
                          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
   end
   end
   table.sort(capeList, function(a,b)
 
    return a < b
  local resultPart = {}
  end)
   table.insert(resultPart, '{| class="wikitable" style="margin:auto; clear:both; width: 100%"')
  local result = '{| class="wikitable" style="margin:auto; clear:both; width: 100%"'
   table.insert(resultPart, '\r\n![[File:Cape_of_Completion_(item).svg|25px|link=Skillcapes]] [[Skillcapes]]')
   result = result..'\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, ' • '))
   result = result..'\r\n|-\r\n|style="text-align:center;"|'..table.concat(capeList, ' • ')
   table.insert(resultPart, '\r\n|}')
   result = result..'\r\n|}'
 
   return result
   return table.concat(resultPart)
end
end


Line 297: Line 318:
   table.insert(returnPart, '|-\r\n!' .. Icons.Icon({'Thieving', type='skill', notext=true}) .. '[[Thieving|Thieving Targets]]')
   table.insert(returnPart, '|-\r\n!' .. Icons.Icon({'Thieving', type='skill', notext=true}) .. '[[Thieving|Thieving Targets]]')
   table.insert(returnPart, '|-\r\n|')
   table.insert(returnPart, '|-\r\n|')
 
 
   local npcData = {}
   local npcData = {}
   for i, npc in ipairs(SkillData.Thieving.NPCs) do
   for i, npc in ipairs(SkillData.Thieving.NPCs) do
Line 313: Line 334:


   return table.concat(returnPart, '\r\n')
   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
end


return p
return p