Module:Constants: Difference between revisions

From Melvor Idle
(Fixed typo on prayer point costs)
No edit summary
 
(154 intermediate revisions by 7 users not shown)
Line 1: Line 1:
local p = {}
local p = {}


local ConstantData = mw.loadData('Module:Constants/data')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local Modifiers = require('Module:Modifiers')
 
function p.getTriangleAttribute(attribute, attackerStyle, targetStyle, modeName)
if type(attribute) ~= 'string' then
error("Parameter 'attribute' must be a string", 2)
elseif type(attackerStyle) ~= 'string' then
error("Parameter 'attackerStyle' must be a string", 2)
elseif type(targetStyle) ~= 'string' then
error("Parameter 'targetStyle' must be a string", 2)
elseif type(modeName) ~= 'string' then
error("Parameter 'modeName' must be a string", 2)
end
local mode = GameData.getEntityByName('gamemodes', modeName)
if mode == nil then
error("Invalid gamemode '" .. modeName .. "'", 2)
end
local attStyle, targStyle = string.lower(attackerStyle), string.lower(targetStyle)
local validStyles = { 'magic', 'melee', 'ranged' }
if not Shared.contains(validStyles, string.lower(attStyle)) then
error("Invalid value for parameter 'attackerStyle'", 2)
elseif not Shared.contains(validStyles, string.lower(targStyle)) then
error("Invalid value for parameter 'targetStyle'", 2)
end
local combatTriangle = GameData.getEntityByID('combatTriangles', mode.combatTriangle)
if combatTriangle == nil then
error("No such combat triangle: " .. mode.combatTriangle)
end
local attrData = combatTriangle[attribute]
if attrData == nil then
error("No such attribute: " .. attribute)
else
return attrData[attStyle][targStyle]
end
end
 
function p.getTriangleDamageModifier(attackerStyle, targetStyle, mode)
return p.getTriangleAttribute('damageModifier', attackerStyle, targetStyle, mode)
end


local Shared = require('Module:Shared')
--Syntax is like p.getTriangleDRModifier('Melee', 'Ranged', 'Normal')
--Returns a multiplier that can be multiplied with base DR to get the post-Triangle result
function p.getTriangleDRModifier(attackerStyle, targetStyle, mode)
return p.getTriangleAttribute('reductionModifier', attackerStyle, targetStyle, mode)
end


--Just hardcoding these because I guess that's where we're at
function p.getDifficultyString(difficulty)
local modifierTypes = {
return GameData.rawData.combatAreaDifficulties[difficulty + 1]
  ["increasedGlobalAccuracy"] = { text =  "+{V}% Global Accuracy", },
end
  ["increasedMeleeAccuracyBonus"] = { text =  "+{V}% Melee Accuracy Bonus", },
  ["increasedMeleeStrengthBonus"] = { text =  "+{V}% Melee Strength Bonus", },
  ["increasedMeleeEvasion"] = { text =  "+{V}% Melee Evasion", },
  ["increasedRangedAccuracyBonus"] = { text =  "+{V}% Ranged Accuracy Bonus", },
  ["increasedRangedStrengthBonus"] = { text =  "+{V}% Ranged Strength Bonus", },
  ["increasedRangedEvasion"] = { text =  "+{V}% Ranged Evasion", },
  ["increasedMagicAccuracyBonus"] = { text =  "+{V}% Magic Accuracy Bonus", },
  ["increasedMagicDamageBonus"] = { text =  "+{V}% Magic Damage Bonus", },
  ["increasedMagicEvasion"] = { text =  "+{V}% Magic Evasion", },
  ["increasedMaxHitFlat"] = { text =  "+{VX} Max Hit", },
  ["increasedMaxHitPercent"] = { text =  "+{V}% Max Hit", },
  ["increasedDamageReduction"] = { text =  "+{V}% Damage Reduction", },
  ["increasedChanceToDoubleLootCombat"] = { text =  "+{V}% Chance To Double Loot in Combat", },
  ["increasedSlayerCoins"] = { text =  "+{V}% Slayer Coins", },
  ["increasedSlayerXP"] = { text =  "+{V}% Slayer XP", },
  ["increasedHPRegenFlat"] = { text =  "+{V} Flat HP Regen", },
  ["increasedGPGlobal"] = { text =  "+{V}% Global GP (except Item Sales)", },
  ["increasedGPFromMonsters"] = { text =  "+{V}% GP From Monsters", },
  ["increasedGPFromMonstersFlat"] = { text =  "+{V} GP From Monsters", },
  ["increasedGPFromThieving"] = { text =  "+{V}% GP From Thieving", },
  ["increasedGPFromThievingFlat"] = { text =  "+{V} GP From Thieving", },
  ["increasedGPFromAgility"] = { text =  "+{V}% GP From Agility", },
  ["decreasedGPFromAgility"] = { text =  "-{V}% GP From Agility", isNegative = true },
  ["increasedDamageToBosses"] = { text =  "+{V}% Damage To Bosses", },
  ["increasedDamageToSlayerTasks"] = { text =  "+{V}% Damage To Slayer Tasks", },
  ["increasedDamageToSlayerAreaMonsters"] = { text =  "+{V}% Damage To Slayer Area Monsters", },
  ["increasedDamageToCombatAreaMonsters"] = { text =  "+{V}% Damage To Combat Area Monsters", },
  ["increasedDamageToDungeonMonsters"] = { text =  "+{V}% Damage To Dungeon Monsters", },
  ["increasedDamageToAllMonsters"] = { text =  "+{V}% Damage To All Monsters", },
  ["increasedAutoEatEfficiency"] = { text =  "+{V}% Auto Eat Efficiency", },
  ["increasedAutoEatThreshold"] = { text =  "+{V}% Auto Eat Threshold", },
  ["increasedAutoEatHPLimit"] = { text =  "+{V}% Auto Eat HP Limit", },
  ["increasedFoodHealingValue"] = { text =  "+{V}% Food Healing Value", },
  ["increasedChanceToPreservePrayerPoints"] = { text =  "+{V}% Chance To Preserve Prayer Points", },
  ["increasedFlatPrayerCostReduction"] = { text =  "+{V} Flat Prayer Cost Reduction", },
  ["increasedMinAirSpellDmg"] = { text =  "+{V} Min Air Spell Dmg", },
  ["increasedMinWaterSpellDmg"] = { text =  "+{V} Min Water Spell Dmg", },
  ["increasedMinEarthSpellDmg"] = { text =  "+{V} Min Earth Spell Dmg", },
  ["increasedMinFireSpellDmg"] = { text =  "+{V} Min Fire Spell Dmg", },
  ["increasedAmmoPreservation"] = { text =  "+{V}% Ammo Preservation", },
  ["increasedRunePreservation"] = { text =  "+{V}% Rune Preservation", },
  ["increasedHiddenSkillLevel"] = { text =  "+{V1} Hidden {SV0} Level", },
  ["decreasedPlayerAttackSpeed"] = { text =  "-{V} Player Attack Speed", },
  ["decreasedPlayerAttackSpeedPercent"] = { text =  "-{V}% Player Attack Speed", },
  ["increasedSlayerAreaEffectNegationFlat"] = { text =  "+{V}% Flat Slayer Area Effect Negation", },
  ["decreasedMonsterRespawnTimer"] = { text =  "-{VMS}s Monster Respawn Timer", },
  ["decreasedGlobalAccuracy"] = { text =  "-{V}% Global Accuracy", isNegative = true },
  ["decreasedMeleeAccuracyBonus"] = { text =  "-{V}% Melee Accuracy Bonus", isNegative = true },
  ["decreasedMeleeStrengthBonus"] = { text =  "-{V}% Melee Strength Bonus", isNegative = true },
  ["decreasedMeleeEvasion"] = { text =  "-{V}% Melee Evasion", isNegative = true },
  ["decreasedRangedAccuracyBonus"] = { text =  "-{V} Ranged Accuracy Bonus", isNegative = true },
  ["decreasedRangedStrengthBonus"] = { text =  "-{V}% Ranged Strength Bonus", isNegative = true },
  ["decreasedRangedEvasion"] = { text =  "-{V}% Ranged Evasion", isNegative = true },
  ["decreasedMagicAccuracyBonus"] = { text =  "-{V}% Magic Accuracy Bonus", isNegative = true },
  ["decreasedMagicDamageBonus"] = { text =  "-{V}% Magic Damage Bonus", isNegative = true },
  ["decreasedMagicEvasion"] = { text =  "-{V}% Magic Evasion", isNegative = true },
  ["decreasedMaxHitFlat"] = { text =  "-{V} Max Hit", isNegative = true },
  ["decreasedMaxHitPercent"] = { text =  "-{V}% Max Hit", isNegative = true },
  ["decreasedDamageReduction"] = { text =  "-{V}% Damage Reduction", isNegative = true },
  ["decreasedChanceToDoubleLootCombat"] = { text =  "-{V}% Chance To Double Loot in Combat", isNegative = true },
  ["decreasedSlayerCoins"] = { text =  "-{V}% Slayer Coins", isNegative = true },
  ["decreasedSlayerXP"] = { text =  "-{V}% Slayer XP", isNegative = true },
  ["decreasedHPRegenFlat"] = { text =  "-{V} Flat HP Regen", isNegative = true },
  ["decreasedGPGlobal"] = { text =  "-{V}% GP from all sources (Except Item Selling)", isNegative = true },
  ["decreasedGPFromMonsters"] = { text =  "-{V}% GP From Monsters", isNegative = true },
  ["decreasedGPFromMonstersFlat"] = { text =  "-{V} GP From Monsters", isNegative = true },
  ["decreasedDamageToBosses"] = { text =  "-{V}% Damage To Bosses", isNegative = true },
  ["decreasedDamageToSlayerTasks"] = { text =  "-{V}% Damage To Slayer Tasks", isNegative = true },
  ["decreasedDamageToSlayerAreaMonsters"] = { text =  "-{V}% Damage To Slayer Area Monsters", isNegative = true },
  ["decreasedDamageToCombatAreaMonsters"] = { text =  "-{V}% Damage To Combat Area Monsters", isNegative = true },
  ["decreasedDamageToDungeonMonsters"] = { text =  "-{V}% Damage To Dungeon Monsters", isNegative = true },
  ["decreasedDamageToAllMonsters"] = { text =  "-{V}% Damage To All Monsters", isNegative = true },
  ["decreasedAutoEatEfficiency"] = { text =  "-{V}% Auto Eat Efficiency", isNegative = true },
  ["decreasedAutoEatThreshold"] = { text =  "-{V}% Auto Eat Threshold", isNegative = true },
  ["decreasedAutoEatHPLimit"] = { text =  "-{V}% Auto Eat HP Limit", isNegative = true },
  ["decreasedFoodHealingValue"] = { text =  "-{V}% Food Healing Value", isNegative = true },
  ["decreasedChanceToPreservePrayerPoints"] = { text =  "-{V}% Chance To Preserve Prayer Points", isNegative = true },
  ["decreasedFlatPrayerCostReduction"] = { text =  "-{V} Flat Prayer Cost Reduction", isNegative = true },
  ["decreasedMinAirSpellDmg"] = { text =  "-{V} Min Air Spell Dmg", isNegative = true },
  ["decreasedMinWaterSpellDmg"] = { text =  "-{V} Min Water Spell Dmg", isNegative = true },
  ["decreasedMinEarthSpellDmg"] = { text =  "-{V} Min Earth Spell Dmg", isNegative = true },
  ["decreasedMinFireSpellDmg"] = { text =  "-{V} Min Fire Spell Dmg", isNegative = true },
  ["decreasedAmmoPreservation"] = { text =  "-{V}% Ammo Preservation", isNegative = true },
  ["decreasedRunePreservation"] = { text =  "-{V}% Rune Preservation", isNegative = true },
  ["decreasedHiddenSkillLevel"] = { text =  "-{V1} Hidden {SV0} Level", isNegative = true },
  ["increasedPlayerAttackSpeed"] = { text =  "+{V} Player Attack Speed", isNegative = true },
  ["increasedPlayerAttackSpeedPercent"] = { text =  "+{V}% Player Attack Speed", isNegative = true },
  ["increasedMonsterRespawnTimer"] = { text =  "+{VMS}s Monster Respawn Timer", isNegative = true },
  ["decreasedSlayerAreaEffectNegationFlat"] = { text =  "-{V}% Flat Slayer Area Effect Negation", isNegative = true },
  ["increasedGPFromSales"] = { text =  "+{V}% GP From Sales", },
  ["increasedBankSpace"] = { text =  "+{V} Bank Space", },
  ["increasedBankSpaceShop"] = { text =  "+{V} Bank Space from Shop", },
  ["increasedChanceToPreservePotionCharge"] = { text =  "+{V}% Chance To Preserve Potion Charge", },
  ["decreasedGPFromSales"] = { text =  "-{V}% GP From Sales", isNegative = true },
  ["decreasedBankSpace"] = { text =  "-{V} Bank Space", isNegative = true },
  ["decreasedBankSpaceShop"] = { text =  "-{V} Bank Space from Shop", isNegative = true },
  ["decreasedChanceToPreservePotionCharge"] = { text =  "-{V}% Chance To Preserve Potion Charge", isNegative = true },
  ["decreasedSkillInterval"] = { text =  "-{V1} {SV0} Interval", },
  ["decreasedSkillIntervalPercent"] = { text =  "-{V1}% {SV0} Interval", },
  ["increasedChanceToDoubleLootThieving"] = { text =  "+{V}% Chance To Double Loot in Thieving", },
  ["increasedPreservationChance"] = { text =  "+{V}% Chance to Preserve Resources", },
  ["increasedStaminaPreservationChance"] = { text =  "+{V}% Chance to Preserve Stamina", },
  ["increasedGlobalMasteryXP"] = { text =  "+{V}% Global Mastery XP", },
  ["increasedGlobalSkillXP"] = { text =  "+{V}% Global Skill XP", },
  ["decreasedGlobalSkillXP"] = { text =  "-{V}% Global Skill XP", isNegative = true },
  ["increasedMasteryXP"] = { text =  "+{V1}% {SV0} Mastery XP", },
  ["increasedSkillXP"] = { text =  "+{V1}% {SV0} Skill XP", },
  ["increasedMaxStamina"] = { text =  "+{V}% Max Stamina", },
  ["increasedMiningNodeHP"] = { text =  "+{V} Mining Node HP", },
  ["increasedSkillInterval"] = { text =  "+{V1} {SV0} Interval", isNegative = true },
  ["increasedSkillIntervalPercent"] = { text =  "+{V1}% {SV0} Interval", isNegative = true },
  ["decreasedChanceToDoubleLootThieving"] = { text =  "-{V}% Chance To Double Loot in Thieving", isNegative = true },
  ["decreasedPreservationChance"] = { text =  "-{V}% Chance to Preserve Resources", isNegative = true },
  ["decreasedStaminaPreservationChance"] = { text =  "-{V}% Chance to Preserve Stamina", isNegative = true },
  ["decreasedGlobalMasteryXP"] = { text =  "-{V}% Global Mastery XP", isNegative = true },
  ["decreasedMasteryXP"] = { text =  "-{V1}% {SV0} Mastery XP", isNegative = true },
  ["decreasedSkillXP"] = { text =  "-{V1}% {SV0} Skill XP", isNegative = true },
  ["decreasedMaxStamina"] = { text =  "-{V} Max Stamina", isNegative = true },
  ["decreasedMiningNodeHP"] = { text =  "-{V} Mining Node HP", isNegative = true },
  ["decreasedGPFromThieving"] = { text =  "-{V}% GP From Thieving", isNegative = true },
  ["decreasedGPFromThievingFlat"] = { text =  "-{V} GP From Thieving", isNegative = true },
  ["dungeonEquipmentSwapping"] = { text =  "{V} Dungeon Equipment Swapping", },
  ["increasedEquipmentSets"] = { text =  "+{V} Equipment Sets", },
  ["autoSlayerUnlocked"] = { text =  "{V} Auto Slayer Unlocked", },
  ["increasedTreeCutLimit"] = { text =  "+{V} Tree Cut Limit", },
  ["increasedChanceToDoubleItems"] = { text =  "+{V} Chance To Double Items", },
  ["decreasedChanceToDoubleItems"] = { text =  "-{V} Chance To Double Items", isNegative = true },
  ["increasedGlobalPreservationChance"] = { text =  "+{V}% Chance to Preserve Resources in Skills", },
  ["decreasedGlobalPreservationChance"] = { text =  "-{V}% Chance to Preserve Resources in Skills", isNegative = true },
  ["increasedFarmingYield"] = { text =  "+{V}% Farming Yield", },
  ["decreasedFarmingYield"] = { text =  "-{V}% Farming Yield", isNegative = true },
  ["increasedMaxHitpoints"] = { text =  "+{VX} Maximum Hitpoints", },
  ["decreasedMaxHitpoints"] = { text =  "-{VX} Maximum Hitpoints", isNegative = true },
  ["increasedStaminaPerObstacle"] = { text =  "+{V} Stamina per Agility Obstacle Completion", },
  ["decreasedStaminaPerObstacle"] = { text =  "+{V} Stamina per Agility Obstacle Completion", isNegative = true },
  ["increasedSlayerTaskLength"] = { text =  "+{V}% Slayer Task Length/Qty", },
  ["decreasedSlayerTaskLength"] = { text =  "+{V}% Slayer Task Length/Qty", isNegative = true },
  ["decreasedFlatPrayerCostReduction"] = { text =  "+{V} Prayer Point Cost for Prayers", isNegative = true },
  ["increasedFlatPrayerCostReduction"] = { text =  "-{V} Prayer Point Cost for Prayers", },
  ["increasedStaminaCost"] = { text =  "+{V} Stamina Cost per action", isNegative = true },
  ["decreasedStaminaCost"] = { text =  "+{V} Stamina Cost per action", },
  ["increasedChanceToDoubleItemsSkill"] = { text =  "+{V1}% Chance to Double Items in {SV0}", },
  ["decreasedChanceToDoubleItemsSkill"] = { text =  "+{V1}% Chance to Double Items in {SV0}", isNegative = true },
  ["increasedChanceToDoubleItemsGlobal"] = { text =  "+{V}% Chance to Double Items Globally", },
  ["decreasedChanceToDoubleItemsGlobal"] = { text =  "+{V}% Chance to Double Items Globally", isNegative = true },
  ["increasedLifesteal"] = { text =  "+{V}% Lifesteal", },
  ["decreasedLifesteal"] = { text =  "+{V}% Lifesteal", isNegative = true },
  ["increasedReflectDamage"] = { text = "+{V}% Reflect Damage", },
  ["decreasedReflectDamage"] = { text = "+{V}% Reflect Damage", isNegative = true },
  ["increasedSkillPreservationChance"] = { text = "+{V1}% Chance to Preserve Resources in {SV0}", },
  ["decreasedSkillPreservationChance"] = { text = "-{V1}% Chance to Preserve Resources in {SV0}", isNegative = true},
  ["increasedChanceToDoubleOres"] = { text = "+{V}% Chance to Double Ores in Mining" },
  ["decreasedChanceToDoubleOres"] = { text = "-{V}% Chance to Double Ores in Mining", isNegative = true },
  ["increasedHitpointRegeneration"] = { text = "+{V}% Hitpoint Regeneration" },
  ["decreasedHitpointRegeneration"] = { text = "-{V}% Hitpoint Regeneration", isNegative = true },
  ["increasedMinHitBasedOnMaxHit"] = { text = "+{V}% of Maximum Hit added to Minimum Hit" },
  ["decreasedMinHitBasedOnMaxHit"] = { text = "-{V}% of Maximum Hit added to Minimum Hit", isNegative = true },
  ["increasedPotionChargesFlat"] = { text = "+{V} Charges per Potion" },
  ["decreasedPotionChargesFlat"] = { text = "-{V} Charges per Potion", isNegative = true }
}


function p.getSkillName(skillID)
function p.getSkillName(skillID)
  for skName, ID in Shared.skpairs(ConstantData.skill) do
local skill = GameData.getSkillData(skillID)
    if ID == skillID then
if skill ~= nil then
      return skName
return skill.name
    end
end
  end
end
  return nil
 
function p.getSkillID(skillName)
for i, skillData in ipairs(GameData.rawData.skillData) do
if skillData.data.name == skillName then
return skillData.skillID
end
end
end
 
function p.getSkillIDText(frame)
local skillName = frame.args ~= nil and frame.args[1] or frame[1]
local id = p.getSkillID(skillName)
if id == nil or id == '' then
return "Unknown"
else
return id
end
end
 
function p.getEquipmentSlotName(id)
local slotData = GameData.getEntityByID('equipmentSlots', id)
if slotData ~= nil then
return slotData.emptyName
end
end
 
function p.getEquipmentSlotID(name)
local slotData = GameData.getEntityByProperty('equipmentSlots', 'emptyName', name)
if slotData ~= nil then
return slotData.id
end
end
 
function p.getCombatStyleName(styleNum)
if type(styleNum) == 'number' then
local styleName = GameData.rawData.attackTypes[styleNum]
if styleName ~= nil then
return Shared.titleCase(styleName)
end
elseif type(styleNum) == 'string' and type(GameData.rawData.attackTypes[string.lower(styleNum)]) == 'number' then
return Shared.titleCase(styleNum)
end
return Shared.printError('Invalid combat style')
end
 
 
--- Slayer functions
--
function p.getSlayerTierByID(tierID)
if type(tierID) ~= 'number' then
return nil
else
return GameData.rawData.slayerTaskCategories[tierID + 1]
end
end
 
function p.getSlayerTier(name)
return GameData.getEntityByProperty('slayerTiers', 'display', name)
end
 
function p.getSlayerTierByLevel(level)
if type(level) ~= 'number' or level < 1 then
return Shared.printError('Invalid Slayer level')
end
 
for i, tier in ipairs(GameData.rawData.slayerTaskCategories) do
if tier.type == 'CombatLevel' and tier.minLevel <= level and (tier.maxLevel == nil or tier.maxLevel >= level) then
return tier
end
end
end
 
--
-- the following functions just return subsets of the slayer functions above
--
 
function p.getSlayerTierName(tierID)
if type(tierID) == 'number' then
local tier = p.getSlayerTierByID(tierID)
if tier ~= nil then
return tier.display
end
end
return Shared.printError('Invalid Slayer tier')
end
 
function p.getSlayerTierNameByLevel(lvl)
local tier = p.getSlayerTierByLevel(lvl)
if type(tier) == 'table' then
return tier.display
else
return Shared.printError('Invalid Slayer tier')
end
end
 
--
--- End of slayer functions
 
--Turns a modifier name like 'increasedHPRegenFlat' into several pieces of data:
--Base Name, Description, IsNegative, and modifyValue
--ex. "HPRegenFlat", "+${value} Flat Hitpoints Regeneration", false, "multiplyByNumberMultiplier"
function p.getModifierDetails(modifierName)
-- Unsupported
error('Function is no longer supported', 2)
--[==[
local baseName = modifierName
local modifier = GameData.rawData.modifierData[modifierName]
 
if modifier == nil then
return nil
end
 
if Shared.startsWith(modifierName, "increased") or Shared.startsWith(modifierName, "decreased") then
baseName = string.sub(modifierName, 10)
end
 
return baseName, modifier.description, modifier.isNegative, modifier.modifyValue
--]==]
end
 
function p._getModifierText(modifier, value, doColor)
return Modifiers.getModifierText(modifier, value, doColor)
end
 
function p.getModifierText(frame)
local modifier = frame.args ~= nil and frame.args[1] or frame[1]
local value = frame.args ~= nil and frame.args[2] or frame[2]
local skill = frame.args ~= nil and frame.args.skill or frame.skill
local doColor = frame.args ~= nil and frame.args[3] or frame[3]
 
if doColor ~= nil then
doColor = string.upper(doColor) ~= 'FALSE'
end
 
if skill ~= nil and skill ~= '' then
value = { { ["skillID"] = p.getSkillID(skill), ["value"] = value } }
end
 
return p._getModifierText(modifier, value, doColor)
end
 
function p.getModifiersText(modifiers, doColor, inline, maxVisible)
return Modifiers.getModifiersText(modifiers, doColor, inline, maxVisible)
end
end


function p.getModifierSkills(modifiers)
return Modifiers.getModifierSkills(modifiers)
end


function p.getModifierText(modifier, value, doColor)
-- Returns a modifiers table indicating modifiersNew less modifiersOld
  if doColor == nil then doColor = true end
-- The returned table can be passed to getModifiersText to obtain the
  local template = modifierTypes[modifier]
-- result in a human readable format
function p.getModifiersDifference(modifiersOld, modifiersNew)
local modHasPrefix = {}
local modDiff, modDiffBase = {}, {}
local allMods = {
{ ["mods"] = (modifiersNew or {}), ["mult"] = 1 },
{ ["mods"] = (modifiersOld or {}), ["mult"] = -1 }
}


  if template == nil then
-- Generate modifiers table containing only variances
    return 'ERROR: Invalid modifier type [[Category:Pages with script errors]]'
-- Create modDiffBase with mod base names (less 'increased'/'decreased' prefixes),
  end
for i, modDef in ipairs(allMods) do
for modName, value in pairs(modDef.mods) do
local modBaseName, modIsIncrease = modName, true
if Shared.startsWith(modName, "increased") or Shared.startsWith(modName, "decreased") then
modBaseName = string.sub(modName, 10)
modIsIncrease = Shared.startsWith(modName, "increased")
modHasPrefix[modBaseName] = true
end
local modMult = (modIsIncrease and 1 or -1) * modDef.mult


  local result = template.text
if type(value) == 'table' then
-- Skill specific modifier
if modDiffBase[modBaseName] == nil then
modDiffBase[modBaseName] = {}
end
for j, subVal in ipairs(value) do
if type(subVal) == 'table' and subVal.skillID ~= nil then
modDiffBase[modBaseName][subVal.skillID] = (modDiffBase[modBaseName][subVal.skillID] or 0) + subVal.value * modMult
end
end
else
modDiffBase[modBaseName] = (modDiffBase[modBaseName] or 0) + value * modMult
end
end
end


  if type(value) == 'table' then
-- Transform modDiffBase into modDiff with the appropriate mod name within the return value
    if Shared.tableCount(value) == 1 and type(value[1]) == 'table' then
for modBaseName, value in pairs(modDiffBase) do
      value = value[1]
if type(value) == 'table' then
    end
-- Skill specific modifier
    if value[1] ~= nil then
for skillID, subVal in pairs(value) do
      local skillName = p.getSkillName(value[1])
if subVal ~= 0 then
      if skillName ~= nil then
local modName = nil
        result = string.gsub(result, '{SV0}', p.getSkillName(value[1]))
if modHasPrefix[modBaseName] then
      end
modName = (subVal < 0 and 'decreased' or 'increased') .. modBaseName
    end
else
    if value[2] ~= nil then
modName = modBaseName
      result = string.gsub(result, '{V1}', value[2])
end
    end
if modDiff[modName] == nil then
  else
modDiff[modName] = {}
    result = string.gsub(result, '{V}', value)
end
    result = string.gsub(result, '{VMS}', value / 1000)
table.insert(modDiff[modName], { ["skillID"] = skillID, ["value"] = math.abs(subVal) })
    result = string.gsub(result, '{VX}', value * 10)
end
  end
end
elseif value ~= 0 then
local modName = nil
if modHasPrefix[modBaseName] then
modName = (value < 0 and 'decreased' or 'increased') .. modBaseName
else
modName = modBaseName
end
modDiff[modName] = (modDiff[modName] or 0) + math.abs(value)
if GameData.rawData.modifierData[modName] == nil then
modDiff[modName] = nil
end
end
end


  if doColor then
return modDiff
    if template.isNegative ~= nil and template.isNegative then
end
      result = '<span style="color:red">'..result..'</span>'
    else
      result = '<span style="color:green">'..result..'</span>'
    end
  end


  return result
-- From game version 1.1 onwards, some entities have custom descriptions, while
-- many are generated based on the modifiers associated to that entity. This
-- function handles that logic given a custom description (may be nil) and
-- a modifiers object
function p.getDescription(customDescription, modifiers)
if customDescription ~= nil then
return customDescription
else
return p.getModifiersText(modifiers, false)
end
end
end


return p
return p

Latest revision as of 22:37, 22 June 2024

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

local p = {}

local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local Modifiers = require('Module:Modifiers')

function p.getTriangleAttribute(attribute, attackerStyle, targetStyle, modeName)
	if type(attribute) ~= 'string' then
		error("Parameter 'attribute' must be a string", 2)
	elseif type(attackerStyle) ~= 'string' then
		error("Parameter 'attackerStyle' must be a string", 2)
	elseif type(targetStyle) ~= 'string' then
		error("Parameter 'targetStyle' must be a string", 2)
	elseif type(modeName) ~= 'string' then
		error("Parameter 'modeName' must be a string", 2)
	end
	
	local mode = GameData.getEntityByName('gamemodes', modeName)
	if mode == nil then
		error("Invalid gamemode '" .. modeName .. "'", 2)
	end
	
	local attStyle, targStyle = string.lower(attackerStyle), string.lower(targetStyle)
	local validStyles = { 'magic', 'melee', 'ranged' }
	if not Shared.contains(validStyles, string.lower(attStyle)) then
		error("Invalid value for parameter 'attackerStyle'", 2)
	elseif not Shared.contains(validStyles, string.lower(targStyle)) then
		error("Invalid value for parameter 'targetStyle'", 2)
	end
	
	local combatTriangle = GameData.getEntityByID('combatTriangles', mode.combatTriangle)
	if combatTriangle == nil then
		error("No such combat triangle: " .. mode.combatTriangle)
	end
	local attrData = combatTriangle[attribute]
	if attrData == nil then
		error("No such attribute: " .. attribute)
	else
		return attrData[attStyle][targStyle]
	end
end

function p.getTriangleDamageModifier(attackerStyle, targetStyle, mode)
	return p.getTriangleAttribute('damageModifier', attackerStyle, targetStyle, mode)
end

--Syntax is like p.getTriangleDRModifier('Melee', 'Ranged', 'Normal')
--Returns a multiplier that can be multiplied with base DR to get the post-Triangle result
function p.getTriangleDRModifier(attackerStyle, targetStyle, mode)
	return p.getTriangleAttribute('reductionModifier', attackerStyle, targetStyle, mode)
end

function p.getDifficultyString(difficulty)
	return GameData.rawData.combatAreaDifficulties[difficulty + 1]
end

function p.getSkillName(skillID)
	local skill = GameData.getSkillData(skillID)
	if skill ~= nil then
		return skill.name
	end
end

function p.getSkillID(skillName)
	for i, skillData in ipairs(GameData.rawData.skillData) do
		if skillData.data.name == skillName then
			return skillData.skillID
		end
	end
end

function p.getSkillIDText(frame)
	local skillName = frame.args ~= nil and frame.args[1] or frame[1]
	local id = p.getSkillID(skillName)
	
	if id == nil or id == '' then
		return "Unknown"
	else
		return id
	end
end

function p.getEquipmentSlotName(id)
	local slotData = GameData.getEntityByID('equipmentSlots', id)
	if slotData ~= nil then
		return slotData.emptyName
	end
end

function p.getEquipmentSlotID(name)
	local slotData = GameData.getEntityByProperty('equipmentSlots', 'emptyName', name)
	if slotData ~= nil then
		return slotData.id
	end
end

function p.getCombatStyleName(styleNum)
	if type(styleNum) == 'number' then
		local styleName = GameData.rawData.attackTypes[styleNum]
		if styleName ~= nil then
			return Shared.titleCase(styleName)
		end
	elseif type(styleNum) == 'string' and type(GameData.rawData.attackTypes[string.lower(styleNum)]) == 'number' then
		return Shared.titleCase(styleNum)
	end
	return Shared.printError('Invalid combat style')
end


--- Slayer functions
--
function p.getSlayerTierByID(tierID)
	if type(tierID) ~= 'number' then
		return nil
	else
		return GameData.rawData.slayerTaskCategories[tierID + 1]
	end
end

function p.getSlayerTier(name)
	return GameData.getEntityByProperty('slayerTiers', 'display', name)
end

function p.getSlayerTierByLevel(level)
	if type(level) ~= 'number' or level < 1 then
		return Shared.printError('Invalid Slayer level')
	end

	for i, tier in ipairs(GameData.rawData.slayerTaskCategories) do
		if tier.type == 'CombatLevel' and tier.minLevel <= level and (tier.maxLevel == nil or tier.maxLevel >= level) then
			return tier
		end
	end
end

--
-- the following functions just return subsets of the slayer functions above
--

function p.getSlayerTierName(tierID)
	if type(tierID) == 'number' then
		local tier = p.getSlayerTierByID(tierID)
		if tier ~= nil then
			return tier.display
		end
	end
	return Shared.printError('Invalid Slayer tier')
end

function p.getSlayerTierNameByLevel(lvl)
	local tier = p.getSlayerTierByLevel(lvl)
	if type(tier) == 'table' then
		return tier.display
	else
		return Shared.printError('Invalid Slayer tier')
	end
end

--
--- End of slayer functions

--Turns a modifier name like 'increasedHPRegenFlat' into several pieces of data:
--Base Name, Description, IsNegative, and modifyValue
--ex. "HPRegenFlat", "+${value} Flat Hitpoints Regeneration", false, "multiplyByNumberMultiplier"
function p.getModifierDetails(modifierName)
	-- Unsupported
	error('Function is no longer supported', 2)
	--[==[
	local baseName = modifierName
	local modifier = GameData.rawData.modifierData[modifierName]

	if modifier == nil then
		return nil
	end

	if Shared.startsWith(modifierName, "increased") or Shared.startsWith(modifierName, "decreased") then
		baseName = string.sub(modifierName, 10)
	end

	return baseName, modifier.description, modifier.isNegative, modifier.modifyValue
	--]==]
end

function p._getModifierText(modifier, value, doColor)
	return Modifiers.getModifierText(modifier, value, doColor)
end

function p.getModifierText(frame)
	local modifier = frame.args ~= nil and frame.args[1] or frame[1]
	local value = frame.args ~= nil and frame.args[2] or frame[2]
	local skill = frame.args ~= nil and frame.args.skill or frame.skill
	local doColor = frame.args ~= nil and frame.args[3] or frame[3]

	if doColor ~= nil then
		doColor = string.upper(doColor) ~= 'FALSE'
	end

	if skill ~= nil and skill ~= '' then
		value = { { ["skillID"] = p.getSkillID(skill), ["value"] = value } }
	end

	return p._getModifierText(modifier, value, doColor)
end

function p.getModifiersText(modifiers, doColor, inline, maxVisible)
	return Modifiers.getModifiersText(modifiers, doColor, inline, maxVisible)
end

function p.getModifierSkills(modifiers)
	return Modifiers.getModifierSkills(modifiers)
end

-- Returns a modifiers table indicating modifiersNew less modifiersOld
-- The returned table can be passed to getModifiersText to obtain the
-- result in a human readable format
function p.getModifiersDifference(modifiersOld, modifiersNew)
	local modHasPrefix = {}
	local modDiff, modDiffBase = {}, {}
	local allMods = {
		{ ["mods"] = (modifiersNew or {}), ["mult"] = 1 },
		{ ["mods"] = (modifiersOld or {}), ["mult"] = -1 }
	}

	-- Generate modifiers table containing only variances
	-- Create modDiffBase with mod base names (less 'increased'/'decreased' prefixes),
	for i, modDef in ipairs(allMods) do
		for modName, value in pairs(modDef.mods) do
			local modBaseName, modIsIncrease = modName, true
			if Shared.startsWith(modName, "increased") or Shared.startsWith(modName, "decreased") then
				modBaseName = string.sub(modName, 10)
				modIsIncrease = Shared.startsWith(modName, "increased")
				modHasPrefix[modBaseName] = true
			end
			local modMult = (modIsIncrease and 1 or -1) * modDef.mult

			if type(value) == 'table' then
				-- Skill specific modifier
				if modDiffBase[modBaseName] == nil then
					modDiffBase[modBaseName] = {}
				end
				for j, subVal in ipairs(value) do
					if type(subVal) == 'table' and subVal.skillID ~= nil then
						modDiffBase[modBaseName][subVal.skillID] = (modDiffBase[modBaseName][subVal.skillID] or 0) + subVal.value * modMult
					end
				end
			else
				modDiffBase[modBaseName] = (modDiffBase[modBaseName] or 0) + value * modMult
			end
		end
	end

	-- Transform modDiffBase into modDiff with the appropriate mod name within the return value
	for modBaseName, value in pairs(modDiffBase) do
		if type(value) == 'table' then
			-- Skill specific modifier
			for skillID, subVal in pairs(value) do
				if subVal ~= 0 then
					local modName = nil
					if modHasPrefix[modBaseName] then
						modName = (subVal < 0 and 'decreased' or 'increased') .. modBaseName
					else
						modName = modBaseName
					end
					if modDiff[modName] == nil then
						modDiff[modName] = {}
					end
					table.insert(modDiff[modName], { ["skillID"] = skillID, ["value"] = math.abs(subVal) })
				end
			end
		elseif value ~= 0 then
			local modName = nil
			if modHasPrefix[modBaseName] then
				modName = (value < 0 and 'decreased' or 'increased') .. modBaseName
			else
				modName = modBaseName
			end
			modDiff[modName] = (modDiff[modName] or 0) + math.abs(value)
			if GameData.rawData.modifierData[modName] == nil then
				modDiff[modName] = nil
			end
		end
	end

	return modDiff
end

-- From game version 1.1 onwards, some entities have custom descriptions, while
-- many are generated based on the modifiers associated to that entity. This
-- function handles that logic given a custom description (may be nil) and
-- a modifiers object
function p.getDescription(customDescription, modifiers)
	if customDescription ~= nil then
		return customDescription
	else
		return p.getModifiersText(modifiers, false)
	end
end

return p