Module:ModifierTables
From Melvor Idle
Revision as of 14:07, 18 April 2022 by Auron956 (talk | contribs) (Use Module:Skills instead of Module:Skills/Gathering)
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, Pets, Prayers, and Constellations 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 Skills = require('Module:Skills') local Agility = require('Module:Skills/Agility') local Prayer = require('Module:Prayer') 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] elseif skill == nil or skill == '' then increaseVal = 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] elseif skill == nil or skill == '' then decreaseVal = 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) if item.golbinRaidExclusive ~= nil and item.golbinRaidExclusive then return false end for i, mod in Shared.skpairs(modifiers) do if p.getModifierValue(item.modifiers, mod, skill, getOpposites) ~= 0 then return true end end return false end) return itemList end function p.getObstaclesWithModifier(modifiers, skill, getOpposites) if type(modifiers) == 'string' then modifiers = {modifiers} end local obstList = Agility.getObstacles( function(obst) for i, mod in Shared.skpairs(modifiers) do if p.getModifierValue(obst.modifiers, mod, skill, getOpposites) ~= 0 then return true end end return false end) return obstList end function p.getConstellationsWithModifier(modifiers, skill, getOpposites) if type(modifiers) == 'string' then modifiers = {modifiers} end local consList = Skills.getConstellations( 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 function p.getPillarsWithModifier(modifiers, skill, getOpposites) if type(modifiers) == 'string' then modifiers = {modifiers} end local pillarList = Agility.getPillars( function(pillar) for i, mod in Shared.skpairs(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 Shared.skpairs(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(category, purchase) if category == 'GolbinRaid' then return false end for i, mod in Shared.skpairs(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._getModifierTable(modifiers, skill, columnName, getOpposites, displayOtherMods, maxOtherMods) 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 = { ["visible"] = {}, ["overflow"] = {} } local otherModCount = 0 local mainModText = {} for modName, modValue in Shared.skpairs(modifiers) do if Shared.contains(modifierNames, modName) then if type(modValue) == 'table' and type(modValue[1]) == 'table' then for j, subVal in ipairs(modValue) do if subVal[1] == skill or skill == nil or skill == '' 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 else table.insert(mainModText, Constants._getModifierText(modName, modValue)) end else modValue = (type(modValue) == 'table' and type(modValue[1]) == 'table' and modValue or {modValue}) for j, subValue in ipairs(modValue) do otherModCount = otherModCount + 1 local key = ((maxOtherMods == nil or otherModCount <= maxOtherMods) and 'visible') or 'overflow' table.insert(modTextArray[key], Constants._getModifierText(modName, subValue)) 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 Shared.skpairs(itemList) do local row = {} row.name = item.name row.icon = Icons.Icon({item.name, type='item'}) row.type = 'Item' --For equipment, show the slot they go in if item.validSlots ~= nil then row.type = row.type..' ('..table.concat(item.validSlots, ', ')..')' end 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.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 not hasOtherModifiers and 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 '..tostring(tonumber(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 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 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.type = [[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 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 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 row = {} row.name = cons.name row.icon = Icons.Icon({cons.name, type='constellation'}) row.type = '[[Astrology#Constellations|Constellation]]' row.val = 15 -- Assume highest possible, the range is 1 to 15 inclusive local modList = Skills._buildAstrologyModifierArray(cons, {1, 15}, true, true, true, true) row.modifierText, row.otherModifiers = getModText(modList) 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 and a.val ~= b.val then return a.val > b.val elseif a.type ~= b.type then return a.type < b.type else 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 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 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) end return p