Greasy Fork

Greasy Fork is available in English.

Kittens tools

Kittens tools (visual)

目前为 2018-12-18 提交的版本,查看 最新版本

// ==UserScript==
// @name         Kittens tools
// @namespace    http://bloodrizer.ru/games/kittens/
// @version      1.085
// @description  Kittens tools (visual)
// @author       Anton
// @match        http://bloodrizer.ru/games/kittens/
// @require      https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.2.22/cytoscape.min.js
// ==/UserScript==

(function() {
	'use strict';

	var $ = jQuery;

	var _BotSettings = {
	    autoBuy: false,
	    autoPromoteKittens: true,
        autoCollectFaith: true,
        autoCreateSteel: true,
        autoCreatePlates: true,
        autoSendHunters: true,
        autoCreateManuscript: true,
        autoCreateWood: true,
        autoCreateBeams: true,
        autoCreateSlabs: true,
        autoCreateCompendium: true,
	    init: function () {
            _BotUI.initSettingsLink();
            _BotUI.initSettingsPage();
            _BotSettings.restoreAll();
        },
        toggleSetting: function (settingName) {
	        var name = 'auto' + settingName;
            if (typeof _BotSettings[name] === 'boolean') {
                _BotSettings[name] = !_BotSettings[name];
                _BotUI.initSettingsPage();
                _BotSettings.store(name, _BotSettings[name]);
            }
            return false;
        },
        store: function(name, value) {
            if (typeof(Storage) !== "undefined") localStorage.setItem(name, value);
        },
        restore: function(name, asBool) {
            if (typeof asBool === 'undefined') asBool = false;
            if (typeof(Storage) !== "undefined") {
                var aValue = localStorage.getItem(name);
                if (asBool && aValue !== null) {
                    return (aValue === 'true' || aValue === true);
                } else {
                    return aValue;
                }
            }
            else return null;
        },
        restoreAll: function () {
            for (var x in _BotSettings) {
                if (_BotSettings.hasOwnProperty(x)) {
                    if (x.indexOf("auto") === 0) {
                        var oldValue = _BotSettings.restore(x, true);
                        if (oldValue !== null) {
                            _BotSettings[x] = oldValue;
                        }
                    }
                }
            }
        }
    };

	var _Helpers = {
	    _log2: [],
	    isGameReady: function() {
            return $("#game").css('display') === 'block';
        },
        log: function(message) {
            var mes = 'BOT: ' + message;
            if (game && game.msg && game.ui) {
                game.msg(mes, 'msg');
                game.ui.renderConsoleLog();
            }
        },
        log2: function(messsage) {
	        if (_Helpers._log2.length >= 100) {
                _Helpers._log2.shift();
            }
	        _Helpers._log2.push(messsage);

	        if (_BotUI.currentPage === 'log2') {
	            _BotUI.initLog2Page();
            }
        },
        isResourceUnlocked: function(res) {
            return game.resPool.get(res).unlocked;
        },
        getBotVersion: function () {
            return typeof GM_info == 'function' ? GM_info().script.version :
                (typeof GM_info == 'object' ? GM_info.script.version : '?');
        },
        getMinCraft: function(res) {
            // craft no more than 2% of possible craft
            var allCount = game.workshop.getCraftAllCount(res);
            var ratioCount = Math.floor(allCount*0.02);
            return ratioCount < 1 ? 1 : ratioCount;
        },
        canBuyBuilding: function(bldName) {
            var prices = game.bld.getPrices(bldName);
            for (var x in prices) {
                if (prices.hasOwnProperty(x)) {
                    if (prices[x].val > game.resPool.get(prices[x].name).value) {
                        return false;
                    }
                }
            }
            return true;
        },
        getCountKittensForPromote: function() {
            var x=0;
            for (var i = 0; i < game.village.sim.kittens.length; i++) {
                var done = false;
                if(game.village.sim.kittens[i].engineerSpeciality !== null) {
                    var kitten = game.workshop.getCraft(game.village.sim.kittens[i].engineerSpeciality);
                    if (kitten) {
                        var tier = kitten.tier;
                        if (game.village.sim.kittens[i].rank < tier) {
                            x++;
                            done = true;
                        }
                    }
                }
                if (!done) {
                    x++;
                }
            }
            return x;
        },
        getZebraTitanium: function () {
	        if (game.diplomacy.get('zebras').unlocked) {
                var shipVal = game.resPool.get("ship").value;
                var shipRate = shipVal * 0.35; //0.35% per ship to get titanium
                var titaniumAmt = 1.5;
                titaniumAmt += titaniumAmt * (shipVal / 100) * 2;	//2% more titanium per ship
                return {percent: shipRate + 15, value: titaniumAmt};
            }
	        return {percent: 0, value: 0};
        },
        clone: function (obj) {
            var copy;

            // Handle the 3 simple types, and null or undefined
            if (null == obj || "object" != typeof obj) return obj;

            // Handle Date
            if (obj instanceof Date) {
                copy = new Date();
                copy.setTime(obj.getTime());
                return copy;
            }

            // Handle Array
            if (obj instanceof Array) {
                copy = [];
                for (var i = 0, len = obj.length; i < len; i++) {
                    copy[i] = _Helpers.clone(obj[i]);
                }
                return copy;
            }

            // Handle Object
            if (obj instanceof Object) {
                copy = {};
                for (var attr in obj) {
                    if (obj.hasOwnProperty(attr)) copy[attr] = _Helpers.clone(obj[attr]);
                }
                return copy;
            }

            throw new Error("Unable to copy obj! Its type isn't supported.");
        }
	};

	var _BotActions = {
        craftAll: function(res) {
            if (_Helpers.isResourceUnlocked(res)) {
                _Helpers.log2("Crafting " + res);
                game.craftAll(res);
            }
        },
        collectAstronomy: function() {
            if (game.calendar.observeRemainingTime > 0) {
                if (typeof game.calendar.observeHandler === 'function') {
                    game.calendar.observeHandler();
                }
            }
        },
        catnipToWood: function() {
            var catnip = game.resPool.get("catnip");
            if (catnip.value >= catnip.maxValue) {
                var minWood = _Helpers.getMinCraft('wood');
                var wood = game.resPool.get("wood");
                if (wood.value + minWood <= wood.maxValue) {
                    _Helpers.log2('Catnip to Wood x ' + minWood);
                    game.craft('wood', minWood);
                }
            }
        },
        collectFaith: function() {
            var faith = game.resPool.get("faith");
            if (faith.value >= faith.maxValue) {
                _Helpers.log2('Praise');
                game.religion.praise();
            }
        },
        sendAllHunters: function() {
            var manpower = game.resPool.get("manpower");
            if (manpower.value >= manpower.maxValue) {
                _Helpers.log2('Sending hunters');
                game.village.huntAll();
                _BotActions.craftAll('parchment');
            }
        },
        ironToSteel: function() {
            if (_Helpers.isResourceUnlocked('steel')) {
                var iron = game.resPool.get("iron");
                var coal = game.resPool.get("coal");
                if (iron.value >= iron.maxValue || coal.value >= coal.maxValue) {
                    if (coal.value >= 100 && iron.value >= 100) {
                        _Helpers.log2('Iron to Steel x ALL');
                        game.craftAll('steel');
                    }
                }
            }
        },
        ironToPlates: function() {
            var iron = game.resPool.get("iron");
            var minPlate = _Helpers.getMinCraft('plate');
            if (iron.value >= (125 * minPlate) && _Helpers.isResourceUnlocked('plate')) {
                _Helpers.log2('Iron to Plate x ' + minPlate);
                game.craft('plate', minPlate);
            }
        },
        woodToBeams: function() {
            var wood = game.resPool.get("wood");
            if (wood.value >= wood.maxValue && _Helpers.isResourceUnlocked('beam')) {
                var minVal = _Helpers.getMinCraft('beam');
                _Helpers.log2('Wood to Beam x ' + minVal);
                game.craft('beam', minVal);
            }
        },
        mineralsToSlabs: function() {
            var minerals = game.resPool.get("minerals");
            if (minerals.value >= minerals.maxValue && _Helpers.isResourceUnlocked('slab')) {
                var minVal = _Helpers.getMinCraft('slab');
                _Helpers.log2('Minerals to Slab x ' + minVal);
                game.craft('slab', minVal);
            }
        },
        cultureToManuscript: function() {
            var culture = game.resPool.get("culture");
            var parchment = game.resPool.get("parchment");
            var minVal = _Helpers.getMinCraft('manuscript');
            if (culture.value >= culture.maxValue && _Helpers.isResourceUnlocked('manuscript') && culture.value >= (400 * minVal) && parchment.value >= (25 * minVal)) {
                _Helpers.log2('Culture to Manuscript x ' + minVal);
                game.craft('manuscript', minVal);
            }
        },
        makeABuy: function(itemName) {
            var btn = $('.bldGroupContainer').find('div.btnContent').find('span').filter(function(){
                var t = $(this).text();
                return t.indexOf(itemName + " (") === 0 || t === itemName;
            });
            if (btn&& btn.length === 1) {
                _Helpers.log('Autobuy ' + itemName);
                _Helpers.log2('Autobuy ' + itemName);
                btn.click();
            }
        },
        promoteKittens: function() {
            var gold = game.resPool.get("gold");
            if (!gold.unlocked) return;
            if (gold.value >= 15 && gold.value >= gold.maxValue && _Helpers.getCountKittensForPromote() > 0) {
                game.village.promoteKittens();
            }
        },
        scienceToCompendium: function() {
            var science = game.resPool.get("science");
            var manuscript = game.resPool.get("manuscript");
            var minVal = _Helpers.getMinCraft('compedium');
            if (science.value >= science.maxValue && _Helpers.isResourceUnlocked('compedium') && manuscript.value >= (50 * minVal) && science.value >= (10000 * minVal)) {
                _Helpers.log2('Science + Manuscript to Compendium x ' + minVal);
                game.craft('compedium', minVal);
            }
        }
	};

	// noinspection JSUnusedGlobalSymbols
    var _BotUI = {
        currentPage: 'log',
        cy: undefined,
        fixFontSize: function() {
            var $midColumn = $('#midColumn');
            var $rightColumn = $('#rightColumn');
            var fnt1 = $('#leftColumn').css('font-size');
            var fnt2 = $midColumn.css('font-size');
            var fnt3 = $rightColumn.css('font-size');
            if (fnt2 !== fnt1 || fnt3 !== fnt1) {
                _Helpers.log('Fixing font size');
                $midColumn.css('font-size', fnt1);
                $rightColumn.css('font-size', fnt1);
            }
        },
        fixStyles: function() {
            var style = '<style type="text/css">' +
                '.modern .btnContent, .btn.bldEnabled.modern div.btnContent, .btn.bldlackResConvert.modern div.btnContent {padding: 5px 0 5px 10px;} '+
                '.btn.modern a {padding: 5px 6px 5px 6px !important;margin:-5px 0;} '+
                '#rightTabLog {max-height: 75vh; overflow-y: scroll; padding-right: 4px;} ' +
                '#IRCChatInner {overflow-y: scroll; height: 75vh;} ' +
                '.msg {opacity: 1 !important;} ' +
                '.right-tab-header a {padding: 0} ' +
                '#scienceTree {z-index:2;position:fixed;left:2vw;top:2vh;width:96vw;height:96vh;background:azure;border:1px solid;} ' +
                '#closeScienceTree {z-index:3;position:fixed;right:2vw;top:2vh;color:black;font-size:20px;padding:4px;border:1px solid;text-decoration:none;} ' +
                '#closeScienceTree:hover {color:blue} ' +
                '</style>';
            $('body').append($(style));
        },
        addBotButton: function () {
            var $a = $('<a href="#" id="botbutton">Bot (' + (_BotLogic.isAutoLogicStarted ? 'on' : 'off') + ')</a>');
            $a.on("click", function() {
                _BotLogic.isAutoLogicStarted = !_BotLogic.isAutoLogicStarted;
                _Helpers.log((_BotLogic.isAutoLogicStarted ? 'Started' : 'Stopped') + ' version ' + _Helpers.getBotVersion());
                $('#botbutton').text(_BotLogic.isAutoLogicStarted ? 'Bot (on)' : 'Bot (off)');
            });
            $('#headerLinks .links-block').append(' | ').append($a);
        },
        initSettingsLink: function () {
            $('a.chatLink').text('Bot settings').attr('onclick', 'KittenTools.UI.onSettingsButtonClick()');
        },
        initSettingsPage: function () {
            var inner = '';

            for (var x in _BotSettings) {
                if (_BotSettings.hasOwnProperty(x)) {
                    if (x.indexOf("auto") === 0) {
                        var name = x.substr(4);
                        var isChecked = _BotSettings[x];
                        inner += '<a href="#" onclick="KittenTools.Settings.toggleSetting(\'' + name + '\')">'
                            + name + '</a> ' + (isChecked ? 'ON' : 'OFF') + '<br/>';
                    }
                }
            }

            $("#IRCChatInner").html(inner);
        },
        initInfoPage: function() {
            var inner = '', br = "<br/>";

            var zebraTitanium = _Helpers.getZebraTitanium();
            inner += 'Zebras trade:' + br;
            inner += '- Titan chance: ' + parseFloat(zebraTitanium.percent).toFixed(2) + '%' + br;
            inner += '- Titan amount: ' + parseFloat(zebraTitanium.value).toFixed(2) + br;

            $("#IRCChatInner").html(inner);
        },
        initInfoButton: function () {
            $('.right-tab-header').append('&nbsp;| <a href="#" onclick="KittenTools.UI.onInfoButtonClick()">Info</a>');
        },
        initLog2Button: function () {
            $('.right-tab-header').append('&nbsp;| <a href="#" onclick="KittenTools.UI.onLog2ButtonClick()">Log2</a>');
        },
        initLog2Page: function() {
            var inner = '', br = "<br/>";

            inner += '<a href="#" onclick="KittenTools.UI.onClearLog2Click()">Clear log</a><hr/>';

            for (var i = (_Helpers._log2.length - 1); i >= 0; i--) {
                if (_Helpers._log2.hasOwnProperty(i)) {
                    inner += _Helpers._log2[i] + br;
                }
            }

            $("#IRCChatInner").html(inner);
        },
        initCy: function() {
            var el = document.getElementById('scienceTree');
            if (typeof _BotUI.cy === 'undefined' && typeof cytoscape !== 'undefined' && el !== null) {
                var elems = [];

                //var techs = _Helpers.clone(game.science.techs);
                //var dx = 0;
                //var dy = 0;
                var _addNode = function (name, connectTo) {
                    var t = game.science.get(name);
                    if (!t) return;
                    elems.push({data:{id:t.name}});
                    if (typeof connectTo !== 'undefined') {
                        var linkName = t.name + '_' + connectTo;
                        elems.push({data:{id:linkName,source:connectTo,target:t.name}});
                    }
                    if (typeof t.unlocks !== 'undefined' && typeof t.unlocks.tech === 'object') {
                        for (var x in t.unlocks.tech) {
                            if (t.unlocks.tech.hasOwnProperty(x)) {
                                _addNode(t.unlocks.tech[x], name);
                            }
                        }
                    }
                };
                _addNode('calendar');

                _BotUI.cy = cytoscape({
                    container: el, // container to render in
                    zoom: 1,
                    elements: elems
                });
            }
        },
        init: function () {
            _BotUI.fixStyles();
            _BotUI.addBotButton();
            _BotUI.initInfoButton();
            _BotUI.initLog2Button();
            _BotUI.initScienceTree();
        },
        initScienceTree: function() {
            var closeDivButton = '<a href="#" id="closeScienceTree" onclick="KittenTools.UI.onCloseScienceTreeClick()">X</a>';
            var scienceDiv = '<div id="scienceTree" style="display:none">' + closeDivButton + '</div>';
            $('#gamePageContainer').prepend(scienceDiv);

            //_BotUI.initCy();
        },
        onCloseScienceTreeClick: function() {
            $('#scienceTree').hide();
        },
        onInfoButtonClick: function () {
            _BotUI.currentPage = 'info';
            game.ui.loadChat();
            _BotUI.initInfoPage();
        },
        onSettingsButtonClick: function () {
            _BotUI.currentPage = 'settings';
            game.ui.loadChat();
            _BotUI.initSettingsPage();
        },
        onLog2ButtonClick: function () {
            _BotUI.currentPage = 'log2';
            game.ui.loadChat();
            _BotUI.initLog2Page();
        },
        initLogLink: function () {
            $('a.chatLink').attr('onclick', 'KittenTools.UI.onLogButtonClick()');
        },
        onLogButtonClick: function () {
            _BotUI.currentPage = 'log';
            game.ui.hideChat();
        },
        onClearLog2Click: function () {
            _Helpers._log2 = [];
            _BotUI.initLog2Page();
        }
    };

	var _BotLogic = {
        tAutoLogic: undefined,
        isAutoLogicStarted: true,
        autoBuyItem: function(bldName) {
            var bld = game.bld.get(bldName);
            if (bld.unlocked && _Helpers.canBuyBuilding(bldName)) {
                var itemName = bld.stages && bld.stages.length > 0 ? bld.stages[bld.stage].label : bld.label;
                _BotActions.makeABuy(itemName);
            }
        },
        autoBuyAll: function() {
            if (!_BotSettings.autoBuy) return;

            _BotLogic.autoBuyItem('field');
            _BotLogic.autoBuyItem('pasture');
            _BotLogic.autoBuyItem('unicornPasture');
            _BotLogic.autoBuyItem('hut');
            _BotLogic.autoBuyItem('logHouse');
            _BotLogic.autoBuyItem('workshop');
            _BotLogic.autoBuyItem('aqueduct');
            _BotLogic.autoBuyItem('library');
            _BotLogic.autoBuyItem('academy');
            _BotLogic.autoBuyItem('barn');
            _BotLogic.autoBuyItem('mine');
            _BotLogic.autoBuyItem('lumberMill');
            _BotLogic.autoBuyItem('temple');
            _BotLogic.autoBuyItem('tradepost');
            _BotLogic.autoBuyItem('warehouse');
            _BotLogic.autoBuyItem('chapel');
            _BotLogic.autoBuyItem('amphitheatre');
            _BotLogic.autoBuyItem('smelter');
        },
        autoClick: function() {
            var field = game.bld.get('field');
            if (field.on < 5) {
                var btn = $('.bldGroupContainer').find('div.btnContent').find('span').filter(function(){
                    return $(this).text().indexOf("Gather catnip") === 0;
                });
                if (btn && btn.length) btn.click();
            }
        },
        autoLogic: function() {
            _BotUI.fixFontSize();

            _BotActions.collectAstronomy();
            if (!_BotLogic.isAutoLogicStarted) return;
            _BotLogic.autoClick();
            _BotLogic.autoBuyAll();
            _BotLogic.promoteKittens();
            _BotLogic.collectFaith();
            _BotLogic.ironToSteelOrPlates();
            _BotLogic.sendAllHunters();
            _BotLogic.cultureToManuscript();
            _BotLogic.catnipToWood();
            _BotLogic.woodToBeams();
            _BotLogic.mineralsToSlabs();
            _BotLogic.scienceToCompendium();
        },
        promoteKittens: function () {
            if (_BotSettings.autoPromoteKittens) _BotActions.promoteKittens();
        },
        collectFaith: function () {
            if (_BotSettings.autoCollectFaith) _BotActions.collectFaith();
        },
        ironToSteelOrPlates: function() {
            var iron = game.resPool.get("iron");
            var coal = game.resPool.get("coal");
            if (iron.value >= iron.maxValue || coal.value >= coal.maxValue) {
                var minPlate = _Helpers.getMinCraft('plate');
                if (coal.value >= 100 && iron.value >= 100 && _Helpers.isResourceUnlocked('steel')) {
                    _BotLogic.ironToSteel();
                } else if (iron.value >= (125 * minPlate) && _Helpers.isResourceUnlocked('plate')) {
                    _BotLogic.ironToPlates();
                }
            }
        },
        ironToSteel: function () {
            if (_BotSettings.autoCreateSteel) _BotActions.ironToSteel();
        },
        ironToPlates: function () {
            if (_BotSettings.autoCreatePlates) _BotActions.ironToPlates();
        },
        sendAllHunters: function () {
            if (_BotSettings.autoSendHunters) _BotActions.sendAllHunters();
        },
        cultureToManuscript: function () {
            if (_BotSettings.autoCreateManuscript) _BotActions.cultureToManuscript();
        },
        catnipToWood: function () {
            if (_BotSettings.autoCreateWood) _BotActions.catnipToWood();
        },
        woodToBeams: function () {
            if (_BotSettings.autoCreateBeams) _BotActions.woodToBeams();
        },
        mineralsToSlabs: function () {
            if (_BotSettings.autoCreateSlabs) _BotActions.mineralsToSlabs();
        },
        scienceToCompendium: function () {
            if (_BotSettings.autoCreateCompendium) _BotActions.scienceToCompendium();
        }
	};

    var KittenTools = {
        Helpers: _Helpers,
        Actions: _BotActions,
        UI: _BotUI,
        Settings: _BotSettings,
        Logic: _BotLogic
    };

    var _starter = function() {
        _BotLogic.tAutoLogic = setInterval(_BotLogic.autoLogic, 1000);
        _BotUI.init();
        _BotSettings.init();
        _Helpers.log('Started version ' + _Helpers.getBotVersion());

        if (typeof game.KittenTools === 'undefined') {
            game.KittenTools = KittenTools;
        }
        if (typeof unsafeWindow !== 'undefined') {
            unsafeWindow.KittenTools = KittenTools;
            unsafeWindow.cytoscape = cytoscape;
        }
    };

    var _waiter = function() {
        if (_Helpers.isGameReady()) {
            _starter();
        } else {
            setTimeout(_waiter, 1000);
        }
    };

    _waiter();
})();