Anonymous

Module:ModifierTables: Difference between revisions

From Melvor Idle
Attempting to add Points of Interest to Modifier tables
(Created initial pass at this)
(Attempting to add Points of Interest to Modifier tables)
(56 intermediate revisions by 3 users not shown)
Line 1: Line 1:
--Module that constructs tables for all things that can affect Player Modifiers
--Module that constructs tables for all things that can affect Player Modifiers
--This includes Agility, Equipment, and Pets right now
--This includes Agility, Equipment, Pets, Prayers, and Constellations right now


local p = {}
local p = {}
Line 8: Line 8:
local Pets = require('Module:Pets')
local Pets = require('Module:Pets')
local Items = require('Module:Items')
local Items = require('Module:Items')
local Skills = require('Module:Skills')
local Agility = require('Module:Skills/Agility')
local Agility = require('Module:Skills/Agility')
local Prayer = require('Module:Prayer')
local Shop = require('Module:Shop')
local Shop = require('Module:Shop')
local Icons = require('Module:Icons')
local Cartography = require('Module:Skills/Cartography')


--First up, functions to get all the things in a category that have a given modifier:
--First up, functions to get all the things in a category that have a given modifier:
function p.getModifierValue(modifiers, modifier, skill, getOpposites)
function p.getModifierValue(modifiers, modifier, skill, getOpposites)
  --Sometimes nil modifier sets will get here, which is fine. Just return 0 immediately
--Sometimes nil modifier sets will get here, which is fine. Just return 0 immediately
  if modifiers == nil then
if modifiers == nil then
    return 0
return 0
  end
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
--Make sure we have the skillID and not the name
  --But if getOpposites is false, only look for an exact match
if skill ~= nil then
  local increaseMod, decreaseMod = '', ''
if skill == '' then
  if getOpposites == nil or getOpposites then
skill = nil
    increaseMod = 'increased'..modifier
elseif Constants.getSkillID(skill) ~= nil then
    decreaseMod = 'decreased'..modifier
-- skill is a skill name
  else
skill = Constants.getSkillID(skill)
    increaseMod = modifier
elseif Constants.getSkillName(skill) == nil then
  end
-- skill is neither a skill name or ID
return 0
end
end


  if not p.hasLogged then
--By default, attempt to add the increased and decreased prefixes to the modifier
    mw.log(increaseMod..', '..decreaseMod)
--But if getOpposites is false, only look for an exact match
    p.hasLogged = true
  end
local mods = {}
  local increaseVal, decreaseVal = 0, 0
if getOpposites == nil or getOpposites then
  if modifiers[increaseMod] ~= nil and modifiers[increaseMod] ~= nil then
mods.inc = 'increased'..modifier
    if type(modifiers[increaseMod]) == 'table' then
mods.dec = 'decreased'..modifier
      for i, subVal in Shared.skpairs(modifiers[increaseMod]) do
else
        if subVal[1] == skill then
mods.inc = modifier
          increaseVal = subVal[2]
end
        end
      end
local magnitude = { inc = 0, dec = 0 }
    else
for modType, modName in pairs(mods) do
      increaseVal = modifiers[increaseMod]
if modifiers[modName] ~= nil then
    end
local valueArray = nil
  end
            if type(modifiers[modName]) ~= 'table' then
                valueArray = {modifiers[modName]}
            else
                valueArray = modifiers[modName]
            end


  if modifiers[decreaseMod] ~= nil and modifiers[decreaseMod] ~= nil then
            for i, subVal in ipairs(valueArray) do
    if type(modifiers[decreaseMod]) == 'table' then
                if type(subVal) == 'table' then
      for i, subVal in Shared.skpairs(modifiers[decreaseMod]) do
if  subVal.skillID ~= nil then
        if subVal[1] == skill then
-- Modifier value is skill specific
          decreaseVal = subVal[2]
if skill == nil or skill == '' or subVal.skillID == skill then
        end
magnitude[modType] = magnitude[modType] + subVal.value
      end
end
    else
else
      decreaseVal = modifiers[decreaseMod]
-- Modifier value is a table of two numbers representing a range. Take the largest value
    end
magnitude[modType] = magnitude[modType] + (subVal[2] or 0)
  end
end
                else
                    magnitude[modType] = magnitude[modType] + subVal
                end
            end
end
end


  return increaseVal - decreaseVal
    return magnitude.inc - magnitude.dec
end
end


function p.getItemsWithModifier(modifier, skill, getOpposites)
function p.getItemsWithModifier(modifiers, skill, getOpposites)
  local itemList = Items.getItems(
if type(modifiers) == 'string' then
        function(item)
modifiers = {modifiers}
          return p.getModifierValue(item.modifiers, modifier, skill, getOpposites) ~= 0
end
        end)
local itemList = Items.getItems(
  return itemList
function(item)
if item.golbinRaidExclusive ~= nil and item.golbinRaidExclusive then
return false
elseif item.modifiers == nil or Shared.tableIsEmpty(item.modifiers) then
return false
end
for i, mod in ipairs(modifiers) do
if p.getModifierValue(item.modifiers, mod, skill, getOpposites) ~= 0 then
return true
end
end
return false
end)
return itemList
end
end


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


function p.getPetsWithModifier(modifier, skill, getOpposites)
function p.getConstellationsWithModifier(modifiers, skill, getOpposites)
  local petList = Pets.getPets(
if type(modifiers) == 'string' then
        function(pet)
modifiers = {modifiers}
          return p.getModifierValue(pet.modifiers, modifier, skill, getOpposites) ~= 0
end
        end)
local consList = Skills.getConstellations(
  return petList
function(cons)
local consMods = Skills._buildAstrologyModifierArray(cons, 1, true, true, true, true)
for i, modifier in ipairs(modifiers) do
if p.getModifierValue(consMods, modifier, skill, getOpposites) ~= 0 then
return true
end
end
return false
end)
return consList
end
end


function p.getUpgradesWithModifier(modifier, skill, getOpposites)
function p.getPillarsWithModifier(modifiers, skill, getOpposites)
  local upgradeList = Shop.getPurchases(
if type(modifiers) == 'string' then
        function(purchase)
modifiers = {modifiers}
          return p.getModifierValue(purchase.contains.modifiers, modifier, skill, getOpposites) ~= 0
end
        end)
local pillarList = Agility.getPillars(
return upgradeList
function(pillar)
for i, mod in ipairs(modifiers) do
if p.getModifierValue(pillar.modifiers, mod, skill, getOpposites) ~= 0 then
return true
end
end
return false
end)
return pillarList
end
 
function p.getPetsWithModifier(modifiers, skill, getOpposites)
if type(modifiers) == 'string' then
modifiers = {modifiers}
end
local petList = Pets.getPets(
function(pet)
for i, mod in ipairs(modifiers) do
if p.getModifierValue(pet.modifiers, mod, skill, getOpposites) ~= 0 then
return true
end
end
return false
end)
return petList
end
 
function p.getPrayersWithModifier(modifiers, skill, getOpposites)
if type(modifiers) == 'string' then
modifiers = {modifiers}
end
local prayerList = Prayer.getPrayers(
function(prayer)
for i, mod in ipairs(modifiers) do
if p.getModifierValue(prayer.modifiers, mod, skill, getOpposites) ~= 0 then
return true
end
end
return false
end)
return prayerList
end
 
function p.getUpgradesWithModifier(modifiers, skill, getOpposites)
if type(modifiers) == 'string' then
modifiers = {modifiers}
end
local upgradeList = Shop.getPurchases(
function(purchase)
if purchase.category == 'melvorD:GolbinRaid' then
return false
end
for i, mod in ipairs(modifiers) do
if p.getModifierValue(purchase.contains.modifiers, mod, skill, getOpposites) ~= 0 then
return true
end
end
return false
end)
return upgradeList
end
 
function p.getPOIsWithModifier(modifiers, skill, getOpposites)
if type(modifiers) == 'string' then
modifiers = {modifiers}
end
local POIList = Cartography.getPointsOfInterest(
function(POI)
if POI.activeModifiers == nil then
return false
end
for i, mod in ipairs(modifiers) do
if p.getModifierValue(POI.activeModifiers, mod, skill, getOpposites) ~= 0 then
return true
end
end
return false
end)
return POIList
end
 
function p._getModifierTable(modifiers, skill, columnName, getOpposites, displayOtherMods, maxOtherMods, forceMagnitudeSort)
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 ~= nil then
if skill == '' then
skill = nil
elseif Constants.getSkillID(skill) ~= nil then
-- skill is a skill name
skill = Constants.getSkillID(skill)
elseif Constants.getSkillName(skill) == nil then
-- skill is neither a skill name or ID
return Shared.printError('Failed to find a skill ID for "' .. skill .. '"')
end
end
 
local getModText =
function(modifiers)
local modTextArray = { ["visible"] = {}, ["overflow"] = {} }
local otherModCount = 0
local mainModText = {}
for modName, modValue in Shared.skpairs(modifiers) do
                local includedMod = Shared.contains(modifierNames, modName)
                local valueArray = nil
                if type(modValue) ~= 'table' then
                    valueArray = {modValue}
                else
                    valueArray = modValue
                end
 
                for j, subVal in ipairs(valueArray) do
                    local includeInMainText = includedMod
                    if type(subVal) == 'table' and subVal.skillID ~= nil then
                        -- Modifier value is skill specific
                        if includeInMainText then
                            -- If the skill doesn't match then don't include in the main text
                            includeInMainText = skill == nil or skill == '' or subVal.skillID == skill
                        end
                        subVal = {subVal}
                    end
 
                    if includeInMainText then
                        table.insert(mainModText, Constants._getModifierText(modName, subVal))
                    else
                        otherModCount = otherModCount + 1
                        local key = ((maxOtherMods == nil or otherModCount <= maxOtherMods) and 'visible') or 'overflow'
                        table.insert(modTextArray[key], Constants._getModifierText(modName, subVal))
                    end
                end
            end
 
local overflowModCount = Shared.tableCount(modTextArray['overflow'])
if overflowModCount == 1 then
table.insert(modTextArray['visible'], modTextArray['overflow'][1])
end
local otherModText = {table.concat(modTextArray['visible'], '<br/>')}
 
if overflowModCount > 1 then
-- Number of other modifiers for the object exceed the specified maximum
table.insert(otherModText, '<br/><span class="mw-collapsible mw-collapsed" ')
table.insert(otherModText, 'data-expandtext="Show ' .. Shared.formatnum(overflowModCount) .. ' more modifiers", data-collapsetext="Hide">')
table.insert(otherModText, table.concat(modTextArray['overflow'], '<br/>') .. '</span>')
end
return table.concat(mainModText, '<br/>'), table.concat(otherModText)
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 ipairs(itemList) do
local row = {}
row.name = item.name
row.icon = Icons.Icon({item.name, type='item'})
row.expIcon = Icons.getExpansionIcon(item.id)
row.type = 'Item'
--For equipment, show the slot they go in
if item.validSlots ~= nil then
row.type = row.type..' ('..table.concat(Shared.clone(item.validSlots), ', ')..')'
end
row.typeText = row.type
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 not hasOtherModifiers and 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.expIcon = Icons.getExpansionIcon(pet.id)
row.type = '[[Pets|Pet]]'
row.typeText = '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 not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
hasOtherModifiers = true
end
 
table.insert(tableArray, row)
end
 
local obstList = p.getObstaclesWithModifier(modifiers, skill, getOpposites)
table.sort(obstList, function(a, b) return a.category < b.category end)
for i, obst in Shared.skpairs(obstList) do
local row = {}
row.name = obst.name
row.icon = Icons.Icon({'Agility%23'..string.gsub(obst.name, ' ', ''), obst.name, type='skill', img='Agility'})
row.expIcon = Icons.getExpansionIcon(obst.id)
row.type = '[[Agility#Obstacles|Agility Obstacle '..tostring(tonumber(obst.category)+1)..']]'
row.typeText = 'Agility Obstacle '..string.format("%02d", (obst.category + 1))
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 not hasOtherModifiers and 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 ipairs(pillarList) do
local row = {}
row.name = pillar.name
row.icon = Icons.Icon({'Agility%23'..string.gsub(pillar.name, ' ', ''), pillar.name, type='skill', img='Agility'})
row.expIcon = Icons.getExpansionIcon(pillar.id)
row.type = '[[Agility#Passive Pillars|Agility Pillar]]'
row.typeText = '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 not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
hasOtherModifiers = true
end
 
table.insert(tableArray, row)
end
 
local prayerList = p.getPrayersWithModifier(modifiers, skill, getOpposites)
for i, prayer in ipairs(prayerList) do
local row = {}
row.name = prayer.name
row.icon = Icons.Icon({prayer.name, type='prayer'})
row.expIcon = Icons.getExpansionIcon(prayer.id)
row.type = [[Prayer]]
row.typeText = 'Prayer'
local totalVal = 0
for i, mod in ipairs(modifiers) do
totalVal = totalVal + p.getModifierValue(prayer.modifiers, mod, skill, getOpposites)
end
row.val = totalVal
 
row.modifierText, row.otherModifiers = getModText(prayer.modifiers)
 
if not hasOtherModifiers and 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 ipairs(upgradeList) do
local row = {}
row.name = Shop._getPurchaseName(upgrade)
row.icon = Icons.Icon({row.name, type='upgrade'})
row.expIcon = Icons.getExpansionIcon(upgrade.id)
row.type = '[[Shop|Upgrade]]'
row.typeText = '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 not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
hasOtherModifiers = true
end
 
table.insert(tableArray, row)
end
 
local constellationList = p.getConstellationsWithModifier(modifiers, skill, getOpposites)
for i, cons in ipairs(constellationList) do
local modList = Skills._buildAstrologyModifierArray(cons, nil, true, true, true, true)
local row = {}
row.name = cons.name
row.icon = Icons.Icon({cons.name, type='constellation'})
row.expIcon = Icons.getExpansionIcon(cons.id)
row.type = '[[Astrology#Constellations|Constellation]]'
row.typeText = 'Constellation'
row.modifierText, row.otherModifiers = getModText(modList)
local totalVal = 0
for i, mod in pairs(modifiers) do
totalVal = totalVal + p.getModifierValue(modList, mod, skill, getOpposites)
end
row.val = totalVal
 
if not hasOtherModifiers and string.len(row.otherModifiers) > 0 then
hasOtherModifiers = true
end
 
table.insert(tableArray, row)
end
local POIList = p.getPOIsWithModifier(modifiers, skill, getOpposites)
for i, POI in ipairs(POIList) do
local row = {}
row.name = POI.name
row.icon = Icons.Icon({POI.name, type='poi'})
row.expIcon = Icons.getExpansionIcon(POI.id)
row.type = '[[Cartography|Point of Interest]]'
row.typeText = 'Point of Interest'
local totalVal = 0
for i, mod in ipairs(modifiers) do
totalVal = totalVal + p.getModifierValue(POI.activeModifiers, mod, skill, getOpposites)
end
row.val = totalVal
 
row.modifierText, row.otherModifiers = getModText(POI.activeModifiers)
 
if not hasOtherModifiers and 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 and displayOtherMods then result = result..'!!Other Modifiers' end
 
--Sort by value if only one modifier was passed in
--Otherwise sort alphabetically by type, then name
table.sort(tableArray, function(a, b)
if (modifierCount == 1 or forceMagnitudeSort) and a.val ~= b.val then
return a.val > b.val
elseif a.typeText ~= b.typeText then
return a.typeText < b.typeText
else
return a.name < b.name
end
end)
for i, row in ipairs(tableArray) do
result = result..'\r\n|-'
result = result..'\r\n|data-sort-value="'..row.name..'"|'..row.icon
result = result..'|| data-sort-value="'..row.typeText..'" | '..row.expIcon..row.type..'||data-sort-value="'..row.val..'"| '..row.modifierText
if hasOtherModifiers and displayOtherMods 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]
local displayOtherMods = frame.args ~= nil and frame.args.displayOtherMods or frame.displayOtherMods
local maxOtherMods = frame.args ~= nil and tonumber(frame.args.maxOtherMods) or 5
local forceMagnitudeSort = frame.args ~= nil and string.upper(tostring(frame.args.forceMagnitudeSort)) == 'TRUE' or false
 
if Shared.contains(modifier, ',') then
modifier = Shared.splitString(modifier, ',')
end
 
if getOpposites ~= nil then
getOpposites = string.upper(getOpposites) ~= 'FALSE'
else
getOpposites = true
end
 
if displayOtherMods ~= nil then
displayOtherMods = string.upper(displayOtherMods) ~= 'FALSE'
else
displayOtherMods = true
end
 
return p._getModifierTable(modifier, skill, columnName, getOpposites, displayOtherMods, maxOtherMods, forceMagnitudeSort)
end
 
--Function for console testing of modifier tables
function p.getModifierTableTest()
return p.getModifierTable({args = {'MeleeMaxHit', 'GP Boosts'}})
end
end


return p
return p