Anonymous

Module:Constants: Difference between revisions

From Melvor Idle
Updated Arch Tool Level display, Fixed error on nil modifiers in getModifiersDifference
(getSkillName/getSkillID: Fix)
(Updated Arch Tool Level display, Fixed error on nil modifiers in getModifiersDifference)
 
(67 intermediate revisions by 7 users not shown)
Line 5: Line 5:


--Just hardcoding these because I guess that's where we're at
--Just hardcoding these because I guess that's where we're at
--getModifierSkills still needs skills, otherwise this can be removed
local modifierTypes = {
local modifierTypes = {
["MeleeStrengthBonus"] = { text = "{V}% Melee Strength Bonus from Equipment", skills = {'Combat'} },
["MeleeStrengthBonus"] = { text = "{V}% Melee Strength Bonus from Equipment", skills = {'Combat'} },
["DamageToDungeonMonsters"] = { text = "{V}% Damage To Dungeon Monsters", skills = {'Combat'} },
["DamageToDungeonMonsters"] = { text = "{V}% Damage To Dungeon Monsters", skills = {'Combat'} },
["GlobalMasteryXP"] = { text = "{V}% Global Mastery XP", skills = {'Woodcutting', 'Fishing', 'Firemaking', 'Cooking', 'Mining', 'Smithing', 'Thieving', 'Farming', 'Fletching', 'Crafting', 'Runecrafting', 'Herblore', 'Agility', 'Summoning', 'Astrology'} },
["GlobalMasteryXP"] = { text = "{V}% Global Mastery XP", skills = {'Woodcutting', 'Fishing', 'Firemaking', 'Cooking', 'Mining', 'Smithing', 'Thieving', 'Farming', 'Fletching', 'Crafting', 'Runecrafting', 'Herblore', 'Agility', 'Summoning', 'Astrology', 'Archaeology'} },
["ChanceRandomPotionHerblore"] = { text = "{V}% chance to gain a second potion of a random tier", skills = {'Herblore'} },
["ChanceRandomPotionHerblore"] = { text = "{V}% chance to gain a second potion of a random tier", skills = {'Herblore'} },
["FlatPrayerCostReduction"] = { text = "{V} Prayer Point Cost for Prayers", inverseSign = true, skills = {'Prayer'} },
["FlatPrayerCostReduction"] = { text = "{V} Prayer Point Cost for Prayers (Prayer Point cost cannot go below 1)", inverseSign = true, skills = {'Prayer'} },
["MinEarthSpellDmg"] = { text = "{VX} Min Earth Spell Dmg", skills = {'Magic'} },
["MinEarthSpellDmg"] = { text = "{VX} Min Earth Spell Dmg", skills = {'Magic'} },
["SlayerTaskLength"] = { text = "{V}% Slayer Task Length/Qty", skills = {'Slayer'} },
["SlayerTaskLength"] = { text = "{V}% Slayer Task Length/Qty", skills = {'Slayer'} },
Line 21: Line 22:
["GlobalPreservationChance"] = { text = "{V}% Chance to Preserve Resources in Skills" },
["GlobalPreservationChance"] = { text = "{V}% Chance to Preserve Resources in Skills" },
["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', 'Hitpoints'} },
["ChanceToDoubleItemsSkill"] = { text = "{V}% 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', 'Hitpoints'} },
["PotionChargesFlat"] = { text = "{V} Charges per Potion" },
["PotionChargesFlat"] = { text = "{V} Charges per Potion" },
["SkillInterval"] = { text = "{VMS}s {SV0} Interval", isIncreaseNegative = true, isSkill = true },
["SkillInterval"] = { text = "{VMS}s {SV0} Interval", isIncreaseNegative = true, isSkill = true },
Line 31: Line 32:
["DamageToSlayerTasks"] = { text = "{V}% Damage To Slayer Tasks", skills = {'Combat'} },
["DamageToSlayerTasks"] = { text = "{V}% Damage To Slayer Tasks", skills = {'Combat'} },
["Lifesteal"] = { text = "{V}% Lifesteal", skills = {'Combat'} },
["Lifesteal"] = { text = "{V}% Lifesteal", skills = {'Combat'} },
["HPRegenFlat"] = { text = "{VX} Flat HP Regen", skills = {'Combat'} },
["HPRegenFlat"] = { text = "{VX} Flat HP Regen", skills = {'Combat', 'Hitpoints'} },
["ChanceToDoubleOres"] = { text = "{V}% Chance to Double Ores in Mining", skills = {'Combat'} },
["ChanceToDoubleOres"] = { text = "{V}% Chance to Double Ores in Mining", skills = {'Mining'} },
["MonsterRespawnTimer"] = { text = "{VMS}s Monster Respawn Timer", isIncreaseNegative = true, skills = {'Combat'} },
["MonsterRespawnTimer"] = { text = "{VMS}s Monster Respawn Timer", isIncreaseNegative = true, skills = {'Combat'} },
["SkillPreservationChance"] = { text = "{V}% Chance to Preserve Resources in {SV0}" },
["SkillPreservationChance"] = { text = "{V}% Chance to Preserve Resources in {SV0}" },
Line 68: Line 69:
["ChanceToDoubleItemsGlobal"] = { text = "{V}% Chance to Double Items Globally" },
["ChanceToDoubleItemsGlobal"] = { text = "{V}% Chance to Double Items Globally" },
["GPGlobal"] = { text = "{V}% GP from all sources (Except Item Selling)", skills = {'Combat', 'Thieving', 'Agility'} },
["GPGlobal"] = { text = "{V}% GP from all sources (Except Item Selling)", skills = {'Combat', 'Thieving', 'Agility'} },
["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'} },
["freeBonfires"] = { text = "+ Automatically relight bonfires for free", skills = {'Firemaking'} },
["freeBonfires"] = { text = "Bonfires in Firemaking require no logs to light. Automatically relights Bonfires when depleted", unsigned = true, skills = {'Firemaking'} },
["AutoEatHPLimit"] = { text = "{V}% Auto Eat HP Limit", skills = {'Combat'} },
["AutoEatHPLimit"] = { text = "{V}% Auto Eat HP Limit", skills = {'Combat'} },
["BankSpaceShop"] = { text = "{V} Bank Space from Shop" },
["BankSpaceShop"] = { text = "{V} Bank Space from Shop" },
Line 77: Line 78:
["ChanceDoubleHarvest"] = { text = "{V}% chance for double harvest", skills = {'Farming'} },
["ChanceDoubleHarvest"] = { text = "{V}% chance for double harvest", skills = {'Farming'} },
["golbinRaidStartingWeapon"] = { text = "Start the Golbin Raid with an {VITEM}", unsigned = true },
["golbinRaidStartingWeapon"] = { text = "Start the Golbin Raid with an {VITEM}", unsigned = true },
["AttackRolls"] = { text = "+Lucky Hit Chance (Roll twice, take the better result)", skills = {'Combat'} },
["AttackRolls"] = { text = "Your Attacks now roll twice (Select highest chance)", unsigned = true, skills = {'Combat'} },
["AmmoPreservation"] = { text = "{V}% Ammo Preservation", skills = {'Ranged'} },
["AmmoPreservation"] = { text = "{V}% Ammo Preservation", skills = {'Ranged'} },
["RangedStrengthBonus"] = { text = "{V}% Ranged Strength Bonus from Equipment", skills = {'Combat'} },
["RangedStrengthBonus"] = { text = "{V}% Ranged Strength Bonus from Equipment", skills = {'Combat'} },
Line 109: Line 110:
["summoningSynergy_1_12"] = {text = "If the Enemy is your current Slayer Task, {V}% Enemy Accuracy Rating.", skills = {"Combat"}, inverseSign = true},
["summoningSynergy_1_12"] = {text = "If the Enemy is your current Slayer Task, {V}% Enemy Accuracy Rating.", skills = {"Combat"}, inverseSign = true},
["summoningSynergy_1_13"] = {text = "Grants flat Melee & Ranged Defence Bonus equal to your Damage Reduction", skills = {"Combat"}},
["summoningSynergy_1_13"] = {text = "Grants flat Melee & Ranged Defence Bonus equal to your Damage Reduction", 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_14"] = {text = "If the Enemy has more combined Evasion Ratings than the Player, grants {V}% Hitpoint Regeneration.", skills = {"Combat", "Hitpoints"}},
["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_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"}},
Line 141: Line 142:
["summoningSynergy_6_12"] = {text = "While fighting your current Slayer Task, grants {V}% of your Melee Max Hit as Minimum Damage.", skills = {"Combat", 'Melee'}},
["summoningSynergy_6_12"] = {text = "While fighting your current Slayer Task, grants {V}% of your Melee Max Hit as Minimum Damage.", skills = {"Combat", 'Melee'}},
["summoningSynergy_6_13"] = {text = "While fighting a Ranged Enemy, grants {V}% Damage Reduction.", skills = {"Combat"}},
["summoningSynergy_6_13"] = {text = "While fighting a Ranged Enemy, grants {V}% Damage Reduction.", skills = {"Combat"}},
["summoningSynergy_6_14"] = {text = "While using a Melee Weapon, grants {V}% of your Melee Max Hit as Flat HP Regen.", skills = {"Combat", 'Melee'}},
["summoningSynergy_6_14"] = {text = "While using a Melee Weapon, grants {V}% of your Melee Max Hit as Flat HP Regen.", skills = {"Combat", 'Melee', 'Hitpoints'}},
["summoningSynergy_6_15"] = {text = "If the Enemy is BURNING, effects from the Minotaur Familiar are tripled.", skills = {"Combat", 'Melee'}},
["summoningSynergy_6_15"] = {text = "If the Enemy is BURNING, effects from the Minotaur Familiar are tripled.", skills = {"Combat", 'Melee'}},
["summoningSynergy_7_8"] = {text = "While fighting a Magic Enemy, grants {V} Ranged Accuracy Bonus and {V} Ranged Strength Bonus.", skills = {"Combat", 'Ranged'}},
["summoningSynergy_7_8"] = {text = "While fighting a Magic Enemy, grants {V} Ranged Accuracy Bonus and {V} Ranged Strength Bonus.", skills = {"Combat", 'Ranged'}},
["summoningSynergy_7_12"] = {text = "While fighting your current Slayer Task, grants {V}% of your Ranged Max Hit as Minimum Damage.", skills = {"Combat", 'Ranged'}},
["summoningSynergy_7_12"] = {text = "While fighting your current Slayer Task, grants {V}% of your Ranged Max Hit as Minimum Damage.", skills = {"Combat", 'Ranged'}},
["summoningSynergy_7_13"] = {text = "While fighting a Magic Enemy, grants {V}% Damage Reduction.", skills = {"Combat"}},
["summoningSynergy_7_13"] = {text = "While fighting a Magic Enemy, grants {V}% Damage Reduction.", skills = {"Combat"}},
["summoningSynergy_7_14"] = {text = "While using a Ranged Weapon, grants {V}% of your Ranged Max Hit as HP Regeneration.", skills = {"Combat", 'Ranged'}},
["summoningSynergy_7_14"] = {text = "While using a Ranged Weapon, grants {V}% of your Ranged Max Hit as HP Regeneration.", skills = {"Combat", 'Ranged', 'Hitpoints'}},
["summoningSynergy_7_15"] = {text = "Your Ranged Attacks now have {V}% to inflict BURNING on the Enemy.", skills = {"Combat", 'Ranged'}},
["summoningSynergy_7_15"] = {text = "Your Ranged Attacks now have {V}% to inflict BURNING on the Enemy.", skills = {"Combat", 'Ranged'}},
["summoningSynergy_8_12"] = {text = "Grants Slayer Coins equal to {V}% of your Magic Damage while on Slayer Task.", skills = {'Slayer'}},
["summoningSynergy_8_12"] = {text = "Grants Slayer Coins equal to {V}% of your Magic Damage while on Slayer Task.", skills = {'Slayer'}},
["summoningSynergy_8_13"] = {text = "While fighting a Melee Enemy, grants {V}% Damage Reduction.", skills = {"Combat"}},
["summoningSynergy_8_13"] = {text = "While fighting a Melee Enemy, grants {V}% Damage Reduction.", skills = {"Combat"}},
["summoningSynergy_8_14"] = {text = "Grants {V}% of your Max Hit as HP Regeneration if using a Magic Attack Style.", skills = {"Combat", 'Magic'}},
["summoningSynergy_8_14"] = {text = "Grants {V}% of your Max Hit as HP Regeneration if using a Magic Attack Style.", skills = {"Combat", 'Magic', 'Hitpoints'}},
["summoningSynergy_9_11"] = {text = "The Chef in Thieving now deals no damage to you.", skills = {'Thieving'}},
["summoningSynergy_9_11"] = {text = "The Chef in Thieving now deals no damage to you.", skills = {'Thieving'}},
["summoningSynergy_9_16"] = {text = "Crafting Recipes that require Dragonhide now use {V} quantity to create. Recipe cost cannot go below 1.", skills = {'Crafting'}, inverseSign = true},
["summoningSynergy_9_16"] = {text = "Crafting Recipes that require Dragonhide now use {V} quantity to create. Recipe cost cannot go below 1.", skills = {'Crafting'}, inverseSign = true},
Line 157: Line 158:
["summoningSynergy_10_11"] = {text = "Successfully pickpocketting the Miner in Thieving will now grant {V} Rune Essence.", skills = {'Thieving'}},
["summoningSynergy_10_11"] = {text = "Successfully pickpocketting the Miner in Thieving will now grant {V} Rune Essence.", skills = {'Thieving'}},
["summoningSynergy_10_16"] = {text = "{V}% chance to double when creating Leather, Hard Leather or Dragonhide Armour in Crafting.", skills = {'Crafting'}},
["summoningSynergy_10_16"] = {text = "{V}% chance to double when creating Leather, Hard Leather or Dragonhide Armour in Crafting.", skills = {'Crafting'}},
["summoningSynergy_10_17"] = {text = "{V}% Smithing & Runecrafting Preservation Chance."},
["summoningSynergy_10_17"] = {text = "{V}% Smithing & Runecrafting Preservation Chance.", skills = {'Smithing', 'Runecrafting'}},
["summoningSynergy_10_18"] = {text = "While the Elemental Potion is active in Runecrafting, grants a chance to get random Combination Runes. The chance and quantity is equal to that of the Elemental Potion.", skills = {'Runecrafting'}},
["summoningSynergy_10_18"] = {text = "While the Elemental Potion is active in Runecrafting, grants a chance to get random Combination Runes. The chance and quantity is equal to that of the Elemental Potion.", skills = {'Runecrafting'}},
["summoningSynergy_10_19"] = {text = "Grants {V} Fire Runes while creating Elemental Runes.", skills = {'Runecrafting'}},
["summoningSynergy_10_19"] = {text = "Grants {V} Fire Runes while creating Elemental Runes.", skills = {'Runecrafting'}},
Line 165: Line 166:
["summoningSynergy_11_19"] = {text = "While Thieving any NPC, 50% chance to grant +100% GP, 35% chance to grant 4x Items, or 15% chance to receive no items or GP at all.", skills = {'Thieving'}},
["summoningSynergy_11_19"] = {text = "While Thieving any NPC, 50% chance to grant +100% GP, 35% chance to grant 4x Items, or 15% chance to receive no items or GP at all.", skills = {'Thieving'}},
["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", "Hitpoints"}},
["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", "Hitpoints"}},
["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 199: Line 200:
["ChanceToConvertSeedDrops"] = { text = "{V}% chance to convert combat seed drops to herbs", skills = {'Combat'} },
["ChanceToConvertSeedDrops"] = { text = "{V}% chance to convert combat seed drops to herbs", skills = {'Combat'} },
["CompostPreservationChance"] = { text = "{V}% Chance to preserve Compost or Weird Gloop applied to Farming Plots when harvesting", skills = {'Farming'} },
["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'} },
["Confusion"] = { text = "{V}% of remaining Hitpoints taken as damage on a successful attack (once per turn)", isIncreaseNegative = true, skills = {'Combat'} },
["curseImmunity"] = { text = "Immune to curses", skills = {'Combat'} },
["curseImmunity"] = { text = "Immune to curses", skills = {'Combat'} },
["DamageReductionPercent"] = { text = "{V}% increased damage reduction", skills = {'Combat'} },
["DamageReductionPercent"] = { text = "{V}% Damage Reduction", skills = {'Combat'} },
["DamageTaken"] = { text = "Take {V}% more Damage from attacks", isIncreaseNegative = true, skills = {'Combat'} },
["DamageTaken"] = { text = "{V}% more Damage taken", isIncreaseNegative = true, skills = {'Combat'} },
["debuffImmunity"] = { text = "Immune to debuffs", 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'} },
["Decay"] = { text = "{V}% of Maximum Hitpoints taken as damage on a successful attack (once per turn)", isIncreaseNegative = true, skills = {'Combat'} },
["doubleItemsSkill"] = { text = "x{VMUL} Items received from {SV0}", unsigned = true },
["doubleItemsSkill"] = { text = "x{VMUL} Items received from {SV0}", unsigned = true },
["doubleOresMining"] = { text = "x{VMUL} Ores received from Mining", unsigned = true, skills = {'Mining'} },
["doubleOresMining"] = { text = "x2 Ores received from Mining", unsigned = true, skills = {'Mining'} },
["DragonBreathDamage"] = { text = "{V}% damage taken from dragonbreath", isIncreaseNegative = true, skills = {'Combat'} },
["DragonBreathDamage"] = { text = "{V}% damage taken from dragonbreath", isIncreaseNegative = true, skills = {'Combat'} },
["FiremakingCoalChance"] = { text = "{V}% chance to receive coal when burning logs in Firemaking", skills = {'Firemaking'} },
["FiremakingCoalChance"] = { text = "{V}% chance to receive coal when burning logs in Firemaking", skills = {'Firemaking'} },
Line 213: Line 214:
["FlatReflectDamage"] = { text = "{VX} Reflect Damage", skills = {'Combat'} },
["FlatReflectDamage"] = { text = "{VX} Reflect Damage", skills = {'Combat'} },
["freeCompost"] = { text = "Composting crops in Farming is free", skills = {'Farming'} },
["freeCompost"] = { text = "Composting crops in Farming is free", skills = {'Farming'} },
["GlobalEvasion"] = { text = "{V}% increased Evasion Ratings", skills = {'Combat'} },
["GlobalEvasion"] = { text = "{V}% Global Evasion", skills = {'Combat'} },
["golbinRaidIncreasedMaximumAmmo"] = { text = "{V}% Maximum Ammo in Golbin Raid", skills = {'Combat'} },
["golbinRaidIncreasedMaximumAmmo"] = { text = "{V}% Maximum Ammo in Golbin Raid", skills = {'Combat'} },
["golbinRaidIncreasedMaximumRunes"] = { text = "{V}% Maximum Runes in Golbin Raid", skills = {'Combat'} },
["golbinRaidIncreasedMaximumRunes"] = { text = "{V}% Maximum Runes in Golbin Raid", skills = {'Combat'} },
Line 245: Line 246:
["poisonImmunity"] = { text = "{V}% chance to ignore poison", skills = {'Combat'} },
["poisonImmunity"] = { text = "{V}% chance to ignore poison", skills = {'Combat'} },
["PoisonLifesteal"] = { text = "{V}% Poison lifesteal", skills = {'Combat'} },
["PoisonLifesteal"] = { text = "{V}% Poison lifesteal", skills = {'Combat'} },
["PrayerCost"] = { text = "{V}% Prayer Point Cost for Prayers", isIncreaseNegative = true, skills = {'Prayer'} },
["PrayerCost"] = { text = "{V}% Prayer Point Cost for Prayers (Prayer Point cost cannot go below 1)", isIncreaseNegative = true, skills = {'Prayer'} },
["RangedCritChance"] = { text = "{V}% Ranged critical hit chance", skills = {'Ranged'} },
["RangedCritChance"] = { text = "{V}% Ranged critical hit chance", skills = {'Ranged'} },
["RangedLifesteal"] = { text = "{V}% Ranged Lifesteal", skills = {'Ranged'} },
["RangedLifesteal"] = { text = "{V}% Ranged Lifesteal", skills = {'Ranged'} },
Line 290: Line 291:
["ChanceToPreserveFood"] = { text = "{V}% chance to Preserve Food when eaten", skills = {'Combat'} },
["ChanceToPreserveFood"] = { text = "{V}% chance to Preserve Food when eaten", skills = {'Combat'} },
["ElementalEffectChance"] = { text = "{V}% chance to apply Burn, Frostburn or Freeze when hitting with a Magic attack (once per turn)", skills = {'Combat'} },
["ElementalEffectChance"] = { text = "{V}% chance to apply Burn, Frostburn or Freeze when hitting with a Magic attack (once per turn)", skills = {'Combat'} },
["EndOfTurnHealing2"] = { text = "{V}% of current hitpoints every 2 turns", skills = {'Combat'} },
["EndOfTurnHealing2"] = { text = "{V}% of current hitpoints every 2 turns", skills = {'Combat', 'Hitpoints'} },
["EndOfTurnHealing3"] = { text = "{V}% of current hitpoints every 3 turns", skills = {'Combat'} },
["EndOfTurnHealing3"] = { text = "{V}% of current hitpoints every 3 turns", skills = {'Combat', 'Hitpoints'} },
["EndOfTurnHealing5"] = { text = "{V}% of current hitpoints every 5 turns", skills = {'Combat'} },
["EndOfTurnHealing5"] = { text = "{V}% of current hitpoints every 5 turns", skills = {'Combat', 'Hitpoints'} },
["freeProtectItem"] = { text = "The Protect Item Prayer costs nothing", skills = {'Prayer'} },
["freeProtectItem"] = { text = "The Protect Item Prayer costs nothing", skills = {'Prayer'} },
["frostBurnImmunity"] = { text = "{V}% chance to ignore Frostburn", skills = {'Combat'} },
["frostBurnImmunity"] = { text = "{V}% chance to ignore Frostburn", skills = {'Combat'} },
Line 307: Line 308:
["PoisonReflectChance"] = { text = "{V}% chance to poison attackers when hit", skills = {'Combat'} },
["PoisonReflectChance"] = { text = "{V}% chance to poison attackers when hit", skills = {'Combat'} },
["rangedImmunity"] = { text = "Immune to Ranged attacks", skills = {'Combat'} },
["rangedImmunity"] = { text = "Immune to Ranged attacks", skills = {'Combat'} },
["RegenerationInterval"] = { text = "{VMS}s Hitpoint Regeneration interval", isIncreaseNegative = true, skills = {'Combat'} },
["RegenerationInterval"] = { text = "{VMS}s Hitpoint Regeneration interval", isIncreaseNegative = true, skills = {'Combat', 'Hitpoints'} },
["slowImmunity"] = { text = "{V}% chance to ignore Slow effects", skills = {'Combat'} },
["slowImmunity"] = { text = "{V}% chance to ignore Slow effects", skills = {'Combat'} },
["SurgeSpellAccuracy"] = { text = "{V}% Accuracy Rating when using Surge spells", skills = {'Combat'} },
["SurgeSpellAccuracy"] = { text = "{V}% Accuracy Rating when using Surge spells", skills = {'Combat'} },
Line 317: Line 318:
["MeleeCritMult"] = { text = "{V}% Melee critical hit multiplier", skills = {'Combat'} },
["MeleeCritMult"] = { text = "{V}% Melee critical hit multiplier", skills = {'Combat'} },
["RangedCritMult"] = { text = "{V}% Ranged critical hit multiplier", skills = {'Ranged'} },
["RangedCritMult"] = { text = "{V}% Ranged critical hit multiplier", skills = {'Ranged'} },
-- New 1.1 modifiers, TODO add actual descriptions and the sort
-- New 1.1 modifiers
["15SlowStunChance2Turns"] = { text = "TODO 15SlowStunChance2Turns", isIncreaseNegative = false, inverseSign = false, skills = {} },
["15SlowStunChance2Turns"] = { text = "{V}% chance to apply a 15% Slow for 2 Attack Turns when hitting with any attack (once per turn)", skills = {'Combat'} },
["30Slow5TurnsChance"] = { text = "TODO 30Slow5TurnsChance", isIncreaseNegative = false, inverseSign = false, skills = {} },
["30Slow5TurnsChance"] = { text = "{V}% chance to inflict a Slow that increases the target's attack interval by 30% for 5 target turns when hitting with an attack", skills = {'Combat'} },
["5DROnBeingHit"] = { text = "TODO 5DROnBeingHit", isIncreaseNegative = false, inverseSign = false, skills = {} },
["5DROnBeingHit"] = { text = "When hit by an Enemy, gain +5% Damage Reduction for 1 Enemy Turn (Does not Stack)", skills = {'Combat'} },
["AbsorbingSkin"] = { text = "TODO AbsorbingSkin", isIncreaseNegative = false, inverseSign = false, skills = {} },
["AbsorbingSkin"] = { text = "Target gains +3% Damage Reduction for every successful hit by the Attacker (Stacks up to 10 times)", skills = {'Combat'} },
["AdditionalAshInFiremaking"] = { text = "TODO AdditionalAshInFiremaking", isIncreaseNegative = false, inverseSign = false, skills = {} },
["AdditionalAshInFiremaking"] = { text = "{V} Ash per burn in Firemaking (Cannot be doubled)", isIncreaseNegative = true, skills = {'Firemaking'} },
["AgilityPillarCost"] = { text = "TODO AgilityPillarCost", isIncreaseNegative = false, inverseSign = false, skills = {} },
["AgilityPillarCost"] = { text = "{V}% Agility Pillar build costs", isIncreaseNegative = true, skills = {'Agility'} },
["allowNonMagicCurses"] = { text = "TODO allowNonMagicCurses", isIncreaseNegative = false, inverseSign = false, skills = {} },
["allowNonMagicCurses"] = { text = "Magic Curses can be used without a Magic weapon", skills = {'Combat'} },
["applyDespairCurseOnSpawn"] = { text = "TODO applyDespairCurseOnSpawn", isIncreaseNegative = false, inverseSign = false, skills = {} },
["applyDespairCurseOnSpawn"] = { text = "Apply Despair Curse to the Target on spawn or revive", skills = {'Combat'} },
["applyMadnessCurseOnSpawn"] = { text = "TODO applyMadnessCurseOnSpawn", isIncreaseNegative = false, inverseSign = false, skills = {}
["applyMadnessCurseOnSpawn"] = { text = "Apply Madness Curse to the Target on spawn or revive", skills = {'Combat'} },
["applyRandomCurseOnSpawn"] = { text = "Apply a random Curse to the Target on spawn or revive", skills = {'Combat'} },
["applyTormentCurseOnSpawn"] = { text = "Apply Torment Curse to the Target on spawn or revive", skills = {'Combat'} },
["Assassin"]
}
}


Line 617: Line 777:
local mode = GameData.getEntityByName('gamemodes', modeName)
local mode = GameData.getEntityByName('gamemodes', modeName)
if mode == nil then
if mode == nil then
error("Invalid gamemode '" .. mode .. "'", 2)
error("Invalid gamemode '" .. modeName .. "'", 2)
end
end
Line 657: Line 817:
local skill = GameData.getSkillData(skillID)
local skill = GameData.getSkillData(skillID)
if skill ~= nil then
if skill ~= nil then
return skill.data.name
return skill.name
end
end
end
end
Line 670: Line 830:


function p.getEquipmentSlotName(id)
function p.getEquipmentSlotName(id)
return type(id) == 'number' and GameData.rawData.equipmentSlots[id] or 'Invalid'
local slotData = GameData.getEntityByID('equipmentSlots', id)
if slotData ~= nil then
return slotData.name
end
end
end


function p.getEquipmentSlotID(name)
function p.getEquipmentSlotID(name)
return GameData.rawData.equipmentSlots[name]
local slotData = GameData.getEntityByName('equipmentSlots', name)
if slotData ~= nil then
return slotData.id
end
end
end


Line 686: Line 852:
return Shared.titleCase(styleNum)
return Shared.titleCase(styleNum)
end
end
return "ERROR: Invalid combat style[[Category:Pages with script errors]]"
return Shared.printError('Invalid combat style')
end
end


Line 706: Line 872:
function p.getSlayerTierByLevel(level)
function p.getSlayerTierByLevel(level)
if type(level) ~= 'number' or level < 1 then
if type(level) ~= 'number' or level < 1 then
return "ERROR: Invalid Slayer level [[Category:Pages with script errors]]"
return Shared.printError('Invalid Slayer level')
end
end
Line 727: Line 893:
end
end
end
end
return "ERROR: Invalid Slayer tier[[Category:Pages with script errors]]"
return Shared.printError('Invalid Slayer tier')
end
end


Line 735: Line 901:
return tier.display
return tier.display
else
else
return "ERROR: Invalid Slayer tier[[Category:Pages with script errors]]"
return Shared.printError('Invalid Slayer tier')
end
end
end
end
Line 742: Line 908:
--- End of slayer functions
--- End of slayer functions


--Turns a modifier name like 'increasedMeleeAccuracyBonus' into several pieces of data:
--Turns a modifier name like 'increasedHPRegenFlat' into several pieces of data:
--Base Name, Text, Sign, and IsNegative
--Base Name, Description, IsNegative, and modifyValue
--ex. "MeleeAccuracyBonus", "+{V}% Melee Accuracy", "+", false
--ex. "HPRegenFlat", "+${value} Flat Hitpoints Regeneration", false, "multiplyByNumberMultiplier"
function p.getModifierDetails(modifierName)
function p.getModifierDetails(modifierName)
local baseName = modifierName
local baseName = modifierName
local isIncrease = true
local modifier = GameData.rawData.modifierData[modifierName]
local isNegative = false
local valueUnsigned = false
 
if Shared.startsWith(modifierName, "increased") or Shared.startsWith(modifierName, "decreased") then
baseName = string.sub(modifierName, 10)
isIncrease = Shared.startsWith(modifierName, "increased")
end


local modifier = modifierTypes[baseName]
if modifier == nil then
if modifier == nil then
return nil
return nil
end
end


local isPositive = isIncrease
if Shared.startsWith(modifierName, "increased") or Shared.startsWith(modifierName, "decreased") then
if modifier.isIncreaseNegative then
baseName = string.sub(modifierName, 10)
isPositive = not isPositive
end
end


local sign = "+"
return baseName, modifier.description, modifier.isNegative, modifier.modifyValue
if (not isIncrease and not modifier.inverseSign) or (isIncrease and modifier.inverseSign) then
sign = "-"
end
 
if type(modifier.unsigned) == 'boolean' then valueUnsigned = modifier.unsigned end
 
return baseName, modifier.text, sign, not isPositive, valueUnsigned, modifier
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, valueUnsigned = p.getModifierDetails(modifier)
local modName, modText, isNegative, modifyValue = p.getModifierDetails(modifier)


if modName == nil then
if modName == nil then
return 'ERROR: Invalid modifier type for ' .. modifier .. '[[Category:Pages with script errors]]'
return Shared.printError('Invalid modifier type for "' .. modifier .. '"')
end
end
 
if modifyValue ~= nil and string.match(modifyValue, 'ToolLevels') then
modifyValue = 'ArchaeologyToolLevels'
end
 
local formatModValue = function(value, rule)
local formatModValue = function(value, rule)
local ruleFunctions = {
local ruleFunctions = {
['V'] = function(val) return val end,
['value'] = function(val) return val end,
['VD'] = function(val) return val / 10 end,
['multiplyByNumberMultiplier'] = function(val) return val * 10 end,
['VMS'] = function(val) return val / 1000 end,
['divideByNumberMultiplier'] = function(val) return val / 10 end,
['VX'] = function(val) return val * 10 end,
['milliToSeconds'] = function(val) return val / 1000 end,
['VX100'] = function(val) return val * 100 end,
['(value)=>value*100'] = function(val) return val * 100 end,
['V+100'] = function(val) return val + 100 end,
['(value)=>100+value'] = function(val) return val + 100 end,
['VMUL'] = function(val) return 2^val end,
['(value)=>value+1'] = function(val) return val + 1 end,
['VITEM'] = function(val)
['(value)=>Math.pow(2,value)'] = function(val) return 2^val end,
local item = GameData.getEntityByID('items', val)
["(value)=>{if(value>=2){return getLangString('ALLOW_UNHOLY_PRAYERS');}\nelse if(value>=1){return getLangString('ALLOW_UNHOLY_PRAYERS_WITH_EQUIPMENT');}\nelse{return 'Invalid modifier value.';}}"] = function(val) return 'Allows for Unholy Prayers to be used' end,
if item ~= nil then
['ArchaeologyToolLevels'] = function(val)
return item.name
local toolLevel = '+' .. val
end
if string.match(modName, 'Sieve') then
end
toolLevel = toolLevel ..  ' level of the Sieve Tool in Archaeology'
}
elseif string.match(modName, 'Trowel') then
local ruleFunc = ruleFunctions[rule] or ruleFunctions['V']
toolLevel = toolLevel ..  ' level of the Trowel Tool in Archaeology'
elseif string.match(modName, 'Brush') then
if type(value) == 'table' then
toolLevel = toolLevel ..  ' level of the Brush Tool in Archaeology'
-- If table is a pair of values then format both & add a separator
elseif string.match(modName, 'Shovel') then
return ruleFunc(value[1]) .. '-' .. ruleFunc(value[2])
toolLevel = toolLevel ..  ' level of the Shovel Tool in Archaeology'
else
end
return ruleFunc(value)
if val > 1 then
return string.gsub(toolLevel, 'level', 'levels')
else
return toolLevel
end
end,
['(value)=>game.golbinRaid.startingWeapons[value].name'] = function(val)
-- For golbin raid starting weapons
local startingWeapons = { 'melvorD:Bronze_Scimitar', 'melvorD:Adamant_Scimitar' }
local itemID = startingWeapons[val + 1]
local item = GameData.getEntityByID('items', itemID)
if item ~= nil then
return item.name
else
return 'Unknown'
end
end
end
}
local ruleFunc = ruleFunctions[modifyValue] or ruleFunctions['value']
if type(value) == 'table' then
-- If table is a pair of values then format both & add a separator
return ruleFunc(value[1]) .. '-' .. ruleFunc(value[2])
else
return ruleFunc(value)
end
end
end


local result = modText
local valueArray, resultArray = nil, {}
if type(value) ~= 'table' then
valueArray = {value}
else
valueArray = value
end


if type(value) == 'table' then
for i, subVal in ipairs(valueArray) do
if Shared.tableCount(value) > 0 and type(value[1]) == 'table' then
local resultText = modText
--Potentially return multiple rows if necessary
-- A few modifiers don't have official descriptions; Fallback to manual ones instead
local resultArray = {}
if string.match(resultText, 'UNDEFINED TRANSLATION') then
for i, subVal in Shared.skpairs(value) do
resultText = modifierTypes[modName].text
table.insert(resultArray, p._getModifierText(modifier, subVal, doColor))
end
local modMagnitude = nil
if type(subVal) == 'table' and subVal.skillID ~= nil then
-- Modifier value is skill specific
modMagnitude = subVal.value
local skillName = p.getSkillName(subVal.skillID)
if skillName ~= nil then
resultText = string.gsub(resultText, '${skillName}', skillName)
end
end
return table.concat(resultArray, '<br/>')
else
elseif Shared.contains(modText, '{SV0}') then
-- Modifier value is the magnitude only
-- If the value is a table and the mod text contains {SV0}, then
modMagnitude = subVal
-- the value is a {skillID, val} pair, otherwise it is a range of
-- values {minVal, maxVal}
if value[1] ~= nil then
local skillName = p.getSkillName(value[1])
if skillName ~= nil then
result = string.gsub(result, '{SV0}', p.getSkillName(value[1]))
end
end
if value[2] ~= nil then value = value[2] end
end
end
end
local valSign = (valueUnsigned and '' or sign)
result = string.gsub(result, '{(V[^}]*)}', function(rule) return valSign .. formatModValue(value, rule) end)
result = string.gsub(result, '{S}', sign)


if doColor then
resultText = string.gsub(resultText, '${value}', function(rule) return (formatModValue(modMagnitude, rule) or '') end)
if isNegative ~= nil and isNegative then
 
result = '<span style="color:red">'..result..'</span>'
if doColor then
else
local colorCode = (isNegative ~= nil and isNegative and 'color:red' or 'color:green')
result = '<span style="color:green">'..result..'</span>'
resultText = '<span style="' .. colorCode .. '">' .. resultText .. '</span>'
end
end
table.insert(resultArray, resultText)
end
end


return result
return table.concat(resultArray, '<br/>')
end
end


Line 860: Line 1,037:


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


Line 866: Line 1,043:
end
end


function p.getModifiersText(modifiers, doColor)
function p.getModifiersText(modifiers, doColor, inline, maxVisible)
if modifiers == nil or Shared.tableCount(modifiers) == 0 then
if inline == nil then inline = false end
if type(maxVisible) ~= 'number' then maxVisible = nil end
if modifiers == nil or Shared.tableIsEmpty(modifiers) then
return ''
return ''
end
end


local modArray = {}
local modArray = { ["visible"] = {}, ["overflow"] = {} }
for bonus, value in Shared.skpairs(modifiers) do
local modCount = { ["visible"] = 0, ["overflow"] = 0 }
table.insert(modArray, p._getModifierText(bonus, value, doColor))
local insertKey = 'visible'
for bonus, value in pairs(modifiers) do
-- If there is a single by skill modifier with multiple values, this will
-- appear as multiple rows. Split these so the number of visible lines is
-- always accurate
local valueArray = nil
if type(value) == 'table' then
valueArray = value
else
valueArray = {value}
end
for i, subVal in ipairs(valueArray) do
if type(subVal) == 'table' and subVal.skillID ~= nil then
subVal = {subVal}
end
if maxVisible ~= nil and not inline and insertKey == 'visible' and modCount[insertKey] >= maxVisible then
insertKey = 'overflow'
end
table.insert(modArray[insertKey], p._getModifierText(bonus, subVal, doColor))
modCount[insertKey] = modCount[insertKey] + 1
end
end
if inline then
return table.concat(modArray['visible'], ' and ')
else
if modCount['overflow'] == 1 then
table.insert(modArray['visible'], modArray['overflow'][1])
end
local overflowText = ''
if modCount['overflow'] > 1 then
-- Number of other modifiers has exceeded the specified maximum
overflowText = table.concat({
'<br/><span class="mw-collapsible mw-collapsed" ',
'data-expandtext="Show ' .. Shared.formatnum(modCount['overflow']) .. ' more modifiers" ',
'data-collapsetext="Hide">',
table.concat(modArray['overflow'], '<br/>'),
'</span>'
})
end
return table.concat(modArray['visible'], '<br/>') .. overflowText
end
end
return table.concat(modArray, "<br/>")
end
end


Line 881: Line 1,098:
local skillArray = {}
local skillArray = {}


for modifier, value in Shared.skpairs(modifiers) do
for modifier, value in pairs(modifiers) do
if type(value) == 'table' then
if type(value) == 'table' then
for i, subVal in Shared.skpairs(value) do
for i, subVal in ipairs(value) do
local skillName = p.getSkillName(subVal[1])
if type(subVal) == 'table' and subVal.skillID ~= nil then
if not Shared.contains(skillArray, skillName) then
local skillName = p.getSkillName(subVal.skillID)
table.insert(skillArray, skillName)
if not Shared.contains(skillArray, skillName) then
table.insert(skillArray, skillName)
end
end
end
end
end
Line 893: Line 1,112:
local baseName = p.getModifierDetails(modifier)
local baseName = p.getModifierDetails(modifier)
if baseName == nil then
if baseName == nil then
return { 'ERROR: Modifier '..modifier..' is invalid' }
return { Shared.printError('Modifier "' .. modifier .. '" is invalid') }
end
end


Line 906: Line 1,125:


return skillArray
return skillArray
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
end


return p
return p
463

edits