Greasy Fork

Greasy Fork is available in English.

Kittens tools

Kittens tools (visual)

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

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Kittens tools
// @namespace    http://bloodrizer.ru/games/kittens/
// @version      1.087
// @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;
                    var nodeData = {data:{id:t.name}};
                    /*if (typeof connectTo !== 'undefined') {
                        nodeData.data.parent = connectTo;
                    }*/
                    elems.push(nodeData);
                    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,
                    wheelSensitivity: 0.5,
                    elements: elems,
                    style: [
                        {
                            selector: 'node',
                            style: {
                                'label': 'data(id)'
                            }
                        }
                    ]
                });
            }
        },
        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();
})();