您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a button to show all your modifiers
当前为
// ==UserScript== // @name Melvor Show Modifiers // @version 0.1.1 // @description Adds a button to show all your modifiers // @author GMiclotte // @match https://*.melvoridle.com/* // @exclude https://wiki.melvoridle.com/* // @grant none // @namespace http://tampermonkey.net/ // @noframes // ==/UserScript== function script() { class ShowModifiers { constructor(name, logName) { this.name = name; this.logName = logName; // increased - decreased this.creasedModifiers = { // modifiers that do not directly relate to skilling misc: { BankSpace: 0, BankSpaceShop: 0, }, // modifiers that relate to both combat and non-combat skilling skilling: { ChanceToPreservePotionCharge: 0, ChanceToDoubleItemsGlobal: 0, GPFromSales: 0, GPGlobal: 0, GlobalSkillXP: 0, HiddenSkillLevel: [], PotionChargesFlat: 0, SkillXP: [], SummoningChargePreservation: 0, }, // modifiers that only relate to combat and are not classified in a finer group combat: { AttackRolls: 0, ChanceToDoubleLootCombat: 0, DamageToAllMonsters: 0, DamageToBosses: 0, DamageToCombatAreaMonsters: 0, DamageToDungeonMonsters: 0, GPFromMonsters: 0, GPFromMonstersFlat: 0, GlobalAccuracy: 0, MaxHitFlat: 0, MaxHitPercent: 0, MaxHitpoints: 0, MinHitBasedOnMaxHit: 0, MonsterRespawnTimer: 0, AttackInterval: 0, AttackIntervalPercent: 0, ChanceToApplyBurn: 0, GPOnEnemyHit: 0, BleedLifesteal: 0, BurnLifesteal: 0, PoisonLifesteal: 0, FlatMinHit: 0, DamageTaken: 0, GlobalEvasion: 0, }, // modifiers that relate to healing hitpoints: { AutoEatEfficiency: 0, AutoEatHPLimit: 0, AutoEatThreshold: 0, FoodHealingValue: 0, HPRegenFlat: 0, HitpointRegeneration: 0, Lifesteal: 0, FlatMaxHitpoints: 0, }, // modifiers that relate to defence defence: { DamageReduction: 0, MagicEvasion: 0, MeleeEvasion: 0, RangedEvasion: 0, ReflectDamage: 0, FlatReflectDamage: 0, RolledReflectDamage: 0, DamageReductionPercent: 0, }, // modifiers that relate to using melee attacks melee: { MeleeAccuracyBonus: 0, MeleeStrengthBonus: 0, MeleeMaxHit: 0, MeleeLifesteal: 0, MeleeCritChance: 0, MeleeCritMult: 0, }, // modifiers that relate to using ranged attacks ranged: { AmmoPreservation: 0, RangedAccuracyBonus: 0, RangedStrengthBonus: 0, RangedMaxHit: 0, RangedLifesteal: 0, RangedCritChance: 0, RangedCritMult: 0, }, // modifiers that relate to using magic attacks magic: { MagicAccuracyBonus: 0, MagicDamageBonus: 0, MinAirSpellDmg: 0, MaxAirSpellDmg: 0, MinEarthSpellDmg: 0, MaxEarthSpellDmg: 0, MinFireSpellDmg: 0, MaxFireSpellDmg: 0, MinWaterSpellDmg: 0, MaxWaterSpellDmg: 0, RunePreservation: 0, MagicMaxHit: 0, MagicLifesteal: 0, MagicCritChance: 0, MagicCritMult: 0, Confusion: 0, Decay: 0, }, // modifiers that relate to slayer tasks, areas, or monsters slayer: { DamageToSlayerAreaMonsters: 0, DamageToSlayerTasks: 0, SlayerAreaEffectNegationFlat: 0, SlayerCoins: 0, SlayerTaskLength: 0, }, // modifiers that relate to prayer prayer: { ChanceToPreservePrayerPoints: 0, FlatPrayerCostReduction: 0, PrayerCost: 0, }, // modifiers that apply to general non-combat skilling nonCombat: { ChanceToDoubleItemsSkill: [], SkillInterval: [], SkillIntervalPercent: [], ChanceAdditionalSkillResource: [], }, production: { GlobalPreservationChance: 0, SkillPreservationChance: [], }, mastery: { GlobalMasteryXP: 0, MasteryXP: [], }, // specific skills agility: { GPFromAgility: 0, AgilityObstacleCost: 0, }, altMagic: { AltMagicSkillXP: 0, }, farming: { ChanceDoubleHarvest: 0, FarmingYield: 0, }, herblore: { ChanceRandomPotionHerblore: 0, }, mining: { ChanceNoDamageMining: 0, ChanceToDoubleOres: 0, MiningNodeHP: 0, }, runecrafting: { ChanceForElementalRune: 0, ElementalRuneGain: 0, AdditionalRunecraftCountRunes: 0, }, smithing: { SeeingGoldChance: 0, }, thieving: { ChanceToDoubleLootThieving: 0, GPFromThieving: 0, GPFromThievingFlat: 0, }, woodcutting: { BirdNestDropRate: 0, }, summoning: { SummoningShardCost: 0, SummoningCreationCharges: 0, }, // modifiers that are not actually implemented in the game unimplemented: { MaxStamina: 0, StaminaCost: 0, StaminaPerObstacle: 0, StaminaPreservationChance: 0, }, } this.singletonModifiers = { misc: { autoSlayerUnlocked: 0, dungeonEquipmentSwapping: 0, increasedEquipmentSets: 0, }, skilling: { allowSignetDrops: 0, increasedMasteryPoolProgress: 0, }, combat: { meleeProtection: 0, rangedProtection: 0, magicProtection: 0, curseImmunity: 0, stunImmunity: 0, sleepImmunity: 0, burnImmunity: 0, poisonImmunity: 0, bleedImmunity: 0, debuffImmunity: 0, increasedRebirthChance: 0, decreasedDragonBreathDamage: 0, increasedMeleeStunThreshold: 0, increasedRuneProvision: 0, increasedChanceToConvertSeedDrops: 0, bonusCoalOnDungeonCompletion: 0, bypassSlayerItems: 0, itemProtection: 0, autoLooting: 0, autoBurying: 0, increasedCombatStoppingThreshold: 0, increasedGPMultiplierPer1MGP: 0, increasedGPMultiplierCap: 0, increasedGPMultiplierMin: 0, allowAttackAugmentingMagic: 0, }, prayer: { increasedRedemptionPercent: 0, increasedRedemptionThreshold: 0, }, nonCombat: { increasedOffItemChance: 0, }, // specific skills cooking: { decreasedFoodBurnChance: 0, decreasedSecondaryFoodBurnChance: 0, }, farming: { freeCompost: 0, increasedCompostPreservationChance: 0, }, firemaking: { freeBonfires: 0, increasedFiremakingCoalChance: 0, }, mining: { increasedMiningGemChance: 0, doubleOresMining: 0, increasedBonusCoalMining: 0, }, smithing: { decreasedSmithingCoalCost: 0, }, thieving: { increasedThievingSuccessRate: 0, increasedThievingSuccessCap: 0, }, woodcutting: { increasedTreeCutLimit: 0, }, // golbin raid modifiers golbinRaid: { golbinRaidIncreasedMaximumAmmo: 0, golbinRaidIncreasedMaximumRunes: 0, golbinRaidIncreasedMinimumFood: 0, golbinRaidIncreasedPrayerLevel: 0, golbinRaidIncreasedPrayerPointsStart: 0, golbinRaidIncreasedPrayerPointsWave: 0, golbinRaidIncreasedStartingRuneCount: 0, golbinRaidPassiveSlotUnlocked: 0, golbinRaidPrayerUnlocked: 0, golbinRaidStartingWeapon: 0, golbinRaidWaveSkipCostReduction: 0, }, // summoning synergy modifiers, should be moved to the appropriate location, IF they are here to stay summoning: { summoningSynergy_0_1: 0, summoningSynergy_0_6: 0, summoningSynergy_0_7: 0, summoningSynergy_0_8: 0, summoningSynergy_0_12: 0, summoningSynergy_0_13: 0, summoningSynergy_0_14: 0, summoningSynergy_0_15: 0, summoningSynergy_1_2: 0, summoningSynergy_1_8: 0, summoningSynergy_1_12: 0, summoningSynergy_1_13: 0, summoningSynergy_1_14: 0, summoningSynergy_1_15: 0, summoningSynergy_2_6: 0, summoningSynergy_2_7: 0, summoningSynergy_2_8: 0, summoningSynergy_2_12: 0, summoningSynergy_2_13: 0, summoningSynergy_2_14: 0, summoningSynergy_2_15: 0, summoningSynergy_3_4: 0, summoningSynergy_3_5: 0, summoningSynergy_3_9: 0, summoningSynergy_3_10: 0, summoningSynergy_3_11: 0, summoningSynergy_3_16: 0, summoningSynergy_3_17: 0, summoningSynergy_3_18: 0, summoningSynergy_3_19: 0, summoningSynergy_4_5: 0, summoningSynergy_4_9: 0, summoningSynergy_4_10: 0, summoningSynergy_4_11: 0, summoningSynergy_4_16: 0, summoningSynergy_4_17: 0, summoningSynergy_4_18: 0, summoningSynergy_4_19: 0, summoningSynergy_5_9: 0, summoningSynergy_5_10: 0, summoningSynergy_5_11: 0, summoningSynergy_5_16: 0, summoningSynergy_5_17: 0, summoningSynergy_5_18: 0, summoningSynergy_6_7: 0, summoningSynergy_6_8: 0, summoningSynergy_6_12: 0, summoningSynergy_6_13: 0, summoningSynergy_6_14: 0, summoningSynergy_6_15: 0, summoningSynergy_7_8: 0, summoningSynergy_7_12: 0, summoningSynergy_7_13: 0, summoningSynergy_7_14: 0, summoningSynergy_7_15: 0, summoningSynergy_8_12: 0, summoningSynergy_8_13: 0, summoningSynergy_8_14: 0, summoningSynergy_9_10: 0, summoningSynergy_9_11: 0, summoningSynergy_9_16: 0, summoningSynergy_9_17: 0, summoningSynergy_9_18: 0, summoningSynergy_9_19: 0, summoningSynergy_10_11: 0, summoningSynergy_10_16: 0, summoningSynergy_10_17: 0, summoningSynergy_10_18: 0, summoningSynergy_10_19: 0, summoningSynergy_11_16: 0, summoningSynergy_11_17: 0, summoningSynergy_11_18: 0, summoningSynergy_11_19: 0, summoningSynergy_12_13: 0, summoningSynergy_12_14: 0, summoningSynergy_12_15: 0, summoningSynergy_13_14: 0, summoningSynergy_13_15: 0, summoningSynergy_14_15: 0, summoningSynergy_16_17: 0, summoningSynergy_16_18: 0, summoningSynergy_16_19: 0, summoningSynergy_17_18: 0, summoningSynergy_17_19: 0, summoningSynergy_18_19: 0, }, aprilFools: { aprilFoolsIncreasedMovementSpeed: 0, aprilFoolsDecreasedMovementSpeed: 0, aprilFoolsIncreasedTeleportCost: 0, aprilFoolsDecreasedTeleportCost: 0, aprilFoolsIncreasedUpdateDelay: 0, aprilFoolsDecreasedUpdateDelay: 0, aprilFoolsIncreasedLemonGang: 0, aprilFoolsDecreasedLemonGang: 0, aprilFoolsIncreasedCarrotGang: 0, aprilFoolsDecreasedCarrotGang: 0, } } this.knownModifiers = {}; Object.getOwnPropertyNames(this.creasedModifiers).forEach(subset => { Object.getOwnPropertyNames(this.creasedModifiers[subset]).forEach(modifier => { this.knownModifiers[`increased${modifier}`] = true; this.knownModifiers[`decreased${modifier}`] = true; }); }); Object.getOwnPropertyNames(this.singletonModifiers).forEach(subset => { Object.getOwnPropertyNames(this.singletonModifiers[subset]).forEach(modifier => { this.knownModifiers[modifier] = true; }); }); // check for unknown modifiers let hasUnknownModifiers = false; [ ...Object.getOwnPropertyNames(player.modifiers), ...player.modifiers.skillModifiers.keys() ].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!') } this.relevantModifiers = {}; // all this.relevantModifiers.all = { names: [ ...Object.getOwnPropertyNames(this.creasedModifiers).map(tag => this.creasedModifiers[tag]), ...Object.getOwnPropertyNames(this.singletonModifiers).map(tag => this.singletonModifiers[tag]), ], skillIDs: Object.getOwnPropertyNames(SKILLS).map(x => Number(x)), }; // misc this.relevantModifiers.misc = { names: [ this.creasedModifiers.misc, this.singletonModifiers.misc, ], skillIDs: [], }; // golbin raid this.relevantModifiers.golbin = { names: [this.singletonModifiers.golbinRaid], skillIDs: [], }; // all combat this.relevantModifiers.combat = { names: [ this.creasedModifiers.skilling, this.creasedModifiers.combat, this.creasedModifiers.hitpoints, this.creasedModifiers.defence, this.creasedModifiers.melee, this.creasedModifiers.ranged, this.creasedModifiers.magic, this.creasedModifiers.slayer, this.creasedModifiers.prayer, ], skillIDs: [ CONSTANTS.skill.Attack, CONSTANTS.skill.Strength, CONSTANTS.skill.Ranged, CONSTANTS.skill.Magic, CONSTANTS.skill.Defence, CONSTANTS.skill.Hitpoints, CONSTANTS.skill.Prayer, CONSTANTS.skill.Slayer, CONSTANTS.skill.Summoning, ], }; // melee combat this.relevantModifiers.melee = { names: [ this.creasedModifiers.skilling, this.creasedModifiers.combat, this.creasedModifiers.hitpoints, this.creasedModifiers.defence, this.creasedModifiers.melee, this.creasedModifiers.slayer, this.creasedModifiers.prayer, ], skillIDs: [ CONSTANTS.skill.Attack, CONSTANTS.skill.Strength, CONSTANTS.skill.Defence, CONSTANTS.skill.Hitpoints, CONSTANTS.skill.Prayer, CONSTANTS.skill.Slayer, CONSTANTS.skill.Summoning, ], }; // ranged combat this.relevantModifiers.ranged = { names: [ this.creasedModifiers.skilling, this.creasedModifiers.combat, this.creasedModifiers.hitpoints, this.creasedModifiers.defence, this.creasedModifiers.ranged, this.creasedModifiers.slayer, this.creasedModifiers.prayer, ], skillIDs: [ CONSTANTS.skill.Ranged, CONSTANTS.skill.Defence, CONSTANTS.skill.Hitpoints, CONSTANTS.skill.Prayer, CONSTANTS.skill.Slayer, CONSTANTS.skill.Summoning, ], }; // magic combat this.relevantModifiers.magic = { names: [ this.creasedModifiers.skilling, this.creasedModifiers.combat, this.creasedModifiers.hitpoints, this.creasedModifiers.defence, this.creasedModifiers.magic, this.creasedModifiers.slayer, this.creasedModifiers.prayer, ], skillIDs: [ CONSTANTS.skill.Magic, CONSTANTS.skill.Defence, CONSTANTS.skill.Hitpoints, CONSTANTS.skill.Prayer, CONSTANTS.skill.Slayer, CONSTANTS.skill.Summoning, ], }; // slayer this.relevantModifiers.slayer = { names: [ this.creasedModifiers.skilling, this.creasedModifiers.slayer, ], skillIDs: [ CONSTANTS.skill.Slayer, ], }; // gathering skills this.gatheringSkills = ['Woodcutting', 'Fishing', 'Mining', 'Thieving', 'Farming', 'Agility']; this.gatheringSkills.forEach(name => { this.relevantModifiers[name] = { names: [ this.creasedModifiers.skilling, this.creasedModifiers.nonCombat, this.creasedModifiers.mastery, ], skillIDs: [ CONSTANTS.skill[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 => { this.relevantModifiers[name] = { names: [ this.creasedModifiers.skilling, this.creasedModifiers.nonCombat, this.creasedModifiers.production, this.creasedModifiers.mastery, ], skillIDs: [ CONSTANTS.skill[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]); } }); // whatever alt magic is this.relevantModifiers.altMagic = { names: [ this.creasedModifiers.skilling, this.creasedModifiers.nonCombat, this.creasedModifiers.altMagic, ], skillIDs: [], }; // golbin raid this.relevantModifiers.golbinRaid = { names: [this.singletonModifiers.golbinRaid], skillIDs: [], }; } log(...args) { console.log(`${this.logName}:`, ...args); } printUniqueModifier(modifier, value) { if (!value) { return []; } return [printPlayerModifier(modifier, value)]; } 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 const increased = modifiers['increased' + modifier]; const decreased = modifiers['decreased' + modifier]; return (increased | 0) - (decreased | 0); } 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') { return map.get(skillID) | 0; } 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 | 0); } // creased return this.printDiffModifier(modifier, value | 0); } // skillModifiers return skillIDs.map(skillID => { const value = this.getSkillModifier(modifiers, modifier, skillID); if (this.isUniqueModifier(modifier)) { // unique return this.printUniqueModifier(modifier, value | 0); } // creased return this.printDiffModifier(modifier, value | 0, 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(names => Object.getOwnPropertyNames(names).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(player.modifiers, '${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, }); } } 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(player.modifiers, \'Active Modifiers\');" ` + 'aria-haspopup="true" ' + 'aria-expanded="true">' + `<img class="skill-icon-xxs" src="${getItemMedia(CONSTANTS.item.Event_Clue_1)}">` + '</button>' + '</div>'; } let node = document.getElementById('page-header-potions-dropdown').parentNode; node.parentNode.insertBefore($(modifierButton().trim())[0], node); } (function () { function injectScript(main) { const scriptElement = document.createElement('script'); scriptElement.textContent = `try {(${main})();} catch (e) {console.log(e);}`; document.body.appendChild(scriptElement).parentNode.removeChild(scriptElement); } function loadScript() { if ((window.isLoaded && !window.currentlyCatchingUp) || (typeof unsafeWindow !== 'undefined' && unsafeWindow.isLoaded && !unsafeWindow.currentlyCatchingUp)) { // Only load script after game has opened clearInterval(scriptLoader); injectScript(script); } } const scriptLoader = setInterval(loadScript, 200); })();