Module:Constants: Difference between revisions

Add many 0.21 modifiers & amend _getModifierText() to support various new substitution options
(_getModifierText: Emit modifier name in error message if invalid)
(Add many 0.21 modifiers & amend _getModifierText() to support various new substitution options)
Line 17: Line 17:
   ["ChanceToDoubleLootCombat"] = { text = "{V}% Chance To Double Loot in Combat", skills = {'Combat'} },
   ["ChanceToDoubleLootCombat"] = { text = "{V}% Chance To Double Loot in Combat", skills = {'Combat'} },
   ["GPFromAgility"] = { text = "{V}% GP From Agility", skills = {'Agility'} },
   ["GPFromAgility"] = { text = "{V}% GP From Agility", skills = {'Agility'} },
   ["SkillXP"] = { text = "{V1}% {SV0} Skill XP" },
   ["SkillXP"] = { text = "{V}% {SV0} Skill XP" },
   ["MiningNodeHP"] = { text = "{V} Mining Node HP", skills = {'Mining'} },
   ["MiningNodeHP"] = { text = "{V} Mining Node HP", skills = {'Mining'} },
  ["StaminaPerObstacle"] = { text = "{V} Stamina per Agility Obstacle Completion", skills = {'Agility'} },
  ["ChanceToDoubleItems"] = { text = "{V} Chance To Double Items" },
   ["FarmingYield"] = { text = "{V}% Farming Yield", skills = {'Farming'} },
   ["FarmingYield"] = { text = "{V}% Farming Yield", skills = {'Farming'} },
   ["GPFromMonstersFlat"] = { text = "{V} GP From Monsters", skills = {'Combat'} },
   ["GPFromMonstersFlat"] = { text = "{V} GP From Monsters", skills = {'Combat'} },
Line 26: Line 24:
   ["RunePreservation"] = { text = "{V}% Rune Preservation", skills = {'Magic'} },
   ["RunePreservation"] = { text = "{V}% Rune Preservation", skills = {'Magic'} },
   ["MaxHitpoints"] = { text = "{VX} Maximum Hitpoints", skills = {'Combat'} },
   ["MaxHitpoints"] = { text = "{VX} Maximum Hitpoints", skills = {'Combat'} },
   ["ChanceToDoubleItemsSkill"] = { text = "{V1}% Chance to Double Items in {SV0}" },
   ["ChanceToDoubleItemsSkill"] = { text = "{V}% Chance to Double Items in {SV0}" },
   ["autoSlayerUnlocked"] = { text = "{V} Auto Slayer Unlocked", skills = {'Slayer'} },
   ["autoSlayerUnlocked"] = { text = "{V} Auto Slayer Unlocked", skills = {'Slayer'} },
   ["HitpointRegeneration"] = { text = "{V}% Hitpoint Regeneration", skills = {'Combat'} },
   ["HitpointRegeneration"] = { text = "{V}% Hitpoint Regeneration", skills = {'Combat'} },
  ["SlayerXP"] = { text = "{V}% Slayer XP", skills = {'Slayer'} },
   ["PotionChargesFlat"] = { text = "{V} Charges per Potion" },
   ["PotionChargesFlat"] = { text = "{V} Charges per Potion" },
   ["SkillInterval"] = { text = "{VMS1}s {SV0} Interval", isIncreaseNegative = true },
   ["SkillInterval"] = { text = "{VMS}s {SV0} Interval", isIncreaseNegative = true },
   ["BankSpace"] = { text = "{V} Bank Space" },
   ["BankSpace"] = { text = "{V} Bank Space" },
   ["MinHitBasedOnMaxHit"] = { text = "{V}% of Maximum Hit added to Minimum Hit", skills = {'Combat'} },
   ["MinHitBasedOnMaxHit"] = { text = "{V}% of Maximum Hit added to Minimum Hit", skills = {'Combat'} },
Line 38: Line 35:
   ["HPRegenFlat"] = { text = "{VX} Flat HP Regen", skills = {'Combat'} },
   ["HPRegenFlat"] = { text = "{VX} Flat HP Regen", skills = {'Combat'} },
   ["ChanceToDoubleOres"] = { text = "{V}% Chance to Double Ores in Mining", skills = {'Combat'} },
   ["ChanceToDoubleOres"] = { text = "{V}% Chance to Double Ores in Mining", skills = {'Combat'} },
  ["MaxStamina"] = { text = "{V} Max Stamina" },
   ["MonsterRespawnTimer"] = { text = "{VMS}s Monster Respawn Timer", isIncreaseNegative = true, skills = {'Combat'} },
   ["MonsterRespawnTimer"] = { text = "{VMS}s Monster Respawn Timer", isIncreaseNegative = true, skills = {'Combat'} },
   ["SkillPreservationChance"] = { text = "{V1}% Chance to Preserve Resources in {SV0}" },
   ["SkillPreservationChance"] = { text = "{V}% Chance to Preserve Resources in {SV0}" },
   ["DamageToCombatAreaMonsters"] = { text = "{V}% Damage To Combat Area Monsters", skills = {'Combat'} },
   ["DamageToCombatAreaMonsters"] = { text = "{V}% Damage To Combat Area Monsters", skills = {'Combat'} },
   ["TreeCutLimit"] = { text = "{V} Tree Cut Limit", skills = {'Woodcutting'} },
   ["TreeCutLimit"] = { text = "{V} Tree Cut Limit", skills = {'Woodcutting'} },
   ["EquipmentSets"] = { text = "{V} Equipment Sets" },
   ["EquipmentSets"] = { text = "{V} Equipment Sets" },
   ["HiddenSkillLevel"] = { text = "{V1} Hidden {SV0} Level" },
   ["HiddenSkillLevel"] = { text = "{V} Hidden {SV0} Level" },
   ["ChanceToPreservePrayerPoints"] = { text = "{V}% Chance To Preserve Prayer Points", skills = {'Prayer'} },
   ["ChanceToPreservePrayerPoints"] = { text = "{V}% Chance To Preserve Prayer Points", skills = {'Prayer'} },
   ["ReflectDamage"] = { text = "{V}% Reflect Damage", skills = {'Combat'} },
   ["ReflectDamage"] = { text = "{V}% Reflect Damage", skills = {'Combat'} },
Line 51: Line 47:
   ["GPFromMonsters"] = { text = "{V}% GP From Monsters", skills = {'Combat'} },
   ["GPFromMonsters"] = { text = "{V}% GP From Monsters", skills = {'Combat'} },
   ["MagicEvasion"] = { text = "{V}% Magic Evasion", skills = {'Combat'} },
   ["MagicEvasion"] = { text = "{V}% Magic Evasion", skills = {'Combat'} },
  ["PlayerAttackSpeedPercent"] = { text = "{V}% Player Attack Speed", isIncreaseNegative = true, skills = {'Combat'} },
  ["PreservationChance"] = { text = "{V}% Chance to Preserve Resources" },
   ["DamageReduction"] = { text = "{V}% Damage Reduction", skills = {'Combat'} },
   ["DamageReduction"] = { text = "{V}% Damage Reduction", skills = {'Combat'} },
   ["MinWaterSpellDmg"] = { text = "{VX} Min Water Spell Dmg", skills = {'Magic'} },
   ["MinWaterSpellDmg"] = { text = "{VX} Min Water Spell Dmg", skills = {'Magic'} },
Line 62: Line 56:
   ["GPFromThievingFlat"] = { text = "{V} GP From Thieving", skills = {'Thieving'} },
   ["GPFromThievingFlat"] = { text = "{V} GP From Thieving", skills = {'Thieving'} },
   ["GlobalAccuracy"] = { text = "{V}% Global Accuracy", skills = {'Combat'} },
   ["GlobalAccuracy"] = { text = "{V}% Global Accuracy", skills = {'Combat'} },
  ["ChanceToDoubleLootThieving"] = { text = "{V}% Chance To Double Loot in Thieving", skills = {'Thieving'} },
   ["SlayerAreaEffectNegationFlat"] = { text = "{V}% Flat Slayer Area Effect Negation", skills = {'Combat'} },
   ["SlayerAreaEffectNegationFlat"] = { text = "{V}% Flat Slayer Area Effect Negation", skills = {'Combat'} },
   ["MagicAccuracyBonus"] = { text = "{V}% Magic Accuracy Bonus", skills = {'Combat'} },
   ["MagicAccuracyBonus"] = { text = "{V}% Magic Accuracy Bonus", skills = {'Combat'} },
   ["SkillIntervalPercent"] = { text = "{V1}% {SV0} Interval", isIncreaseNegative = true },
   ["SkillIntervalPercent"] = { text = "{V}% {SV0} Interval", isIncreaseNegative = true },
   ["GlobalSkillXP"] = { text = "{V}% Global Skill XP" },
   ["GlobalSkillXP"] = { text = "{V}% Global Skill XP" },
   ["MeleeAccuracyBonus"] = { text = "{V}% Melee Accuracy Bonus", skills = {'Combat'} },
   ["MeleeAccuracyBonus"] = { text = "{V}% Melee Accuracy Bonus", skills = {'Combat'} },
Line 72: Line 65:
   ["MaxHitPercent"] = { text = "{V}% Max Hit", skills = {'Combat'} },
   ["MaxHitPercent"] = { text = "{V}% Max Hit", skills = {'Combat'} },
   ["AltMagicSkillXP"] = { text = "{V}% Alt. Magic Skill XP", skills = {'Magic'} },
   ["AltMagicSkillXP"] = { text = "{V}% Alt. Magic Skill XP", skills = {'Magic'} },
  ["StaminaPreservationChance"] = { text = "{V}% Chance to Preserve Stamina" },
   ["MinAirSpellDmg"] = { text = "{VX} Min Air Spell Dmg", skills = {'Combat'} },
   ["MinAirSpellDmg"] = { text = "{VX} Min Air Spell Dmg", skills = {'Combat'} },
   ["AutoEatEfficiency"] = { text = "{V}% Auto Eat Efficiency", skills = {'Combat'} },
   ["AutoEatEfficiency"] = { text = "{V}% Auto Eat Efficiency", skills = {'Combat'} },
Line 80: Line 72:
   ["RangedAccuracyBonus"] = { text = "{V} Ranged Accuracy Bonus", skills = {'Combat'} },
   ["RangedAccuracyBonus"] = { text = "{V} Ranged Accuracy Bonus", skills = {'Combat'} },
   ["AutoEatThreshold"] = { text = "{V}% Auto Eat Threshold", skills = {'Combat'} },
   ["AutoEatThreshold"] = { text = "{V}% Auto Eat Threshold", skills = {'Combat'} },
  ["PlayerAttackSpeed"] = { text = "{VMS}s Player Attack Speed", isIncreaseNegative = true, skills = {'Combat'} },
   ["freeBonfires"] = { text = "+ Automatically relight bonfires for free", skills = {'Firemaking'} },
   ["freeBonfires"] = { text = "+ Automatically relight bonfires for free", skills = {'Firemaking'} },
   ["AutoEatHPLimit"] = { text = "{V}% Auto Eat HP Limit", skills = {'Combat'} },
   ["AutoEatHPLimit"] = { text = "{V}% Auto Eat HP Limit", skills = {'Combat'} },
Line 92: Line 83:
   ["RangedStrengthBonus"] = { text = "{V}% Ranged Strength Bonus", skills = {'Combat'} },
   ["RangedStrengthBonus"] = { text = "{V}% Ranged Strength Bonus", skills = {'Combat'} },
   ["MagicDamageBonus"] = { text = "{V}% Magic Damage Bonus", skills = {'Combat'} },
   ["MagicDamageBonus"] = { text = "{V}% Magic Damage Bonus", skills = {'Combat'} },
   ["MasteryXP"] = { text = "{V1}% {SV0} Mastery XP" },
   ["MasteryXP"] = { text = "{V}% {SV0} Mastery XP" },
   ["dungeonEquipmentSwapping"] = { text = "{V} Dungeon Equipment Swapping", skills = {'Combat'} },
   ["dungeonEquipmentSwapping"] = { text = "{V} Dungeon Equipment Swapping", skills = {'Combat'} },
   ["SeeingGoldChance"] = { text = "{V}% chance for Silver Ore to also produce a Gold Bar when smithed", skills = {'Smithing'} },
   ["SeeingGoldChance"] = { text = "{V}% chance for Silver Ore to also produce a Gold Bar when smithed", skills = {'Smithing'} },
   ["ElementalRuneGain"] = { text = "{V} runes received when generating random elemental runes", skills = {'Runecrafting'} },
   ["ElementalRuneGain"] = { text = "{V} runes received when generating random elemental runes", skills = {'Runecrafting'} },
  ["StaminaCost"] = { text = "{V} Stamina Cost per action", isIncreaseNegative = true },
   ["GPFromSales"] = { text = "{V}% GP From Sales" },
   ["GPFromSales"] = { text = "{V}% GP From Sales" },
   ["MaxHitFlat"] = { text = "{VX} Max Hit", skills = {'Combat'} },
   ["MaxHitFlat"] = { text = "{VX} Max Hit", skills = {'Combat'} },
Line 107: Line 97:
   ["GPOnEnemyHit"] = { text = "{V} GP Gained on successful Enemy Hit", skills = {'Combat'} },
   ["GPOnEnemyHit"] = { text = "{V} GP Gained on successful Enemy Hit", skills = {'Combat'} },
   ["AdditionalRunecraftCountRunes"] = { text = "{V} Additional Runes of the same type in Runecrafting", skills = {'Runecrafting'} },
   ["AdditionalRunecraftCountRunes"] = { text = "{V} Additional Runes of the same type in Runecrafting", skills = {'Runecrafting'} },
   ["ChanceAdditionalSkillResource"] = { text = "{V1}% Chance to gain +1 additional resource in {SV0}. Cannot be doubled" },
   ["ChanceAdditionalSkillResource"] = { text = "{V}% Chance to gain +1 additional resource in {SV0}. Cannot be doubled" },
  ["EnemyMeleeEvasion"] = { text = "{V}% Enemy Melee Evasion", isIncreaseNegative = true, skills = {'Combat'} },
  ["EnemyRangedEvasion"] = { text = "{V}% Enemy Ranged Evasion", isIncreaseNegative = true, skills = {'Combat'} },
  ["EnemyMagicEvasion"] = { text = "{V}% Enemy Magic Evasion", isIncreaseNegative = true, skills = {'Combat'} },
   ["AttackIntervalPercent"] = { text = "{V}% Attack Interval", isIncreaseNegative = true, skills = {'Combat'} },
   ["AttackIntervalPercent"] = { text = "{V}% Attack Interval", isIncreaseNegative = true, skills = {'Combat'} },
   ["summoningSynergy_0_1"] = {text = "Upon killing an Enemy, grants GP equal to {V}% of their highest base Evasion Rating.", skills = {"Combat",}},
   ["summoningSynergy_0_1"] = {text = "Upon killing an Enemy, grants GP equal to {V}% of their highest base Evasion Rating.", skills = {"Combat",}},
Line 126: Line 113:
   ["summoningSynergy_1_14"] = {text = "If the Enemy has more combined Evasion Ratings than the Player, grants {V}% Hitpoint Regeneration.", skills = {"Combat"}},
   ["summoningSynergy_1_14"] = {text = "If the Enemy has more combined Evasion Ratings than the Player, grants {V}% Hitpoint Regeneration.", skills = {"Combat"}},
   ["summoningSynergy_1_15"] = {text = "If the Player is BURNING, grants {V} Melee, Ranged and Magic Defence Bonus.", skills = {"Combat"}},
   ["summoningSynergy_1_15"] = {text = "If the Player is BURNING, grants {V} Melee, Ranged and Magic Defence Bonus.", skills = {"Combat"}},
  ["summoningSynergy_2_6"] = {text = "If using a Melee Attack Style, grants {V}% Lifesteal.", skills = {"Combat", 'Melee'}},
  ["summoningSynergy_2_7"] = {text = "If using a Ranged Attack Style, grants {V}% Lifesteal.", skills = {"Combat", 'Ranged'}},
  ["summoningSynergy_2_8"] = {text = "If using a Magic Attack Style, grants {V}% Lifesteal.", skills = {"Combat", 'Magic'}},
   ["summoningSynergy_2_12"] = {text = "Grants Slayer Coins equal to {V}% of HP leeched from Lifesteal.", skills = {"Slayer"}},
   ["summoningSynergy_2_12"] = {text = "Grants Slayer Coins equal to {V}% of HP leeched from Lifesteal.", skills = {"Slayer"}},
   ["summoningSynergy_2_13"] = {text = "Upon attacking an Enemy, heals you for {V}% of your Damage Reduction. This can only proc once every 2 seconds.", skills = {"Combat"}},
   ["summoningSynergy_2_13"] = {text = "Upon attacking an Enemy, heals you for {V}% of your Damage Reduction. This can only proc once every 2 seconds.", skills = {"Combat"}},
  ["summoningSynergy_2_14"] = {text = "{V}% Lifesteal from Bleed damage.", skills = {"Combat", 'Melee'}},
   ["summoningSynergy_2_15"] = {text = "Heals you for all damage dealt by the Wolf & Dragon Familiars.", skills = {"Combat"}},
   ["summoningSynergy_2_15"] = {text = "Heals you for all damage dealt by the Wolf & Dragon Familiars.", skills = {"Combat"}},
   ["summoningSynergy_3_4"] = {text = "{V}% chance per action in Woodcutting to gain a random Gem.", skills = {'Woodcutting'}},
   ["summoningSynergy_3_4"] = {text = "{V}% chance per action in Woodcutting to gain a random Gem.", skills = {'Woodcutting'}},
Line 186: Line 169:
   ["summoningSynergy_12_13"] = {text = "While fighting your current Slayer Task, {V}% Damage Reduction.", skills = {"Combat"}},
   ["summoningSynergy_12_13"] = {text = "While fighting your current Slayer Task, {V}% Damage Reduction.", skills = {"Combat"}},
   ["summoningSynergy_12_14"] = {text = "While fighting your current Slayer Task, {V}% Hitpoints Regeneration.", skills = {"Combat"}},
   ["summoningSynergy_12_14"] = {text = "While fighting your current Slayer Task, {V}% Hitpoints Regeneration.", skills = {"Combat"}},
  ["summoningSynergy_12_15"] = {text = "You take {V}% less damage from Dragonbreath Special Attacks.", skills = {"Combat"}},
   ["summoningSynergy_13_14"] = {text = "{V}% Hitpoints Regeneration if you have less than 75% Current HP.", skills = {"Combat"}},
   ["summoningSynergy_13_14"] = {text = "{V}% Hitpoints Regeneration if you have less than 75% Current HP.", skills = {"Combat"}},
  ["summoningSynergy_13_15"] = {text = "You take no damage from BURNING.", skills = {"Combat"}},
  ["summoningSynergy_14_15"] = {text = "You now heal for all BURNING damage you or the Dragon Familiar applies.", skills = {"Combat", 'Magic'}},
   ["summoningSynergy_16_17"] = {text = "{V}% chance to preserve resources in Crafting when creating Rings or Amulets only.", skills = {'Crafting'}},
   ["summoningSynergy_16_17"] = {text = "{V}% chance to preserve resources in Crafting when creating Rings or Amulets only.", skills = {'Crafting'}},
   ["summoningSynergy_16_18"] = {text = "Crafting Potions now last twice as long. Bonus is applied when a new potion is activated. Charges are used per Crafting action.", skills = {'Crafting'}},
   ["summoningSynergy_16_18"] = {text = "Crafting Potions now last twice as long. Bonus is applied when a new potion is activated. Charges are used per Crafting action.", skills = {'Crafting'}},
Line 196: Line 176:
   ["summoningSynergy_17_19"] = {text = "{V} Coal required for Smithing Item production.", skills = {'Smithing'}, inverseSign = true},
   ["summoningSynergy_17_19"] = {text = "{V} Coal required for Smithing Item production.", skills = {'Smithing'}, inverseSign = true},
   ["summoningSynergy_18_19"] = {text = "While using the Controlled Heat Potions, +5% Firemaking Skill XP and Bonfire duration is doubled. Charges are used per Firemaking action.", skills = {'Firemaking'}},
   ["summoningSynergy_18_19"] = {text = "While using the Controlled Heat Potions, +5% Firemaking Skill XP and Bonfire duration is doubled. Charges are used per Firemaking action.", skills = {'Firemaking'}},
  -- New 0.21 modifiers
  ["AgilityObstacleCost"] = { text = "{V}% Agility Obstacle Build Costs}", skills = {'Agility'} },
  ["allowAttackAugmentingMagic"] = { text = "Magic Curses and Auroras can be used without a magic weapon", skills = {'Combat'} },
  ["allowSignetDrops"] = { text = "Something else drops instead of Gold Topaz Ring" },
  ["aprilFoolsDecreasedCarrotGang"] = { text = "{V} Carrot Gang reputation points", isIncreaseNegative = true, inverseSign = true, skills = {'Combat'} },
  ["aprilFoolsDecreasedLemonGang"] = { text = "{V} Lemon Gang reputation points", isIncreaseNegative = true, inverseSign = true, skills = {'Combat'} },
  ["aprilFoolsDecreasedMovementSpeed"] = { text = "{V} Movement Speed}", isIncreaseNegative = true, inverseSign = true },
  ["aprilFoolsDecreasedTeleportCost"] = { text = "{V}% Rune cost for Teleportation Spells", inverseSign = true },
  ["aprilFoolsDecreasedUpdateDelay"] = { text = "{V} days next Major Update has been delayed", inverseSign = true },
  ["aprilFoolsIncreasedCarrotGang"] = { text = "{V} Carrot Gang reputation points", skills = {'Combat'} },
  ["aprilFoolsIncreasedLemonGang"] = { text = "{V} Lemon Gang reputation points", skills = {'Combat'} },
  ["aprilFoolsIncreasedMovementSpeed"] = { text = "{V} Movement Speed}" },
  ["aprilFoolsIncreasedTeleportCost"] = { text = "{V}% Rune cost for Teleportation Spells", isIncreaseNegative = true },
  ["aprilFoolsIncreasedUpdateDelay"] = { text = "{V} days next Major Update has been delayed", isIncreaseNegative = true },
  ["AttackInterval"] = { text = "{VMS}s Attack Interval", isIncreaseNegative = true, skills = {'Combat'} },
  ["autoBurying"] = { text = "Bones are automatically buried for {V+100}% of their prayer point value", skills = {'Prayer'} },
  ["autoLooting"] = { text = "Combat loot is automatically collected", skills = {'Combat'} },
  ["bleedImmunity"] = { text = "Immune to bleeding", skills = {'Combat'} },
  ["BleedLifesteal"] = { text = "{V}% Bleed lifsteal", skills = {'Combat'} },
  ["BonusCoalMining"] = { text = "{V} Coal Ore per Ore Mined. (Item doubling does not apply)", skills = {'Mining'} },
  ["bonusCoalOnDungeonCompletion"] = { text = "1% chance to recieve {V} Coal when completing a dungeon", skills = {'Combat'} },
  ["burnImmunity"] = { text = "Immune to burning", skills = {'Combat'} },
  ["BurnLifesteal"] = { text = "{V}% Burn lifesteal", skills = {'Combat'} },
  ["bypassSlayerItems"] = { text = "Bypass Slayer Area item requirements", skills = {'Slayer'} },
  ["ChanceToConvertSeedDrops"] = { text = "{V}% chance to convert combat seed drops to herbs", skills = {'Combat'} },
  ["CombatStoppingThreshold"] = { text = "{V}% automatic combat stopping threshold", skills = {'Combat'} },
  ["CompostPreservationChance"] = { text = "{V}% Chance to preserve Compost or Weird Gloop applied to Farming Plots when harvesting", skills = {'Farming'} },
  ["Confusion"] = { text = "Take {V}% of remaining HP as damage on a succesful attack", isIncreaseNegative = true, skills = {'Combat'} },
  ["curseImmunity"] = { text = "Immune to curses", skills = {'Combat'} },
  ["DamageReductionPercent"] = { text = "{V}% increased damage reduction", skills = {'Combat'} },
  ["DamageTaken"] = { text = "Take {V}% more Damage from attacks", isIncreaseNegative = true, skills = {'Combat'} },
  ["debuffImmunity"] = { text = "Immune to debuffs", skills = {'Combat'} },
  ["Decay"] = { text = "Take {V}% of Max HP as damage on a succesful attack", isIncreaseNegative = true, skills = {'Combat'} },
  ["doubleItemsSkill"] = { text = "x{2^VD} TODO Items recieved from {SV0}" },
  ["doubleOresMining"] = { text = "x{2^VD} TODO Ores recieved from Mining", skills = {'Mining'} },
  ["DragonBreathDamage"] = { text = "{V}% damage taken from dragonbreath", isIncreaseNegative = true, skills = {'Combat'} },
  ["FiremakingCoalChance"] = { text = "{V}% chance to recieve coal when burning logs in Firemaking", skills = {'Firemaking'} },
  ["FlatMaxHitpoints"] = { text = "{VX} Maximum Hitpoints", skills = {'Hitpoints'} },
  ["FlatMinHit"] = { text = "{VX} Minimum Hit", skills = {'Combat'} },
  ["FlatReflectDamage"] = { text = "{VX} Reflect Damage", skills = {'Combat'} },
  ["FoodBurnChance"] = { text = "{V}% chance to burn food when Cooking", isIncreaseNegative = true, skills = {'Cooking'} },
  ["freeCompost"] = { text = "Composting crops in Farming is free", skills = {'Farming'} },
  ["GlobalEvasion"] = { text = "{V}% increased Evasion Ratings", skills = {'Combat'} },
  ["golbinRaidIncreasedMaximumAmmo"] = { text = "{V}% Maximum Ammo in Golbin Raid", skills = {'Combat'} },
  ["golbinRaidIncreasedMaximumRunes"] = { text = "{V}% Maximum Runes in Golbin Raid", skills = {'Combat'} },
  ["golbinRaidIncreasedMinimumFood"] = { text = "{V} Minimum Food in Golbin Raid", skills = {'Combat'} },
  ["golbinRaidIncreasedPrayerLevel"] = { text = "{V} Prayer Levels in Golbin Raid", skills = {'Prayer'} },
  ["golbinRaidIncreasedPrayerPointsStart"] = { text = "{V} Starting Prayer Points in Golbin Raid", skills = {'Prayer'} },
  ["golbinRaidIncreasedPrayerPointsWave"] = { text = "{V} Prayer Points per Wave in Golbin Raid", skills = {'Prayer'} },
  ["golbinRaidPassiveSlotUnlocked"] = { text = "Unlocked Passive Slot in Golbin Raid", skills = {'Combat'} },
  ["golbinRaidPrayerUnlocked"] = { text = "Unlocked Prayer in Golbin Raid", skills = {'Prayer'} },
  ["golbinRaidWaveSkipCostReduction"] = { text = "{V}% Golbin Raid wave Skip Cost", inverseSign = true, skills = {'Combat'} },
  ["GPMultiplierCap"] = { text = "{VD}% maximum gp per damage dealt", skills = {'Combat'} },
  ["GPMultiplierMin"] = { text = "{VD}% minimum gp per damage dealt", skills = {'Combat'} },
  ["GPMultiplierPer1MGP"] = { text = "{VD}% GP per damage dealt for every 1M GP owned", skills = {'Combat'} },
  ["itemProtection"] = { text = "Items are not lost on death", skills = {'Combat'} },
  ["MagicCritChance"] = { text = "{V}% Magic critical hit chance", skills = {'Magic'} },
  ["MagicCritMult"] = { text = "{V}% Magic critical hit multiplier", skills = {'Magic'} },
  ["MagicLifesteal"] = { text = "{V}% Magic lifesteal", skills = {'Magic'} },
  ["MagicMaxHit"] = { text = "{V}% Magic Max Hit", skills = {'Magic'} },
  ["magicProtection"] = { text = "Magic attacks have a {V}% chance to hit", skills = {'Magic'} },
  ["MasteryPoolProgress"] = { text = "{V}% to effective Mastery Pool progress" },
  ["MaxAirSpellDmg"] = { text = "{MX} Max Air Spell Dmg", skills = {'Magic'} },
  ["MaxEarthSpellDmg"] = { text = "{MX} Max Earth Spell Dmg", skills = {'Magic'} },
  ["MaxFireSpellDmg"] = { text = "{MX} Max Fire Spell Dmg", skills = {'Magic'} },
  ["MaxWaterSpellDmg"] = { text = "{MX} Max Water Spell Dmg", skills = {'Magic'} },
  ["MeleeCritChance"] = { text = "{V}% Melee critical hit chance", skills = {'Combat'} },
  ["MeleeCritMult"] = { text = "{V}% Melee critical hit multiplier", skills = {'Combat'} },
  ["MeleeLifesteal"] = { text = "{V}% Melee Lifesteal", skills = {'Combat'} },
  ["MeleeMaxHit"] = { text = "{V}% Melee Max Hit", skills = {'Combat'} },
  ["meleeProtection"] = { text = "Melee attacks have a {V}% chance to hit", skills = {'Combat'} },
  ["MeleeStunThreshold"] = { text = "Melee attacks stun the target when they deal {V}% of max hit", skills = {'Combat'} },
  ["MiningGemChance"] = { text = "{V}% Chance to recieve gems from Mining (Does not work for Rune Essence)", skills = {'Combat'} },
  ["OffItemChance"] = { text = "{V}% increased chance to recieve an off-item (An item from a skill that is not the main resource you are gathering)" },
  ["poisonImmunity"] = { text = "Immune to poison", skills = {'Combat'} },
  ["PoisonLifesteal"] = { text = "{V}% Poison lifesteal", skills = {'Combat'} },
  ["PrayerCost"] = { text = "{V}% Prayer Point Cost for Prayers", isIncreaseNegative = true, skills = {'Prayer'} },
  ["RangedCritChance"] = { text = "{V}% Ranged critical hit chance", skills = {'Ranged'} },
  ["RangedCritMult"] = { text = "{V}% Ranged critical hit multiplier", skills = {'Ranged'} },
  ["RangedLifesteal"] = { text = "{V}% Ranged Lifesteal", skills = {'Ranged'} },
  ["RangedMaxHit"] = { text = "{V}% Ranged Max Hit", skills = {'Ranged'} },
  ["rangedProtection"] = { text = "Ranged attacks have a {V}% chance to hit", skills = {'Ranged'} },
  ["RebirthChance"] = { text = "{V}% chance to respawn with full hitpoints upon reaching 0 hitpoints", skills = {'Combat'} },
  ["RedemptionPercent"] = { text = "{V}% of max hitpoints healed on redemption", skills = {'Combat'} },
  ["RedemptionThreshold"] = { text = "{V}% redemption threshold", skills = {'Combat'} },
  ["RolledReflectDamage"] = { text = "{S}0-{V} Reflect Damage", isIncreaseNegative = true, unsigned = true, skills = {'Combat'} },
  ["RuneProvision"] = { text = "Rune providing items provide {VMUL}x as many runes", skills = {'Combat'} },
  ["SecondaryFoodBurnChance"] = { text = "{V}% Secondary Chance to burn food when Cooking", isIncreaseNegative = true, skills = {'Cooking'} },
  ["sleepImmunity"] = { text = "Immune to Sleep", skills = {'Combat'} },
  ["SmithingCoalCost"] = { text = "{V}% Coal Costs for Smithing", skills = {'Smithing'} },
  ["stunImmunity"] = { text = "Immune to Stuns and Freezes", skills = {'Combat'} },
  ["summoningSynergy_9_19"] = { text = "" },
  ["ThievingSuccessCap"] = { text = "{V}% Thieving Success Rate Cap", skills = {'Thieving'} },
  ["ThievingSuccessRate"] = { text = "{V}% Thieving Success Rate", skills = {'Thieving'} },
  -- The below are not present in 0.21 but are left here for now until everything is fully-migrated to 0.21
  ["ChanceToDoubleItems"] = { text = "{V}% Chance To Double Items" },
  ["ChanceToDoubleLootThieving"] = { text = "{V}% Chance To Double Loot in Thieving", skills = {'Thieving'} },
  ["EnemyMeleeEvasion"] = { text = "{V}% Enemy Melee Evasion", isIncreaseNegative = true, skills = {'Combat'} },
  ["EnemyRangedEvasion"] = { text = "{V}% Enemy Ranged Evasion", isIncreaseNegative = true, skills = {'Combat'} },
  ["EnemyMagicEvasion"] = { text = "{V}% Enemy Magic Evasion", isIncreaseNegative = true, skills = {'Combat'} },
  ["MaxStamina"] = { text = "{V} Max Stamina" },
  ["PlayerAttackSpeed"] = { text = "{VMS}s Player Attack Speed", isIncreaseNegative = true, skills = {'Combat'} },
  ["PlayerAttackSpeedPercent"] = { text = "{V}% Player Attack Speed", isIncreaseNegative = true, skills = {'Combat'} },
  ["PreservationChance"] = { text = "{V}% Chance to Preserve Resources" },
  ["SlayerXP"] = { text = "{V}% Slayer XP", skills = {'Slayer'} },
  ["StaminaCost"] = { text = "{V} Stamina Cost per action", isIncreaseNegative = true },
  ["StaminaPerObstacle"] = { text = "{V} Stamina per Agility Obstacle Completion", skills = {'Agility'} },
  ["StaminaPreservationChance"] = { text = "{V}% Chance to Preserve Stamina" },
  ["summoningSynergy_12_15"] = {text = "You take {V}% less damage from Dragonbreath Special Attacks.", skills = {"Combat"}},
  ["summoningSynergy_13_15"] = {text = "You take no damage from BURNING.", skills = {"Combat"}},
  ["summoningSynergy_14_15"] = {text = "You now heal for all BURNING damage you or the Dragon Familiar applies.", skills = {"Combat", 'Magic'}},
  ["summoningSynergy_2_6"] = {text = "If using a Melee Attack Style, grants {V}% Lifesteal.", skills = {"Combat", 'Melee'}},
  ["summoningSynergy_2_7"] = {text = "If using a Ranged Attack Style, grants {V}% Lifesteal.", skills = {"Combat", 'Ranged'}},
  ["summoningSynergy_2_8"] = {text = "If using a Magic Attack Style, grants {V}% Lifesteal.", skills = {"Combat", 'Magic'}},
  ["summoningSynergy_2_14"] = {text = "{V}% Lifesteal from Bleed damage.", skills = {"Combat", 'Melee'}},
}
}


Line 339: Line 434:
   local isIncrease = true
   local isIncrease = true
   local isNegative = false
   local isNegative = false
  local valueUnsigned = false


   if Shared.startsWith(modifierName, "increased") or Shared.startsWith(modifierName, "decreased") then
   if Shared.startsWith(modifierName, "increased") or Shared.startsWith(modifierName, "decreased") then
Line 360: Line 456:
   end
   end


   return baseName, modifier.text, sign, not isPositive
  if type(modifier.unsigned) == 'boolean' then valueUnsigned = modifier.unsigned end
 
   return baseName, modifier.text, sign, not isPositive, valueUnsigned
end
end


function p._getModifierText(modifier, value, doColor)
function p._getModifierText(modifier, value, doColor)
   if doColor == nil then doColor = true end
   if doColor == nil then doColor = true end
   local modName, modText, sign, isNegative = p.getModifierDetails(modifier)
   local modName, modText, sign, isNegative, valueUnsigned = p.getModifierDetails(modifier)


   if modName == nil then
   if modName == nil then
Line 388: Line 486:
         end
         end
       end
       end
       if value[2] ~= nil then
       if value[2] ~= nil then value = value[2] end
        result = string.gsub(result, '{V1}', sign..value[2])
        result = string.gsub(result, '{VMS1}', sign..(value[2] / 1000))
      end
     end
     end
   else
   end
  -- Re-check the type of value, as it may have been modified above even if it was originally a table
  if type(value) ~= 'table' then
    local valSign = (valueUnsigned and '' or sign)
     if string.find(result, '{IV}', 1, true) ~= nil and tonumber(value) ~= nil then
     if string.find(result, '{IV}', 1, true) ~= nil and tonumber(value) ~= nil then
       local item = ItemData.Items[tonumber(value) + 1]
       local item = ItemData.Items[tonumber(value) + 1]
Line 400: Line 498:
       end
       end
     end
     end
     result = string.gsub(result, '{V}', sign..value)
     result = string.gsub(result, '{V}', valSign..value)
     result = string.gsub(result, '{VMS}', sign..(value / 1000))
    result = string.gsub(result, '{VD}', valSign..(value / 10))
     result = string.gsub(result, '{VX}', sign..(value * 10))
     result = string.gsub(result, '{VMS}', valSign..(value / 1000))
     result = string.gsub(result, '{VX100}', sign..(value * 100))
     result = string.gsub(result, '{VX}', valSign..(value * 10))
     result = string.gsub(result, '{V+100}', sign..(value + 100))
     result = string.gsub(result, '{VX100}', valSign..(value * 100))
     result = string.gsub(result, '{V%+100}', valSign..(value + 100))
    result = string.gsub(result, '{VMUL}', 2^value)
    result = string.gsub(result, '{S}', sign)
   end
   end