GOTA_Extender_Auxiliary

Auxiliary functions for the page and the extender.

目前為 2014-10-29 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/5618/23138/GOTA_Extender_Auxiliary.js

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

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

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

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

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

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

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

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

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

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

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

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

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

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

var extender = {
    command: function (name, args) {
        var cmd = { name: name, args: args };
        $("textarea#observable").attr("command", JSON.stringify(cmd));
    },
    lastcommand: function () {
        return $("textarea#observable").attr("command");
    },
    option: function (option, val) {
        if (typeof option == "string") {
            this.command("option", [option, val]);
        } else {
            error("Please specify name and value as parameters.", "COMMAND");
        }
    }
};

var productionQueue = [];
function attemptProduction(bSymbol) {

    if (!productionQueue || productionQueue.length == 0) {
        log('Attempted production, but queue was missing or empty. Exiting...', "PRODUCTION");
        return;
    }

    if (typeof bSymbol != "undefined") {

        // Check this building for production
        var b = buildingBySymbol(bSymbol);

        if (buildingProducing(b)) {
            log("Building " + b.symbol + " is busy.", "PRODUCTION");
            return;
        }

        if (buildingFinished(b)) {
            log("Building " + b.symbol + " finished production.", "PRODUCTION");

            doFinishProduction(b.item_id, function() {
                attemptProduction(b.symbol);
            });

            return;
        }

        var element = getElement(b.symbol);
        if (element) {
            executeElement(element);
            return;
        }
    } else {

        for (var i = 0; i < userContext.buildingsData.length; i++) {
            var b = userContext.buildingsData[i];

            if (buildingProducing(b)) {
                log("Building " + b.symbol + " is busy.", "PRODUCTION");
                continue;
            }

            if (buildingFinished(b)) {
                log("Building " + b.symbol + " finished production.", "PRODUCTION");
                doFinishProduction(b.item_id, function() {
                    attemptProduction();
                });

                return;
            }

            var element = getElement(b.symbol);
            if (element) {
                executeElement(element, function () {
                    attemptProduction();
                });

                return;
            }
        }
    }
};

function getElement(buildingSymbol) {
    if (!productionQueue || productionQueue.length == 0) {
        log('Attempted to extract item from queue, but the production queue was missing or empty. Exiting...', "PRODUCTION");
        return null;
    }

    var element;

    for (var i = 0; i < productionQueue.length; i++) {

        if (productionQueue[i].activeBuildingPanel == buildingSymbol) {
            element = productionQueue[i];
            break;
        }
    }

    if (!element) {
        log('No elements enqueued for building ' + buildingSymbol + '. Array size: ' + productionQueue.length, "PRODUCTION");
        return null;
    }

    return element;
};

function executeElement(element, callback) {

    var index = productionQueue.indexOf(element);
    log('Production of element ' + element.name + ' : ' + element.type + ' with index ' + index + ' initiated.', "PRODUCTION");

    if (element.type == "item") {
        userContext.recipeData = element.recipeData;
        userContext.activeBuildingPanel = element.activeBuildingPanel;

        doProduction(element.outputSymbol, element.recipeCategory, null, null, element.recipeName, callback);
        productionQueue.splice(index, 1);

        log('Production details: ' + element.name + ' at ' + element.activeBuildingPanel + ', ' + element.outputSymbol + ', ' + element.recipeCategory + ', ' + element.recipeName + ';', "PRODUCTION");
    } else {

        var buildingId = buildingBySymbol(element.activeBuildingPanel).id;

        applySelectedUpgrade({ building_id: buildingId, id: element.upgradeId, gold: 0, silver: 0 }, null, callback);
        productionQueue.splice(index, 1);

        log('Production details: ' + element.name + ' : ' + element.type + ' at ' + element.activeBuildingPanel + ', ' + element.symbol + ';', "PRODUCTION");

    }
};

function buildingFinished(b) {
    return b.producing_archetype_id && !b.build_remaining;
}

function buildingProducing(b) {
    return b.producing_archetype_id && b.build_remaining;
}

var bruteForceTimeout;
function bruteForce(enabled, times) {

    var msg;
    var container = $("#bruteBtn");
    if (!container || container.length == 0) {
        container = $(".challengerewardbox .rewarditem:last");
    }

    if (!container || container.length == 0) {
        container = $(".challengerewards .challengerewarditems:first");
    }

    if (!container || container.length == 0) {
        msg = "Cannot find appropriate container for messaging!";
        warn(msg);        
    }

    if (typeof enabled == "boolean" && !enabled) {
        bruteForceTimeout = clearTimeout(bruteForceTimeout);

        msg = "Bruting terminated.";
        log(msg, "BRUTING");

        //        console.debug("Debuging message delivery: is there a container? " + (container) + ", " +
        //            "what's his length: " + container.length + ", append message? " + (container && container.length > 0) + ", " +
        //            "and what's the message: " + msg);

        if (container.hasClass("btnwrap btnmed")) {
            container.find("a").text("Done!");
        }

        container.after("<br />" + msg);

        if (times === "all") {
            bruteAll();
        }

        return;
    }

    // Do not run if bruting is disabled (but can be viewed)
    if (extender_bruteWounds && extender_bruteWounds == 0) {

        msg = "Disabled. Please set a positive number of max wounds from options to continue.";
        warn(msg, "BRUTING");

        // console.debug("Debuging message delivery: is there a container? " + (container) + ", " +
        // "what's his length: " + container.length + ", append message? " + (container && container.length > 0) + ", " +
        // "and what's the message: " + msg);

        container.after("<br />" + msg);

        bruteForce(false, times);
        return;
    }

    var s = userContext.setSwornSword;

    if (!s) {
        msg = "Failed, no sworn sword set.";
        error(msg, "BRUTING");

        container.after("<br />" + msg);
        bruteForce(false, times);
        return;
    }

    // console.debug("Debuging sworn sword condition: s.damage: " + s.damage + ", " +
    // "extender_bruteWounds: " + extender_bruteWounds + ", do bruting? " + (s.damage < extender_bruteWounds));

    if (s.damage < extender_bruteWounds) {

        if (!s.modifier) {

            // Calculate what attack shoild we use if there ain't any
            var max = Math.max(s.calc_battle, s.calc_trade, s.calc_intrigue);

            if (max == s.calc_intrigue) {
                s.modifier = "spy";
            } else if (max == s.calc_trade) {
                s.modifier = "barter";
            } else {
                s.modifier = "fight";
            }
        }

        // console.debug("Attack with: " + s.modifier);
        if (times == "once") {
            // console.debug("Attack with: " + s.modifier);            
            doAdventure("", s.modifier, false, function () {
                bruteForce(false, times);
            });
        } else {
            // console.debug("Attack with: " + s.modifier);
            doAdventure("", s.modifier, false, function () {
                bruteForce(true, times);
            });
        }

        return;
    }

    if (times === "all" || extender_bruteSwitchOff) {

        msg = "Sworn sword recieved " + extender_bruteWounds + " wounds! Brute timer will self terminate.";
        warn(msg, "BRUTING");

        // console.debug("Debuging message delivery: is there a container? " + (container) + ", " +
        // "what's his length: " + container.length + ", append message? " + (container && container.length > 0) + ", " +
        // "and what's the message: " + msg);

        container.after("<br />" + msg);

        bruteForce(false, times);

    } else {

        // Add a minute to the cooldown, and then multiply by wounds
        var interval = extender_bruteWounds * (s.damage_cooldown + 60);
        msg = "Sworn sword recieved " + extender_bruteWounds + " wounds! " +
            "Brute timer will self adjust. Wait " + extender_bruteWounds + " * (" + s.damage_cooldown + " + 60) = " + interval + " seconds.";

        warn(msg, "BRUTING");

        bruteForceTimeout = setTimeout(function () {
            bruteForce(true, times);
        }, interval * 1000);

        // console.debug("Debuging message delivery: is there a container? " + (container) + ", " +
        // "what's his length: " + container.length + ", append message? " + (container && container.length > 0) + ", " +
        // "and what's the message: " + msg);

        container.after("<br />" + msg);
    }
};

function bruteAll() {
    var sw = getSwornSwords();

    for (var i = 0; i < sw.length; i++) {
        var ss = sw[i];
        if (ss.cooldown > 0 || ss.damage_cooldown > 0 || ss.damage >= extender_bruteWounds) 
            continue;

        setSwornSword(ss.id);
        bruteForce(true, "all");
        return;
    }

    inform("All sworn swords have been bruted to maximum wounds.");

}

$(document).on("keyup", function (e) {
    if (e.keyCode == 27 && typeof bruteForceTimeout != "undefined") {
        e.preventDefault();
        e.stopPropagation();

        bruteForce(false);
        inform("Bruting terminated.");
    }
});

function increment(me) {
    var opt = $(me);

    var min = parseInt(opt.attr("min"));
    var max = parseInt(opt.attr("max"));
    var step = parseInt(opt.attr("step"));
    var val = parseInt(opt.text());

    if (isNaN(min) || isNaN(max) || isNaN(step) || isNaN(val)) {
        error("Parsing of attributes failed!", "number option");
        return;
    }

    var newVal = val + step > max ? min : val + step;
    opt.text(newVal);
};

function check(me) {
    $(me).toggleClass('checked');
};

function bruteSwitchToggle(me) {
    var bSwitch = $(me).find("a.btngold");
    bSwitch.text() == "switch off"
    ? bSwitch.text("adjust")
    : bSwitch.text("switch off");
};

function inputIncrement(me) {
    var input = $(me).parent().find("input[name='quantity']");
    if (!input || input.length == 0) {
        return;
    }

    var v = parseInt(input.val());
    var max = parseInt(input.attr("maxlength"));
    if (isNaN(v) || isNaN(max)) {
        return;
    }

    if (me.id == "excountup") {
        (max == 3 ? max = 999 : max = 99);
        (v + 1 > max ? v = max : v = v + 1);
    } else if (me.id == "excountdown") {
        (v - 1 < 0 ? v = 0 : v = v - 1);
    }
    input.val(v);
}

function sort(arr) {
    if (typeof arr == "undefined") {
        arr = playerInventory;
    }

    if (!(arr instanceof Array)) {
        error("Not an array! Sorting failed.");
        return arr;
    }
    
    // console.debug("Sorting of array initiated, check parameters: boons count: " + boons.length + ", " +
    // "sorting property: " + extender_boonsSortBy);

    arr.sort(function (a, b) {
        return b[extender_boonsSortBy2] - a[extender_boonsSortBy2];
    });

    arr.sort(function (a, b) {
        return b[extender_boonsSortBy] - a[extender_boonsSortBy];
    });

    log("Array sorted by " + extender_boonsSortBy + " and then by " + extender_boonsSortBy2 + " successfully.", "PAGE");
    return arr;

}

function sortShop(arr) {
    if (typeof arr == "undefined" || !(arr instanceof Array)) {
        error("Not an array. Please pass an array to be sorted.");
        return arr;
    }

     //console.debug("Sorting of array initiated, check array count: " + arr.length);    

    arr.sort(function(a, b) {

        //console.debug("Init first sorting, condition 1, properties exist: ", a.hasOwnProperty(extender_shopSortBy2), b.hasOwnProperty(extender_shopSortBy2));
        if (!a.hasOwnProperty(extender_shopSortBy2) || !b.hasOwnProperty(extender_shopSortBy2)) {
            return false;
        }        

        var aVal = a[extender_shopSortBy2];
        var bVal = b[extender_shopSortBy2];

        //console.debug("Logging property values: ", aVal, bVal);

        if (typeof aVal != "number" || typeof bVal != "number") {

            //console.debug("Values need parsing...");

            aVal = parseInt(aVal);
            bVal = parseInt(bVal);

            //console.debug("Parsed values: ", aVal, bVal);
            if (isNaN(aVal) || isNaN(bVal)) {
                return false;
            }
        }

        //console.debug("Sorting descending...");
        return bVal - aVal;
    });

    arr.sort(function (a, b) {

        //console.debug("Init second sorting, condition 1, properties exist: ", a.hasOwnProperty(extender_shopSortBy2), b.hasOwnProperty(extender_shopSortBy2));
        if (!a.hasOwnProperty(extender_shopSortBy) || !b.hasOwnProperty(extender_shopSortBy)) {
            return false;
        }
        
        var aVal = a[extender_shopSortBy];
        var bVal = b[extender_shopSortBy];

        //console.debug("Logging property values: ", aVal, bVal);

        if (typeof aVal != "number" || typeof bVal != "number") {

            //console.debug("Values need parsing...");

            aVal = parseInt(aVal);
            bVal = parseInt(bVal);

            //console.debug("Parsed values: ", aVal, bVal);
            if (isNaN(aVal) || isNaN(bVal)) {
                return false;
            }
            
        }

        //console.debug("Sorting descending...");
        return bVal - aVal;
    });

    // Array will always be sorted by gold, descending
    arr.sort(function (a, b) {
        return parseInt(a["price_perk_points"]) - parseInt(b["price_perk_points"]);
    });

    //console.debug("Sorted by gold: ");

    //arr.forEach(function (element) {
    //    console.debug(element["price_perk_points"]);
    //});

    log("Array sorted by " + extender_shopSortBy + " and then by " + extender_shopSortBy2 + " successfully.", "PAGE");
    return arr;

}

function formatStats(battle, trade, intrigue, level) {
    return '<div class="exstatbox">' +
        '<div id="plevel" class="statitem">' +
        '<div><span></span>' +
        '</div><var>' + level + '</var></div>' +
        '<div id="battle" class="statitem">' +
        '<div><span></span>' +
        '</div><var class="battle_val" id="battle_val">' + battle + '</var></div>' +
        '<div id="trade" class="statitem">' +
        '<div><span></span>' +
        '</div><var class="trade_val" id="trade_val">' + trade + '</var></div>' +
        '<div id="intrigue" class="statitem">' +
        '<div><span></span></div>' +
        '<var class="intrigue_val" id="intrigue_val">' + intrigue + '</var></div>' +
        '</div>';
}

function getSwornSwords() {
    var ss = [];
    var pi = playerInventory;
    for (var i = 0; i < pi.length; i++) {
        var s = pi[i];
        if (s.slot == "Sworn Sword") {
            ss.push(s);
        }
    }

    return ss;
}

function setSwornSword(id) {
    if (typeof id == "undefined") {
        return;
    }

    var s = extractItemById(playerInventory, id);
    s && (userContext.setSwornSword = s);

}

function sendAll(adventure, swornswords) {

    if (typeof swornswords == "undefined" || !(swornswords instanceof window.Array)) {
        error("An array should be passed to the function. Sending failed.");
        return;
    }

    if (typeof adventure != "string") {
        error("Adventure should be passed as a string. Sending failed.");
        return;
    }

    if (swornswords.length == 0) {
        log('All sworn swords send on ' + adventure + '.');
        return;
    }

    var s = swornswords.pop();

    log("Debuging send all: swornswords: " + swornswords.length + "," +
        "cooldown: " + s.cooldown + "," +
        "damage: " + s.damage + ", " +
        "send? " + !(swornswords.length > 0 && (s.cooldown > 0 || s.damage >= extender_bruteWounds)));

    while (swornswords.length > 0 && (s.cooldown > 0 || s.damage >= extender_bruteWounds)) {
        s = swornswords.pop();
    }

    if (swornswords.length == 0) {
        inform("All sworn swords send on " + adventure + ".");
        return;
    }

    setSwornSword(s.id);

    if (!s.modifier) {
        // Calculate what attack shoild we use if there ain't any
        var max = Math.max(s.calc_battle, s.calc_trade, s.calc_intrigue);
        if (max == s.calc_intrigue) {
            s.modifier = 'spy';
        } else if (max == s.calc_trade) {
            s.modifier = 'barter';
        } else {
            s.modifier = 'fight';
        }
    }

    doAdventure(adventure, s.modifier, false, function () {
        sendAll(adventure, swornswords);
    });

}