Module:ModifierTables: Difference between revisions

From Melvor Idle
(ModifierTable should now sort alphabetically when more than one modifier is requested)
(Sort modifier tables alphabetically by default if more than one argument is passed in)
Line 311: Line 311:
   if hasOtherModifiers then result = result..'!!Other Modifiers' end
   if hasOtherModifiers then result = result..'!!Other Modifiers' end


   table.sort(tableArray, function(a, b)
   --Sort by value if only one modifier was passed in
                          if modifierCount > 1 and a.val ~= b.val then
  --Otherwise sort alphabetically by name
                            return a.val > b.val
  if modifierCount == 1 then
                          elseif a.name ~= b.name then
    table.sort(tableArray, function(a, b)
                            return a.name < b.name
                            if a.val ~= b.val then
                          else
                              return a.val > b.val
                            return a.type < b.type
                            elseif a.name ~= b.name then
                           end
                              return a.name < b.name
                        end)
                            else
                              return a.type < b.type
                            end
                           end)
  else
    table.sort(tableArray, function(a, b) return a.name < b.name end)
  end
   for i, row in Shared.skpairs(tableArray) do
   for i, row in Shared.skpairs(tableArray) do
     result = result..'\r\n|-'
     result = result..'\r\n|-'

Revision as of 19:14, 29 July 2021

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

--Module that constructs tables for all things that can affect Player Modifiers
--This includes Agility, Equipment, and Pets right now

local p = {}

local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Pets = require('Module:Pets')
local Items = require('Module:Items')
local Agility = require('Module:Skills/Agility')
local Shop = require('Module:Shop')
local Icons = require('Module:Icons')

--First up, functions to get all the things in a category that have a given modifier:
function p.getModifierValue(modifiers, modifier, skill, getOpposites)
  --Sometimes nil modifier sets will get here, which is fine. Just return 0 immediately
  if modifiers == nil then
    return 0
  end
  
  --Make sure we have the skillID and not the name
  if skill == '' then
    skill = nil
  elseif type(skill) == 'string' then
    skill = Constants.getSkillID(skill)
  end

  --By default, attempt to add the increased and decreased prefixes to the modifier
  --But if getOpposites is false, only look for an exact match
  local increaseMod, decreaseMod = '', ''
  if getOpposites == nil or getOpposites then
    increaseMod = 'increased'..modifier
    decreaseMod = 'decreased'..modifier
  else
    increaseMod = modifier
  end

  local increaseVal, decreaseVal = 0, 0
  if modifiers[increaseMod] ~= nil and modifiers[increaseMod] ~= nil then
    if type(modifiers[increaseMod]) == 'table' then
      for i, subVal in Shared.skpairs(modifiers[increaseMod]) do
        if subVal[1] == skill then
          increaseVal = subVal[2]
        end
      end
    else
      increaseVal = modifiers[increaseMod]
    end
  end

  if modifiers[decreaseMod] ~= nil and modifiers[decreaseMod] ~= nil then
    if type(modifiers[decreaseMod]) == 'table' then
      for i, subVal in Shared.skpairs(modifiers[decreaseMod]) do
        if subVal[1] == skill then
          decreaseVal = subVal[2]
        end
      end
    else
      decreaseVal = modifiers[decreaseMod]
    end
  end

  return increaseVal - decreaseVal
end

function p.getItemsWithModifier(modifiers, skill, getOpposites)
  if type(modifiers) == 'string' then
    modifiers = {modifiers}
  end
  local itemList = Items.getItems(
        function(item)
          local result = false
          for i, mod in Shared.skpairs(modifiers) do
            if p.getModifierValue(item.modifiers, mod, skill, getOpposites) ~= 0 then
              result = true
              break
            end
          end
          return result
        end)
  return itemList    
end

function p.getObstaclesWithModifier(modifiers, skill, getOpposites)
  if type(modifiers) == 'string' then
    modifiers = {modifiers}
  end
  local obstList = Agility.getObstacles(
        function(obst)
          local result = false
          for i, mod in Shared.skpairs(modifiers) do
            if p.getModifierValue(obst.modifiers, mod, skill, getOpposites) ~= 0 then
              result = true
              break
            end
          end
          return result
        end)
  return obstList
end

function p.getPillarsWithModifier(modifiers, skill, getOpposites)
  if type(modifiers) == 'string' then
    modifiers = {modifiers}
  end
  local pillarList = Agility.getPillars(
        function(pillar)
          local result = false
          for i, mod in Shared.skpairs(modifiers) do
            if p.getModifierValue(pillar.modifiers, mod, skill, getOpposites) ~= 0 then
              result = true
              break
            end
          end
          return result
        end)
  return pillarList
end

function p.getPetsWithModifier(modifiers, skill, getOpposites)
  if type(modifiers) == 'string' then
    modifiers = {modifiers}
  end
  local petList = Pets.getPets(
        function(pet)
          local result = false
          for i, mod in Shared.skpairs(modifiers) do
            if p.getModifierValue(pet.modifiers, mod, skill, getOpposites) ~= 0 then
              result = true
              break
            end
          end
          return result
        end)
  return petList
end

function p.getUpgradesWithModifier(modifiers, skill, getOpposites)
  if type(modifiers) == 'string' then
    modifiers = {modifiers}
  end
  local upgradeList = Shop.getPurchases(
        function(category, purchase)
          local result = false
          for i, mod in Shared.skpairs(modifiers) do
            if p.getModifierValue(purchase.contains.modifiers, mod, skill, getOpposites) ~= 0 then
              result = true
              break
            end
          end
          return result
        end)
 return upgradeList
end

function p._getModifierTable(modifiers, skill, columnName, getOpposites)
  local modifierNames = {}
  if type(modifiers) == 'string' then
    modifiers = {modifiers}
  end
  for i, modifier in pairs(modifiers) do
    if getOpposites then
      table.insert(modifierNames, 'increased'..modifier)
      table.insert(modifierNames, 'decreased'..modifier)
    else
      table.insert(modifierNames, modifier)
    end
  end

  local hasOtherModifiers = false
  local modifierCount = Shared.tableCount(modifiers)

  if skill == '' then
    skill = nil
  elseif type(skill) == 'string' then
    skill = Constants.getSkillID(skill)
  end

  local getModText = 
    function(modifiers)
      local modTextArray = {}
      local mainModText = {}
      for modName, modValue in Shared.skpairs(modifiers) do
        if Shared.contains(modifierNames, modName) then
          if type(modValue) == 'table' then
            for j, subVal in Shared.skpairs(modValue) do
              if subVal[1] == skill then
                table.insert(mainModText, Constants._getModifierText(modName, subVal))
              else
                table.insert(modTextArray, Constants._getModifierText(modName, subVal))
              end
            end
          else
            table.insert(mainModText, Constants._getModifierText(modName, modValue))
          end
        else
          table.insert(modTextArray, Constants._getModifierText(modName, modValue))
        end
      end

      return table.concat(mainModText, '<br/>'), table.concat(modTextArray, '<br/>')
    end

  local tableArray = {}
  --Going through each type of thing to add to the array
  local itemList = p.getItemsWithModifier(modifiers, skill, getOpposites)
  for i, item in Shared.skpairs(itemList) do
    local row = {}
    row.name = item.name
    row.icon = Icons.Icon({item.name, type='item'})
    row.type = 'Item'
    local totalVal = 0
    for i, mod in pairs(modifiers) do
      totalVal = totalVal + p.getModifierValue(item.modifiers, mod, skill, getOpposites)
    end
    row.val = totalVal

    row.modifierText, row.otherModifiers = getModText(item.modifiers)

    if string.len(row.otherModifiers) > 0 then
      hasOtherModifiers = true
    end

    table.insert(tableArray, row)
  end
  local petList = p.getPetsWithModifier(modifiers, skill, getOpposites)
  for i, pet in Shared.skpairs(petList) do
    local row = {}
    row.name = pet.name
    row.icon = Icons.Icon({pet.name, type='pet'})
    row.type = '[[Pets|Pet]]'
    local totalVal = 0
    for i, mod in pairs(modifiers) do
      totalVal = totalVal + p.getModifierValue(pet.modifiers, mod, skill, getOpposites)
    end
    row.val = totalVal

    row.modifierText, row.otherModifiers = getModText(pet.modifiers)

    if string.len(row.otherModifiers) > 0 then
      hasOtherModifiers = true
    end

    table.insert(tableArray, row)
  end
  local obstList = p.getObstaclesWithModifier(modifiers, skill, getOpposites)
  for i, obst in Shared.skpairs(obstList) do
    local row = {}
    row.name = obst.name
    row.icon = Icons.Icon({'Agility', obst.name, type='skill'})
    row.type = '[[Agility#Obstacles|Agility Obstacle]]'
    local totalVal = 0
    for i, mod in pairs(modifiers) do
      totalVal = totalVal + p.getModifierValue(obst.modifiers, mod, skill, getOpposites)
    end
    row.val = totalVal

    row.modifierText, row.otherModifiers = getModText(obst.modifiers)

    if string.len(row.otherModifiers) > 0 then
      hasOtherModifiers = true
    end

    table.insert(tableArray, row)
  end

  local pillarList = p.getPillarsWithModifier(modifiers, skill, getOpposites)
  for i, pillar in Shared.skpairs(pillarList) do
    local row = {}
    row.name = pillar.name
    row.icon = Icons.Icon({'Agility', pillar.name, type='skill'})
    row.type = '[[Agility#Passive Pillars|Agility Pillar]]'
    local totalVal = 0
    for i, mod in pairs(modifiers) do
      totalVal = totalVal + p.getModifierValue(pillar.modifiers, mod, skill, getOpposites)
    end
    row.val = totalVal

    row.modifierText, row.otherModifiers = getModText(pillar.modifiers)

    if string.len(row.otherModifiers) > 0 then
      hasOtherModifiers = true
    end

    table.insert(tableArray, row)
  end
  local upgradeList = p.getUpgradesWithModifier(modifiers, skill, getOpposites)
  for i, upgrade in Shared.skpairs(upgradeList) do
    local row = {}
    row.name = upgrade.name
    row.icon = Icons.Icon({upgrade.name, type='upgrade'})
    row.type = '[[Shop|Upgrade]]'
    local totalVal = 0
    for i, mod in pairs(modifiers) do
      totalVal = totalVal + p.getModifierValue(upgrade.contains.modifiers, mod, skill, getOpposites)
    end
    row.val = totalVal

    row.modifierText, row.otherModifiers = getModText(upgrade.contains.modifiers)

    if string.len(row.otherModifiers) > 0 then
      hasOtherModifiers = true
    end

    table.insert(tableArray, row)
  end

  local result = '{| class="wikitable sortable stickyHeader"'
  result = result..'\r\n|- class="headerRow-0"'
  result = result..'\r\n!Source!!Type!!'..columnName
  if hasOtherModifiers then result = result..'!!Other Modifiers' end

  --Sort by value if only one modifier was passed in
  --Otherwise sort alphabetically by name
  if modifierCount == 1 then
    table.sort(tableArray, function(a, b)
                             if a.val ~= b.val then
                               return a.val > b.val
                             elseif a.name ~= b.name then
                               return a.name < b.name
                             else
                               return a.type < b.type
                             end
                           end)
  else
    table.sort(tableArray, function(a, b) return a.name < b.name end)
  end
  for i, row in Shared.skpairs(tableArray) do
    result = result..'\r\n|-'
    result = result..'\r\n|data-sort-value="'..row.name..'"|'..row.icon
    result = result..'||'..row.type..'||data-sort-value="'..row.val..'"|'..row.modifierText
    if hasOtherModifiers then
      result = result..'||'..row.otherModifiers
    end
  end

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

function p.getModifierTable(frame)
  local modifier = frame.args ~= nil and frame.args[1] or frame[1]
  local skill = frame.args ~= nil and frame.args.skill or frame.skill
  local columnName = frame.args ~= nil and frame.args[2] or frame[2]
  local getOpposites = frame.args ~= nil and frame.args[3] or frame[3]

  if Shared.contains(modifier, ',') then
    modifier = Shared.splitString(modifier, ',')
  end

  if getOpposites ~= nil then
    getOpposites = string.upper(getOpposites) ~= 'FALSE'
  else
    getOpposites = true
  end

  
  return p._getModifierTable(modifier, skill, columnName, getOpposites)
end

return p