您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a button to show all your modifiers
// ==UserScript== // @name Melvor Show Modifiers // @namespace http://tampermonkey.net/ // @version 0.2.13 // @description Adds a button to show all your modifiers // @author GMiclotte // @include https://melvoridle.com/* // @include https://*.melvoridle.com/* // @exclude https://melvoridle.com/index.php // @exclude https://*.melvoridle.com/index.php // @exclude https://wiki.melvoridle.com/* // @exclude https://*.wiki.melvoridle.com/* // @inject-into page // @noframes // @grant none // ==/UserScript== ((main) => { const script = document.createElement('script'); script.textContent = `try { (${main})(); } catch (e) { console.log(e); }`; document.body.appendChild(script).parentNode.removeChild(script); })(() => { class ShowModifiers { constructor(name, logName, check = true) { this.name = name; this.logName = logName; // increased - decreased this.creasedModifiers = { // modifiers that do not directly relate to skilling misc: [ 'BankSpace', 'BankSpaceShop', ], // modifiers that relate to both combat and non-combat skilling skilling: [ 'ChanceToPreservePotionCharge', 'ChanceToDoubleItemsGlobal', 'GPFromSales', 'GPGlobal', 'GlobalSkillXP', 'HiddenSkillLevel', 'PotionChargesFlat', 'SkillXP', 'SummoningChargePreservation', ], // modifiers that only relate to combat and are not classified in a finer group combat: [ 'AttackRolls', 'ChanceToDoubleLootCombat', 'DamageToAllMonsters', 'DamageToBosses', 'DamageToCombatAreaMonsters', 'DamageToDungeonMonsters', 'GPFromMonsters', 'GPFromMonstersFlat', 'GlobalAccuracy', 'MaxHitFlat', 'MaxHitPercent', 'MaxHitpoints', 'MinHitBasedOnMaxHit', 'MonsterRespawnTimer', 'AttackInterval', 'AttackIntervalPercent', 'ChanceToApplyBurn', 'GPOnEnemyHit', 'BleedLifesteal', 'BurnLifesteal', 'PoisonLifesteal', 'FlatMinHit', 'DamageTaken', 'GlobalEvasion', ], // modifiers that relate to healing hitpoints: [ 'AutoEatEfficiency', 'AutoEatHPLimit', 'AutoEatThreshold', 'FoodHealingValue', 'HPRegenFlat', 'HitpointRegeneration', 'Lifesteal', 'FlatMaxHitpoints', ], // modifiers that relate to defence defence: [ 'DamageReduction', 'MagicEvasion', 'MeleeEvasion', 'RangedEvasion', 'ReflectDamage', 'FlatReflectDamage', 'RolledReflectDamage', 'DamageReductionPercent', ], // modifiers that relate to using melee attacks attack: [], strength: [], melee: [ 'MeleeAccuracyBonus', 'MeleeStrengthBonus', 'MeleeMaxHit', 'MeleeLifesteal', 'MeleeCritChance', ], // modifiers that relate to using ranged attacks ranged: [ 'AmmoPreservation', 'RangedAccuracyBonus', 'RangedStrengthBonus', 'RangedMaxHit', 'RangedLifesteal', 'RangedCritChance', ], // modifiers that relate to using magic attacks magic: [ 'MagicAccuracyBonus', 'MagicDamageBonus', 'MinAirSpellDmg', 'MaxAirSpellDmg', 'MinEarthSpellDmg', 'MaxEarthSpellDmg', 'MinFireSpellDmg', 'MaxFireSpellDmg', 'MinWaterSpellDmg', 'MaxWaterSpellDmg', 'RunePreservation', 'MagicMaxHit', 'MagicLifesteal', 'MagicCritChance', ], // modifiers that relate to slayer tasks, areas, or monsters slayer: [ 'DamageToSlayerAreaMonsters', 'DamageToSlayerTasks', 'SlayerAreaEffectNegationFlat', 'SlayerCoins', 'SlayerTaskLength', ], // modifiers that relate to prayer prayer: [ 'ChanceToPreservePrayerPoints', 'FlatPrayerCostReduction', 'PrayerCost', ], // modifiers that apply to general non-combat skilling nonCombat: [ 'ChanceToDoubleItemsSkill', 'SkillInterval', 'SkillIntervalPercent', 'ChanceAdditionalSkillResource', ], production: [ 'GlobalPreservationChance', 'SkillPreservationChance', ], mastery: [ 'GlobalMasteryXP', 'MasteryXP', ], // specific skills agility: [ 'GPFromAgility', 'AgilityObstacleCost', ], altMagic: [ 'AltMagicSkillXP', 'AltMagicRunePreservation', 'RunePreservation', ], astrology: [], cooking: [ 'ChanceSuccessfulCook', 'ChancePerfectCookGlobal', 'ChancePerfectCookFire', 'ChancePerfectCookFurnace', 'ChancePerfectCookPot', ], crafting: [], farming: [ 'ChanceDoubleHarvest', 'FarmingYield', 'AllotmentSeedCost', ], firemaking: [ 'ChanceForDiamondFiremaking', 'GPFromFiremaking', ], fishing: [ 'FishingSpecialChance', ], fletching: [], herblore: [ 'ChanceRandomPotionHerblore', ], mining: [ 'ChanceNoDamageMining', 'ChanceToDoubleOres', 'MiningNodeHP', ], runecrafting: [ 'ChanceForElementalRune', 'ElementalRuneGain', 'AdditionalRunecraftCountRunes', ], smithing: [ 'SeeingGoldChance', ], summoning: [ 'SummoningMaxHit', ], nonCBSummoning: [ 'SummoningShardCost', 'SummoningCreationCharges', ], thieving: [ 'ChanceToDoubleLootThieving', 'GPFromThieving', 'GPFromThievingFlat', 'ThievingStealth', 'MinThievingGP', ], woodcutting: [ 'BirdNestDropRate', ], // golbin raid golbinRaid: [], // aprilFools aprilFools: [], // modifiers that are not actually implemented in the game unimplemented: [ 'MaxStamina', 'StaminaCost', 'StaminaPerObstacle', 'StaminaPreservationChance', ], } // unique modifiers, i.e. not in+de creased this.singletonModifiers = { misc: [ 'autoSlayerUnlocked', 'dungeonEquipmentSwapping', 'increasedEquipmentSets', ], skilling: [ 'allowSignetDrops', 'increasedMasteryPoolProgress', ], combat: [ 'meleeProtection', 'rangedProtection', 'magicProtection', 'meleeImmunity', 'rangedImmunity', 'magicImmunity', 'otherStyleImmunity', 'curseImmunity', 'stunImmunity', 'sleepImmunity', 'burnImmunity', 'poisonImmunity', 'bleedImmunity', 'debuffImmunity', 'slowImmunity', 'frostBurnImmunity', 'masteryToken', 'autoEquipFoodUnlocked', 'autoSwapFoodUnlocked', 'masteryToken', 'freeProtectItem', 'globalEvasionHPScaling', 'increasedRebirthChance', 'decreasedDragonBreathDamage', 'increasedMeleeStunThreshold', 'increasedChanceToIncreaseStunDuration', 'increasedRuneProvision', 'increasedChanceToConvertSeedDrops', 'increasedAfflictionChance', 'increasedChanceToApplyPoison', 'increasedChanceToApplyFrostburn', 'increasedEndOfTurnHealing2', 'increasedEndOfTurnHealing3', 'increasedEndOfTurnHealing5', 'increasedTotalBleedDamage', 'increasedOnHitSlowMagnitude', 'increasedNonMagicPoisonChance', 'increasedFrostburn', 'increasedPoisonReflectChance', 'increasedBleedReflectChance', 'bonusCoalOnDungeonCompletion', 'bypassSlayerItems', 'itemProtection', 'autoLooting', 'autoBurying', 'increasedGPMultiplierPer1MGP', 'increasedGPMultiplierCap', 'increasedGPMultiplierMin', 'allowAttackAugmentingMagic', 'summoningSynergy_0_1', 'summoningSynergy_0_6', 'summoningSynergy_0_7', 'summoningSynergy_0_8', 'summoningSynergy_0_12', 'summoningSynergy_0_13', 'summoningSynergy_0_14', 'summoningSynergy_0_15', 'summoningSynergy_1_2', 'summoningSynergy_1_8', 'summoningSynergy_1_12', 'summoningSynergy_1_13', 'summoningSynergy_1_14', 'summoningSynergy_1_15', 'summoningSynergy_2_13', 'summoningSynergy_2_15', 'summoningSynergy_6_13', 'summoningSynergy_7_13', 'summoningSynergy_8_13', 'summoningSynergy_12_13', 'summoningSynergy_12_14', 'summoningSynergy_13_14', 'increasedChanceToPreserveFood', 'allowLootContainerStacking', 'infiniteLootContainer', ], hitpoints: [ 'decreasedRegenerationInterval', ], defence: [], attack: [], strength: [], melee: [ 'increasedMeleeStunChance', 'summoningSynergy_6_7', 'summoningSynergy_6_12', 'summoningSynergy_6_14', 'summoningSynergy_6_15', ], ranged: [ 'summoningSynergy_7_8', 'summoningSynergy_7_12', 'summoningSynergy_7_14', 'summoningSynergy_7_15', ], magic: [ 'increasedConfusion', 'increasedDecay', 'summoningSynergy_6_8', 'summoningSynergy_8_14', 'increasedMinNatureSpellDamageBasedOnMaxHit', 'increasedSurgeSpellAccuracy', 'increasedSurgeSpellMaxHit', 'increasedElementalEffectChance', ], slayer: [ 'summoningSynergy_2_12', 'summoningSynergy_8_12', ], prayer: [ 'increasedRedemptionPercent', 'increasedRedemptionThreshold', ], nonCombat: [ 'increasedOffItemChance', 'doubleItemsSkill', ], production: [], mastery: [], // specific skills agility: [], altMagic: [], astrology: [ 'increasedBaseStardustDropQty', ], cooking: [ 'decreasedSecondaryFoodBurnChance', 'summoningSynergy_3_9', 'summoningSynergy_4_9', 'summoningSynergy_9_17', 'summoningSynergy_9_18', 'summoningSynergy_9_19', ], crafting: [ 'summoningSynergy_5_16', 'summoningSynergy_9_16', 'summoningSynergy_10_16', 'summoningSynergy_16_17', 'summoningSynergy_16_18',], farming: [ 'freeCompost', 'increasedCompostPreservationChance', ], firemaking: [ 'freeBonfires', 'increasedFiremakingCoalChance', 'summoningSynergy_3_19', 'summoningSynergy_4_19', 'summoningSynergy_9_19', 'summoningSynergy_16_19', 'summoningSynergy_18_19', ], fishing: [ 'summoningSynergy_3_5', 'summoningSynergy_4_5', 'summoningSynergy_5_9', 'summoningSynergy_5_18',], fletching: [], herblore: [], mining: [ 'increasedMiningGemChance', 'doubleOresMining', 'increasedBonusCoalMining', 'summoningSynergy_4_5', 'summoningSynergy_4_10', 'summoningSynergy_4_16', 'summoningSynergy_4_17', 'summoningSynergy_4_18', ], runecrafting: [ 'increasedRunecraftingEssencePreservation', 'summoningSynergy_3_10', 'summoningSynergy_5_10', 'summoningSynergy_10_17', 'summoningSynergy_10_18', 'summoningSynergy_10_19',], smithing: [ 'decreasedSmithingCoalCost', 'summoningSynergy_5_17', 'summoningSynergy_9_17', 'summoningSynergy_10_17', 'summoningSynergy_17_18', 'summoningSynergy_17_19', ], summoning: [], nonCBSummoning: [], thieving: [ 'increasedThievingSuccessRate', 'increasedThievingSuccessCap', 'summoningSynergy_3_11', 'summoningSynergy_4_11', 'summoningSynergy_5_11', 'summoningSynergy_9_11', 'summoningSynergy_10_11', 'summoningSynergy_11_16', 'summoningSynergy_11_17', 'summoningSynergy_11_18', 'summoningSynergy_11_19', ], woodcutting: [ 'increasedTreeCutLimit', 'summoningSynergy_3_4', 'summoningSynergy_3_16', 'summoningSynergy_3_17', 'summoningSynergy_3_18', 'summoningSynergy_3_19', ], // golbin raid modifiers golbinRaid: [ 'golbinRaidIncreasedMaximumAmmo', 'golbinRaidIncreasedMaximumRunes', 'golbinRaidIncreasedMinimumFood', 'golbinRaidIncreasedPrayerLevel', 'golbinRaidIncreasedPrayerPointsStart', 'golbinRaidIncreasedPrayerPointsWave', 'golbinRaidIncreasedStartingRuneCount', 'golbinRaidPassiveSlotUnlocked', 'golbinRaidPrayerUnlocked', 'golbinRaidStartingWeapon', 'golbinRaidWaveSkipCostReduction', ], // chaos mode modifiers aprilFools: [ 'aprilFoolsIncreasedMovementSpeed', 'aprilFoolsDecreasedMovementSpeed', 'aprilFoolsIncreasedTeleportCost', 'aprilFoolsDecreasedTeleportCost', 'aprilFoolsIncreasedUpdateDelay', 'aprilFoolsDecreasedUpdateDelay', 'aprilFoolsIncreasedLemonGang', 'aprilFoolsDecreasedLemonGang', 'aprilFoolsIncreasedCarrotGang', 'aprilFoolsDecreasedCarrotGang', ], unimplemented: [], } if (check) { this.checkUnknownModifiers(); } // map of relevant modifiers per tag this.relevantModifiers = {}; // all this.relevantModifiers.all = this.getModifierNames( Object.getOwnPropertyNames(this.creasedModifiers), Object.getOwnPropertyNames(SKILLS).map(x => Number(x)), ); // misc this.relevantModifiers.misc = this.getModifierNames(['misc'], []); // golbin raid this.relevantModifiers.golbin = this.getModifierNames(['golbinRaid'], []); // all combat this.relevantModifiers.combat = this.getModifierNames( [ 'skilling', 'combat', ], [ Skills.Attack, Skills.Strength, Skills.Ranged, Skills.Magic, Skills.Defence, Skills.Hitpoints, Skills.Prayer, Skills.Slayer, Skills.Summoning, ], ); // melee combat this.relevantModifiers.melee = this.getModifierNames( [ 'skilling', 'combat', ], [ Skills.Attack, Skills.Strength, Skills.Defence, Skills.Hitpoints, Skills.Prayer, Skills.Slayer, Skills.Summoning, ], ); // ranged combat this.relevantModifiers.ranged = this.getModifierNames( [ 'skilling', 'combat', ], [ Skills.Ranged, Skills.Defence, Skills.Hitpoints, Skills.Prayer, Skills.Slayer, Skills.Summoning, ], ); // magic combat this.relevantModifiers.magic = this.getModifierNames( [ 'skilling', 'combat', 'hitpoints', ], [ Skills.Magic, Skills.Defence, Skills.Hitpoints, Skills.Prayer, Skills.Slayer, Skills.Summoning, ], ); // slayer this.relevantModifiers.slayer = this.getModifierNames( [ 'skilling', ], [ Skills.Slayer, ], ); // gathering skills this.gatheringSkills = ['Woodcutting', 'Fishing', 'Mining', 'Thieving', 'Farming', 'Agility', 'Astrology']; this.gatheringSkills.forEach(name => { this.relevantModifiers[name] = this.getModifierNames( [ 'skilling', 'nonCombat', 'mastery', ], [ Skills[name] ], ); const lname = name.toLowerCase(); if (this.creasedModifiers[lname] !== undefined) { this.relevantModifiers[name].names.push(this.creasedModifiers[lname]); } if (this.singletonModifiers[lname] !== undefined) { this.relevantModifiers[name].names.push(this.singletonModifiers[lname]); } }); // production skills this.productionSkills = ['Firemaking', 'Cooking', 'Smithing', 'Fletching', 'Crafting', 'Runecrafting', 'Herblore', 'Summoning']; this.productionSkills.forEach(name => { const setNames = [ 'skilling', 'nonCombat', 'production', 'mastery', ]; if (name === 'Summoning') { setNames.push('nonCBSummoning'); } this.relevantModifiers[name] = this.getModifierNames( setNames, [ Skills[name] ], ); }); // whatever alt magic is this.relevantModifiers.altMagic = this.getModifierNames( [ 'skilling', 'nonCombat', 'altMagic', ], [], ); // golbin raid this.relevantModifiers.golbinRaid = this.getModifierNames( ['golbinRaid'], [], ); } log(...args) { console.log(`${this.logName}:`, ...args); } checkUnknownModifiers() { // list of known modifiers this.knownModifiers = {}; for (const subset in this.creasedModifiers) { this.creasedModifiers[subset].forEach(modifier => { this.knownModifiers[`increased${modifier}`] = true; this.knownModifiers[`decreased${modifier}`] = true; }); } for (const subset in this.singletonModifiers) { this.singletonModifiers[subset].forEach(modifier => { this.knownModifiers[modifier] = true; }); } // check for unknown modifiers const modifierNames = [ ...Object.getOwnPropertyNames(player.modifiers), // player.modifiers.skillModifiers ...Object.getOwnPropertyNames(modifierData).filter(x => modifierData[x].isSkill), ]; let hasUnknownModifiers = false; modifierNames.forEach(modifier => { if (modifier === 'skillModifiers') { return; } if (this.knownModifiers[modifier]) { return; } hasUnknownModifiers = true; this.log(`unknown modifier ${modifier}`); }); if (!hasUnknownModifiers) { this.log('no unknown modifiers detected!') } // check for non-existent modifiers let hasNonExistentModifiers = false; for (const modifier in this.knownModifiers) { if (!modifierNames.includes(modifier)) { hasNonExistentModifiers = true; this.log(`non-existent modifier ${modifier}`); } } if (!hasNonExistentModifiers) { this.log('no non-existent modifiers detected!') } } getModifierNames(setNames, skillIDs) { // add skill based on skillID skillIDs.forEach(id => { if (!setNames.includes(Skills[id])) { setNames.push(Skills[id].toLowerCase()); } }); // add melee based on att/str skillID if (skillIDs.includes(Skills.Attack) || skillIDs.includes(Skills.Strength)) { if (!setNames.includes('melee')) { setNames.push('melee'); } } // gather modifiers return { names: [...new Set([ ...setNames.map(name => this.creasedModifiers[name]).reduce((a, x) => [...a, ...x], []), ...setNames.map(name => this.singletonModifiers[name]).reduce((a, x) => [...a, ...x], []), ])], skillIDs: skillIDs, }; } printUniqueModifier(modifier, value, skillID) { if (!value) { return []; } // convert to array if required const valueToPrint = skillID !== undefined ? [skillID, value] : value; return [printPlayerModifier(modifier, valueToPrint)]; } printDiffModifier(modifier, value, skillID = undefined) { // compute difference if (!value) { return []; } // store if value is positive or negative const positive = value > 0; // take absolute value let valueToPrint = positive ? value : -value; // convert to array if required valueToPrint = skillID !== undefined ? [skillID, valueToPrint] : valueToPrint; // print increased or decreased if (positive) { return [printPlayerModifier('increased' + modifier, valueToPrint)]; } return [printPlayerModifier('decreased' + modifier, valueToPrint)]; } getModifierValue(modifiers, modifier, skillID = undefined) { if (!this.isSkillModifier(modifier)) { return this.getSimpleModifier(modifiers, modifier); } return this.getSkillModifier(modifiers, modifier, skillID); } getSimpleModifier(modifiers, modifier) { // unique if (this.isUniqueModifier(modifier)) { return modifiers[modifier]; } // creased let increased = modifiers['increased' + modifier]; if (!increased) { increased = 0; } let decreased = modifiers['decreased' + modifier]; if (!decreased) { decreased = 0; } return increased - decreased; } getSkillModifier(modifiers, modifier, skillID) { const skillModifiers = modifiers.skillModifiers ? modifiers.skillModifiers : modifiers; // unique if (this.isUniqueModifier(modifier)) { const map = this.skillModifierMapAux(skillModifiers, modifier); return this.skillModifierAux(map, skillID); } // creased const increased = this.skillModifierMapAux(skillModifiers, 'increased' + modifier); const decreased = this.skillModifierMapAux(skillModifiers, 'decreased' + modifier); return this.skillModifierAux(increased, skillID) - this.skillModifierAux(decreased, skillID); } skillModifierMapAux(map, skillID) { if (!map) { return []; } let tmp; if (map.constructor.name === 'Map') { tmp = map.get(skillID); } else { tmp = map[skillID]; } return tmp ? tmp : []; } skillModifierAux(map, skillID) { if (!map || map.length === 0) { return 0; } if (map.constructor.name === 'Map') { const value = map.get(skillID); if (!value) { return 0 } return value; } return map.filter(x => x[0] === skillID) .map(x => x[1]) .reduce((a, b) => a + b, 0); } printModifier(modifiers, modifier, skillIDs) { if (!this.isSkillModifier(modifier)) { const value = this.getSimpleModifier(modifiers, modifier); if (this.isUniqueModifier(modifier)) { // unique return this.printUniqueModifier(modifier, value); } // creased return this.printDiffModifier(modifier, value); } // skillModifiers return skillIDs.map(skillID => { const value = this.getSkillModifier(modifiers, modifier, skillID); if (this.isUniqueModifier(modifier)) { // unique return this.printUniqueModifier(modifier, value, skillID); } // creased return this.printDiffModifier(modifier, value, skillID); }).reduce((a, b) => a.concat(b), []); } isUniqueModifier(modifier) { return modifierData[modifier] !== undefined; } isSkillModifier(modifier) { if (this.isUniqueModifier(modifier)) { return modifierData[modifier].isSkill; } const data = modifierData['increased' + modifier]; if (data === undefined) { // this.log(`Unknown modifier ${modifier}`); return false; } return data.isSkill; } printRelevantModifiers(modifiers, tag) { const relevantNames = this.relevantModifiers[tag].names; const skillIDs = this.relevantModifiers[tag].skillIDs; const toPrint = []; relevantNames.forEach(name => { this.printModifier(modifiers, name, skillIDs).forEach(result => toPrint.push(result)); }); return toPrint; } makeTagButton(tag, text, icon) { return '<div class="dropdown d-inline-block ml-2">' + '<button type="button" ' + 'class="btn btn-sm btn-dual text-combat-smoke" ' + 'id="page-header-modifiers" ' + `onclick="window.${this.name}.replaceRelevantModifiersHtml(window.${this.name}.getModifiers(), '${text}', '${tag}');" ` + 'aria-haspopup="true" ' + 'aria-expanded="true">' + `<img class="skill-icon-xxs" src="${icon}">` + '</button>' + '</div>'; } replaceRelevantModifiersHtml(modifiers, text, tag) { $('#show-modifiers').replaceWith(this.printRelevantModifiersHtml(modifiers, text, tag)); } printRelevantModifiersHtml(modifiers, text, tag, id = 'show-modifiers') { let passives = `<div id="${id}"><br/>`; passives += `<h5 class=\"font-w400 font-size-sm mb-1\">${text}</h5><br/>`; this.printRelevantModifiers(modifiers, tag).forEach(toPrint => { passives += `<h5 class=\"font-w400 font-size-sm mb-1 ${toPrint[1]}\">${toPrint[0]}</h5>`; }); passives += '</div>'; return passives; } showRelevantModifiers(modifiers, text, tag = 'all') { let passives = `<h5 class=\"font-w600 font-size-sm mb-1 text-combat-smoke\">${text}</h5><h5 class=\"font-w600 font-size-sm mb-3 text-warning\"></h5>`; passives += `<h5 class="font-w600 font-size-sm mb-3 text-warning"><small>(Does not include non-modifier effects)</small></h5>`; passives += this.makeTagButton('all', 'All Modifiers', 'assets/media/main/completion_log.svg'); passives += this.makeTagButton('golbinRaid', 'Golbin Raid', 'assets/media/main/raid_coins.svg'); passives += this.makeTagButton('combat', 'Combat', 'assets/media/skills/combat/combat.svg'); passives += this.makeTagButton('melee', 'Melee', 'assets/media/skills/attack/attack.svg'); passives += this.makeTagButton('ranged', 'Ranged', 'assets/media/skills/ranged/ranged.svg'); passives += this.makeTagButton('magic', 'Combat Magic', 'assets/media/skills/combat/spellbook.svg'); passives += this.makeTagButton('slayer', 'Slayer', 'assets/media/skills/slayer/slayer.svg'); passives += '<br/>'; this.gatheringSkills.forEach(skill => passives += this.makeTagButton(skill, skill, `assets/media/skills/${skill.toLowerCase()}/${skill.toLowerCase()}.svg`)); passives += '<br/>'; this.productionSkills.forEach(skill => passives += this.makeTagButton(skill, skill, `assets/media/skills/${skill.toLowerCase()}/${skill.toLowerCase()}.svg`)); passives += this.makeTagButton('altMagic', 'Alt. Magic', 'assets/media/skills/magic/magic.svg'); passives += this.printRelevantModifiersHtml(modifiers, 'All Modifiers', tag); Swal.fire({ html: passives, }); } getModifiers() { return game.isGolbinRaid ? game.golbinRaid.player.modifiers : player.modifiers; } } function startShowModifiers() { const name = 'melvorShowModifiers'; window[name] = new ShowModifiers(name, 'Show Modifiers'); let modifierButton = () => { return '<div class="dropdown d-inline-block ml-2">' + '<button type="button" ' + 'class="btn btn-sm btn-dual text-combat-smoke" ' + 'id="page-header-modifiers" ' + `onclick="window.${name}.showRelevantModifiers(window.${name}.getModifiers(), \'Active Modifiers\');" ` + 'aria-haspopup="true" ' + 'aria-expanded="true">' + `<img class="skill-icon-xxs" src="${getItemMedia(Items.Event_Clue_1)}">` + '</button>' + '</div>'; } let node = document.getElementById('page-header-potions-dropdown').parentNode; node.parentNode.insertBefore($(modifierButton().trim())[0], node); } function loadScript() { if (typeof confirmedLoaded !== typeof undefined && confirmedLoaded) { // Only load script after game has opened clearInterval(scriptLoader); startShowModifiers(); } } const scriptLoader = setInterval(loadScript, 200); });