Melvor Idle - AutoSlayer

Automatically reroll and extend slayer tasks for specific monsters

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        Melvor Idle - AutoSlayer
// @description Automatically reroll and extend slayer tasks for specific monsters
// @version     1.0
// @namespace   Visua
// @match       https://melvoridle.com/*
// @match       https://www.melvoridle.com/*
// @grant       none
// ==/UserScript==
/* jshint esversion: 6 */

((main) => {
    var script = document.createElement('script');
    script.textContent = `try { (${main})(); } catch (e) { console.log(e); }`;
    document.body.appendChild(script).parentNode.removeChild(script);
})(() => {
    'use strict';

    const id = 'AutoSlayer';

    function loadAutoSlayer() {
        // Load settings
        let settings = {
            monsters: MONSTERS.map((m, i) => i).filter(id => MONSTERS[id].canSlayer),
            monstersToExtend: [],
        };
        const savedSettings = JSON.parse(localStorage.getItem(`${id}-${currentCharacter}`));
        if (savedSettings) {
            settings = savedSettings;
        }

        // Validate and save settings on change
        const settingsHandler = {
            set: function (obj, prop, value) {
                if (prop === 'monsters') {
                    if (!Array.isArray(value) || value.some(e => !Number.isInteger(e))) {
                        throw new TypeError('monsters should be an array of integers');
                    }
                } else if (prop === 'monstersToExtend') {
                    if (!Array.isArray(value) || value.some(e => !Number.isInteger(e))) {
                        throw new TypeError('monstersToExtend should be an array of integers');
                    }
                }

                obj[prop] = value;
                localStorage.setItem(`${id}-${currentCharacter}`, JSON.stringify(AUTOSLAYER.settings));
                console.log('Settings saved');
                return true;
            },
        };

        window.AUTOSLAYER = {
            settings: new Proxy(settings, settingsHandler),
        };

        const _autoSlayer = autoSlayer;
        const _getSlayerTask = getSlayerTask;

        function getAutoSlayerTask(monster, tier = 0) {
            _getSlayerTask(monster, tier);

            try {
                if (AUTOSLAYER.settings.monsters.includes(slayerTask[0].monsterID)) {
                    console.log(`AutoSlayer: Fighting ${MONSTERS[slayerTask[0].monsterID].name} x${slayerTask[0].count}`);
                    if (isInCombat && enemyInCombat !== slayerTask[0].monsterID) {
                        jumpToEnemy(slayerTask[0].monsterID);
                    }
                    if (AUTOSLAYER.settings.monstersToExtend.includes(slayerTask[0].monsterID)) {
                        extendSlayerTask();
                        console.log(`AutoSlayer: Extended to ${slayerTask[0].count}`);
                    }
                } else {
                    console.log(`AutoSlayer: Rerolling ${MONSTERS[slayerTask[0].monsterID].name}`);
                    // Temporarily set autoSlayer to true so we don't roll for monsters we can't fight
                    autoSlayer = true;
                    selectNewSlayerTask(tier);
                    // Set it to false again so we don't automatically jump to the new monster
                    autoSlayer = false;
                }
            } catch (e) {
                console.error(e);
            }
        };

        AUTOSLAYER.start = function () {
            console.log('AutoSlayer: Starting');
            getSlayerTask = getAutoSlayerTask;
            // This is just to indicate that we're making use of this setting to only roll for monsters we can fight
            autoSlayer = true;
            $('#setting-autoslayermonster').prop('checked', true);
        };

        AUTOSLAYER.stop = function () {
            console.log('AutoSlayer: Stopping');
            getSlayerTask = _getSlayerTask;
            // Restore the original setting
            autoSlayer = _autoSlayer;
            $('#setting-autoslayermonster').prop('checked', autoSlayer);
        };

        AUTOSLAYER.start();
    }

    function loadScript() {
        if (typeof confirmedLoaded !== 'undefined' && confirmedLoaded && !currentlyCatchingUp) {
            clearInterval(interval);
            console.log(`Loading ${id}`);
            loadAutoSlayer();
        }
    }

    const interval = setInterval(loadScript, 500);
});