Difference between revisions of "Module:Skills/Agility"

From Melvor Idle
(Implement getPillars())
(Remove unused modules/data; use ipairs instead of skpairs where possible to respect data order; getObstacleCourseTable: Display obstacles in same order as in-game)
Line 1: Line 1:
 
local p = {}
 
local p = {}
  
local ItemData = mw.loadData('Module:Items/data')
 
 
local SkillData = mw.loadData('Module:Skills/data')
 
local SkillData = mw.loadData('Module:Skills/data')
  
Line 7: Line 6:
 
local Shared = require('Module:Shared')
 
local Shared = require('Module:Shared')
 
local Items = require('Module:Items')
 
local Items = require('Module:Items')
local ItemSourceTables = require('Module:Items/SourceTables')
 
 
local Icons = require('Module:Icons')
 
local Icons = require('Module:Icons')
  
Line 16: Line 14:
  
 
function p.getObstacle(name)
 
function p.getObstacle(name)
   for i, obst in Shared.skpairs(SkillData.Agility.Obstacles) do
+
   for i, obst in ipairs(SkillData.Agility.Obstacles) do
 
     if obst.name == name then
 
     if obst.name == name then
 
       local result = Shared.clone(obst)
 
       local result = Shared.clone(obst)
Line 28: Line 26:
 
function p.getObstacles(checkFunc)
 
function p.getObstacles(checkFunc)
 
   local result = {}
 
   local result = {}
   for i, obst in Shared.skpairs(SkillData.Agility.Obstacles) do
+
   for i, obst in ipairs(SkillData.Agility.Obstacles) do
 
     if checkFunc(obst) then
 
     if checkFunc(obst) then
 
       local newObst = Shared.clone(obst)
 
       local newObst = Shared.clone(obst)
Line 40: Line 38:
 
function p.getPillars(checkFunc)
 
function p.getPillars(checkFunc)
 
   local result = {}
 
   local result = {}
   for i, pillar in Shared.skpairs(SkillData.Agility.Pillars) do
+
   for i, pillar in ipairs(SkillData.Agility.Pillars) do
 
     if checkFunc(pillar) then
 
     if checkFunc(pillar) then
 
       local newPillar = Shared.clone(pillar)
 
       local newPillar = Shared.clone(pillar)
Line 60: Line 58:
 
   local catLog = {}
 
   local catLog = {}
 
   local Obstacles = Shared.clone(SkillData.Agility.Obstacles)
 
   local Obstacles = Shared.clone(SkillData.Agility.Obstacles)
   table.sort(Obstacles, function(a, b) return a.category < b.category end)
+
   table.sort(Obstacles, function(a, b) return (a.category == b.category and a.id < b.id) or a.category < b.category end)
  
 
   local catCounts = {}
 
   local catCounts = {}
   for i, obst in Shared.skpairs(Obstacles) do
+
   for i, obst in ipairs(Obstacles) do
 
     if catCounts[obst.category] == nil then
 
     if catCounts[obst.category] == nil then
 
       catCounts[obst.category] = 1
 
       catCounts[obst.category] = 1
Line 71: Line 69:
 
   end
 
   end
  
   for i, obst in Shared.skpairs(Obstacles) do
+
   for i, obst in ipairs(Obstacles) do
 
     result = result..'\r\n|-'
 
     result = result..'\r\n|-'
 
     result = result..'\r\n|'
 
     result = result..'\r\n|'
Line 106: Line 104:
 
     end
 
     end
 
     if obst.requirements ~= nil and obst.requirements.skillLevel ~= nil then
 
     if obst.requirements ~= nil and obst.requirements.skillLevel ~= nil then
       for j, skillReq in Shared.skpairs(obst.requirements.skillLevel) do
+
       for j, skillReq in ipairs(obst.requirements.skillLevel) do
 
         result = result..'<br/>'..Icons._SkillReq(Constants.getSkillName(skillReq[1]), skillReq[2])
 
         result = result..'<br/>'..Icons._SkillReq(Constants.getSkillName(skillReq[1]), skillReq[2])
 
       end
 
       end
Line 115: Line 113:
 
     if obst.cost.gp > 0 then table.insert(costs, Icons.GP(obst.cost.gp)) end
 
     if obst.cost.gp > 0 then table.insert(costs, Icons.GP(obst.cost.gp)) end
 
     if obst.cost.slayerCoins > 0 then table.insert(costs, Icons.SC(obst.cost.slayerCoins)) end
 
     if obst.cost.slayerCoins > 0 then table.insert(costs, Icons.SC(obst.cost.slayerCoins)) end
     for j, itemCost in Shared.skpairs(obst.cost.items) do
+
     for j, itemCost in ipairs(obst.cost.items) do
 
       local item = Items.getItemByID(itemCost[1])
 
       local item = Items.getItemByID(itemCost[1])
 
       table.insert(costs, Icons.Icon({item.name, type='item', qty = itemCost[2], notext=true}))
 
       table.insert(costs, Icons.Icon({item.name, type='item', qty = itemCost[2], notext=true}))
Line 134: Line 132:
 
   result = result..'\r\n!Name!!Bonuses!!Cost'
 
   result = result..'\r\n!Name!!Bonuses!!Cost'
  
   for i, pill in Shared.skpairs(SkillData.Agility.Pillars) do
+
   for i, pill in ipairs(SkillData.Agility.Pillars) do
 
     result = result..'\r\n|-'
 
     result = result..'\r\n|-'
 
     result = result..'\r\n|'..pill.name
 
     result = result..'\r\n|'..pill.name
Line 152: Line 150:
 
     if pill.cost.gp > 0 then table.insert(costs, Icons.GP(pill.cost.gp)) end
 
     if pill.cost.gp > 0 then table.insert(costs, Icons.GP(pill.cost.gp)) end
 
     if pill.cost.slayerCoins > 0 then table.insert(costs, Icons.SC(pill.cost.slayerCoins)) end
 
     if pill.cost.slayerCoins > 0 then table.insert(costs, Icons.SC(pill.cost.slayerCoins)) end
     for j, itemCost in Shared.skpairs(pill.cost.items) do
+
     for j, itemCost in ipairs(pill.cost.items) do
 
       local item = Items.getItemByID(itemCost[1])
 
       local item = Items.getItemByID(itemCost[1])
 
       table.insert(costs, Icons.Icon({item.name, type='item', qty = itemCost[2], notext=true}))
 
       table.insert(costs, Icons.Icon({item.name, type='item', qty = itemCost[2], notext=true}))
Line 166: Line 164:
 
function p.getObstaclesForItem(itemID)
 
function p.getObstaclesForItem(itemID)
 
   local result = {}
 
   local result = {}
   for i, obst in Shared.skpairs(SkillData.Agility.Obstacles) do
+
   for i, obst in ipairs(SkillData.Agility.Obstacles) do
     for j, costLine in Shared.skpairs(obst.cost.items) do
+
     for j, costLine in ipairs(obst.cost.items) do
 
       if costLine[1] == itemID then
 
       if costLine[1] == itemID then
 
         table.insert(result, obst)
 
         table.insert(result, obst)
Line 174: Line 172:
 
   end
 
   end
  
   for i, obst in Shared.skpairs(SkillData.Agility.Pillars) do
+
   for i, obst in ipairs(SkillData.Agility.Pillars) do
     for j, costLine in Shared.skpairs(obst.cost.items) do
+
     for j, costLine in ipairs(obst.cost.items) do
 
       if costLine[1] == itemID then
 
       if costLine[1] == itemID then
 
         table.insert(result, obst)
 
         table.insert(result, obst)

Revision as of 22:35, 17 November 2021

Documentation for this module may be created at Module:Skills/Agility/doc

local p = {}

local SkillData = mw.loadData('Module:Skills/data')

local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Items = require('Module:Items')
local Icons = require('Module:Icons')

function p.getObstacleByID(obstID)
  local result = Shared.clone(SkillData.Agility.Obstacles[obstID + 1])
  return result
end

function p.getObstacle(name)
  for i, obst in ipairs(SkillData.Agility.Obstacles) do
    if obst.name == name then
      local result = Shared.clone(obst)
      result.id = i - 1
      return result
    end
  end
  return nil
end

function p.getObstacles(checkFunc)
  local result = {}
  for i, obst in ipairs(SkillData.Agility.Obstacles) do
    if checkFunc(obst) then
      local newObst = Shared.clone(obst)
      newObst.id = i - 1
      table.insert(result, newObst)
    end
  end
  return result
end

function p.getPillars(checkFunc)
  local result = {}
  for i, pillar in ipairs(SkillData.Agility.Pillars) do
    if checkFunc(pillar) then
      local newPillar = Shared.clone(pillar)
      newPillar.id = i - 1
      table.insert(result, newPillar)
    end
  end
  return result
end

function p.getObstacleCourseTable(frame)
  local result = ''

  result = '{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!Slot!!Name!!XP!!GP!!Time'--!!XP/s!!GP/s
  result = result..'!!Bonuses!!Requirements!!Cost'

  local catLog = {}
  local Obstacles = Shared.clone(SkillData.Agility.Obstacles)
  table.sort(Obstacles, function(a, b) return (a.category == b.category and a.id < b.id) or a.category < b.category end)

  local catCounts = {}
  for i, obst in ipairs(Obstacles) do
    if catCounts[obst.category] == nil then
      catCounts[obst.category] = 1
    else
      catCounts[obst.category] = catCounts[obst.category] + 1
    end
  end

  for i, obst in ipairs(Obstacles) do
    result = result..'\r\n|-'
    result = result..'\r\n|'
    if catLog[obst.category] == nil then
      local rowspan = catCounts[obst.category]
      result = result..'rowspan="'..rowspan..'" style="border:1px solid black"|'..(obst.category + 1)..'||'
      catLog[obst.category] = true
    end
    result = result..obst.name

    --After the name & category, doing XP, GP, Time, and rates
    local XP = obst.completionBonuses.xp
    local GP = obst.completionBonuses.gp
    local Time = obst.interval / 1000
    result = result..'||'..XP..'||data-sort-value="'..GP..'"|'..Icons.GP(GP)
    result = result..'||data-sort-value="'..Time..'"|'..Shared.timeString(Time, true)
    --result = result..'||'..Shared.round(XP / Time, 2, 2)
    --result = result..'||data-sort-value="'..GP/Time..'"|'..Icons.GP(Shared.round(GP/Time, 2, 2))

    local bonuses = {}
    --After that, adding the bonuses
    for bonusName, bonusValue in pairs(obst.modifiers) do
      table.insert(bonuses, Constants._getModifierText(bonusName, bonusValue))
    end
    if Shared.tableCount(bonuses) == 0 then
      table.insert(bonuses, '<span style="color:red">None :(</span>')
    end
    result = result..'||'..table.concat(bonuses, '<br/>')

    --Grabbing requirements to create
    result = result..'||'
    if obst.category > 0 then
      result = result..Icons._SkillReq('Agility', obst.category * 10)
    end
    if obst.requirements ~= nil and obst.requirements.skillLevel ~= nil then
      for j, skillReq in ipairs(obst.requirements.skillLevel) do
        result = result..'<br/>'..Icons._SkillReq(Constants.getSkillName(skillReq[1]), skillReq[2])
      end
    end

    --Finally, the cost
    local costs = {}
    if obst.cost.gp > 0 then table.insert(costs, Icons.GP(obst.cost.gp)) end
    if obst.cost.slayerCoins > 0 then table.insert(costs, Icons.SC(obst.cost.slayerCoins)) end
    for j, itemCost in ipairs(obst.cost.items) do
      local item = Items.getItemByID(itemCost[1])
      table.insert(costs, Icons.Icon({item.name, type='item', qty = itemCost[2], notext=true}))
    end
    result = result..'|| data-sort-value="'..obst.cost.gp..'"|'..table.concat(costs, '<br/>')
  end

  result = result..'\r\n|}'

  return result
end

function p.getPassivePillarTable(frame)
  local result = ''

  result = '{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!Name!!Bonuses!!Cost'

  for i, pill in ipairs(SkillData.Agility.Pillars) do
    result = result..'\r\n|-'
    result = result..'\r\n|'..pill.name

    --After that, adding the bonuses
    local bonuses = {}
    for bonusName, bonusValue in pairs(pill.modifiers) do
      table.insert(bonuses, Constants._getModifierText(bonusName, bonusValue))
    end
    if Shared.tableCount(bonuses) == 0 then
      table.insert(bonuses, '<span style="color:red">None :(</span>')
    end
    result = result..'||'..table.concat(bonuses, '<br/>')

    --Finally, the cost
    local costs = {}
    if pill.cost.gp > 0 then table.insert(costs, Icons.GP(pill.cost.gp)) end
    if pill.cost.slayerCoins > 0 then table.insert(costs, Icons.SC(pill.cost.slayerCoins)) end
    for j, itemCost in ipairs(pill.cost.items) do
      local item = Items.getItemByID(itemCost[1])
      table.insert(costs, Icons.Icon({item.name, type='item', qty = itemCost[2], notext=true}))
    end
    result = result..'|| data-sort-value="'..pill.cost.gp..'"|'..table.concat(costs, '<br/>')
  end

  result = result..'\r\n|}'

  return result
end

function p.getObstaclesForItem(itemID)
  local result = {}
  for i, obst in ipairs(SkillData.Agility.Obstacles) do
    for j, costLine in ipairs(obst.cost.items) do
      if costLine[1] == itemID then
        table.insert(result, obst)
      end
    end
  end

  for i, obst in ipairs(SkillData.Agility.Pillars) do
    for j, costLine in ipairs(obst.cost.items) do
      if costLine[1] == itemID then
        table.insert(result, obst)
      end
    end
  end

  return result
end

return p