// ==UserScript== // @name Kittens tools // @namespace http://bloodrizer.ru/games/kittens/ // @version 1.188 // @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 // @downloadURL none // ==/UserScript== (function() { 'use strict'; var $ = jQuery; var _Helpers = { _logs: { log2: [], hunt: [], wrkshp: [], trade: [], build: [] }, getCurrentDateTime: function() { var d = new Date(); var getPaddedComp = function(comp) { return ((parseInt(comp) < 10) ? ('0' + comp) : comp) }; var date = getPaddedComp(d.getDate()) + '.' + getPaddedComp(d.getMonth()+1) + '.' + d.getFullYear(); var time = getPaddedComp(d.getHours()) + ':' + getPaddedComp(d.getMinutes()); return (date + " " + time); }, isGameReady: function() { return $('#game').css('display') === 'block'; }, console: function(message) { if (console) console.log(message); }, log: function(message) { var mes = 'BOT: ' + message; if (game && game.msg && game.ui) { game.msg(mes, 'msg'); game.ui.renderConsoleLog(); } }, logCustom: function(logName, message, withDateTime) { while (_Helpers._logs[logName].length >= 100) { _Helpers._logs[logName].shift(); } if (withDateTime === true) { message = '[' + _Helpers.getCurrentDateTime() + '] ' + message; } _Helpers._logs[logName].push(message); if (_BotUI.currentPage === logName) { _BotUI.initCustomLogPage(logName); } }, log2: function(message) { _Helpers.logCustom('log2', message); }, buildLog: function(message) { _Helpers.logCustom('build', message, true); }, isResourceUnlocked: function(res) { var r = game.resPool.get(res); if (r.unlocked || (r.visible && r.craftable && !r.isHidden)) { return true; } else { var workshop = game.workshop.crafts; for (var i in workshop) { if (workshop.hasOwnProperty(i)) { if (workshop[i].name === res && workshop[i].unlocked) { return true; } } } } return false; }, 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; }, getPricesForModel: function(model, isReligion) { var ratio = model.priceRatio || 1; if (isReligion) { var prices = game.village.getEffectLeader("wise", model.prices); } else { prices = _Helpers.clone(model.prices); } for (var i = 0; i< prices.length; i++){ prices[i].val = prices[i].val * Math.pow(ratio, model.val); } return prices; }, canBuyModel: function(model, isReligion) { var prices = _Helpers.getPricesForModel(model, isReligion); return _Helpers.isEnoughResourcesForPrice(prices); }, canBuyBuilding: function(bldName) { var prices = game.bld.getPrices(bldName); return _Helpers.isEnoughResourcesForPrice(prices); }, isEnoughResourcesForPrice: function(prices) { for (var x in prices) { if (prices.hasOwnProperty(x)) { var resName = prices[x].name; if (prices[x].val > game.resPool.get(resName).value) { return false; } if (resName === 'catnip') { if (!_Helpers.canSpendMint(prices[x].val)) { return false; } } if (_BotSettings.isCheckedResSetting(resName)) { return false; } } } return true; }, getPromoteInfo: function(kitten, rank, doNotCheckGold) { if (doNotCheckGold) { var currentGold = parseFloat('+Infinity') } else { currentGold = game.resPool.get('gold').value; } var sim = game.village.sim; var kittenRank = kitten.rank; if (typeof(rank) == 'undefined') { rank = kitten.rank + 1; } var rankDiff = rank - kittenRank; var expToPromote = 0; var goldToPromote = 0; if (rankDiff > 0) { expToPromote = sim.expToPromote(kittenRank, rank, kitten.exp); goldToPromote = sim.goldToPromote(kittenRank, rank, currentGold); } return { rankDiff: rankDiff, exp: expToPromote, gold: goldToPromote }; }, canPromoteKitten: function(kitten, rank, doNotCheckGold) { var promoteInfo = _Helpers.getPromoteInfo(kitten, rank, doNotCheckGold); var canPromote = false; if (promoteInfo.rankDiff > 0) { if (promoteInfo.exp[0] && (promoteInfo.gold[0] || doNotCheckGold === true)) { canPromote = true; } else if (promoteInfo.rankDiff > 1) { // If rank is unreachable, try one rank return _Helpers.canPromoteKitten(kitten, undefined, doNotCheckGold); } } return { promoteInfo: promoteInfo, canPromote: canPromote }; }, getKittensForPromoteInfo: function(doNotCheckGold) { var promotedKittens = []; for (var i = 0; i < game.village.sim.kittens.length; i++) { var done = false; if(game.village.sim.kittens[i].engineerSpeciality != null) { var tier = game.workshop.getCraft(game.village.sim.kittens[i].engineerSpeciality).tier; if (game.village.sim.kittens[i].rank < tier) { promotedKittens.push({'kitten': game.village.sim.kittens[i], 'rank': tier}); done = true; } } if (!done) { promotedKittens.push({'kitten': game.village.sim.kittens[i]}); } } var promotedKittensCount = 0; var totalGoldNeeded = 0; if(promotedKittens.length) { for (i = 0; i < promotedKittens.length; i++) { if (typeof(promotedKittens[i].rank) == 'number') { var promoteInfo = _Helpers.canPromoteKitten(promotedKittens[i].kitten, promotedKittens[i].rank, doNotCheckGold); promotedKittensCount += promoteInfo.canPromote ? 1 : 0; totalGoldNeeded += promoteInfo.canPromote ? promoteInfo.promoteInfo.gold[1] : 0; } else { promoteInfo = _Helpers.canPromoteKitten(promotedKittens[i].kitten, undefined, doNotCheckGold); promotedKittensCount += promoteInfo.canPromote ? 1 : 0; totalGoldNeeded += promoteInfo.canPromote ? promoteInfo.promoteInfo.gold[1] : 0; } } } return { count: promotedKittensCount, gold: totalGoldNeeded }; }, 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.'); }, getGameStandingRatio: function () { var standingRatio = game.getEffect('standingRatio'); standingRatio = standingRatio ? standingRatio : 0; if (game.prestige.getPerk('diplomacy').researched){ standingRatio += 10; } return standingRatio; }, getBuildingTitle: function (building_type) { var bld = game.bld.get(building_type); return bld.stages && bld.stages.length > 0 ? bld.stages[bld.stage].label : bld.label; }, canSpendMint: function (mintAmount) { var calendar = game.calendar, winterDays = calendar.daysPerSeason - (calendar.getCurSeason().name === 'winter' ? calendar.day : 0); var catnipPerTick = game.calcResourcePerTick('catnip', { modifiers:{ 'catnip' : 0.25 }}); //calculate estimate winter per tick for catnip; return (game.resPool.get('catnip').value - mintAmount + (winterDays * catnipPerTick / calendar.dayPerTick)) > 0; }, getMagnetoBonus: function (addSteamwork, addMagneto) { if (typeof addSteamwork === 'undefined') addSteamwork = 0; if (typeof addMagneto === 'undefined') addMagneto = 0; var steamworks = game.bld.get('steamworks'); var steamworksOn = steamworks.on + addSteamwork; var magnetoOn = game.bld.get('magneto').effects.magnetoRatio * addMagneto; var swRatio = steamworksOn > 0 ? (1+ steamworks.effects['magnetoBoostRatio'] * steamworksOn) : 1; return (game.getEffect('magnetoRatio') + magnetoOn) * swRatio; }, getBuildingPrice: function (building_type) { return game.bld.getPrices(building_type); }, isBuildingUnlocked: function(building_type) { return game.bld.isUnlocked(game.bld.get(building_type)); }, canBuildNow: function (building_type) { if (_Helpers.isBuildingUnlocked(building_type)) { var prices = _Helpers.getBuildingPrice(building_type); for (var i in prices) { if (prices.hasOwnProperty(i)) { var resName = prices[i].name; var resVal = prices[i].val; var res = game.resPool.get(resName); if (!res.unlocked) return false; if (res.maxValue > 0 && res.maxValue < resVal) return false; } } return true; } return false; }, getMaximumCompediumsToKeep: function () { var maxCompediums = 0; for (var i in game.science.techs) { if (game.science.techs.hasOwnProperty(i)) { var tech = game.science.techs[i]; if (tech.unlocked && !tech.researched) { var prices = tech.prices; for (var p in prices) { if (prices.hasOwnProperty(p)) { if (prices[p].name === 'compedium') { if (prices[p].val > maxCompediums) { maxCompediums = prices[p].val; } } } } } } } return maxCompediums; } }; var _BotSetting = { auto: { Buy: false, PromoteKittens: true, CollectFaith: true, CreateSteel: true, CreatePlates: true, SendHunters: true, CreateManuscript: true, CreateWood: true, CreateBeams: true, CreateSlabs: true, CreateCompedium: true, CreateBlueprints: true, Trade: false, CreateKerosene: true, CreateThorium: true, CreateEludium: true }, buys: {}, keeps: {} }; var zeroSetting = _Helpers.clone(_BotSetting); // noinspection JSUnusedGlobalSymbols var _BotSettingsMigrator = { currentVersion: 5, migrate1to2: function() { for (var i in _BotSettings.settings) { if (_BotSettings.settings.hasOwnProperty(i)) { if (typeof _BotSettings.settings[i].auto.CreateBlueprints === 'undefined') { _BotSettings.settings[i].auto.CreateBlueprints = true; } if (typeof _BotSettings.settings[i].auto.CreateCompedium === 'undefined') { if (typeof _BotSettings.settings[i].auto['CreateCompendium'] !== 'undefined') { _BotSettings.settings[i].auto.CreateCompedium = _BotSettings.settings[i].auto['CreateCompendium']; delete _BotSettings.settings[i].auto['CreateCompendium']; } else { _BotSettings.settings[i].auto.CreateCompedium = true; } } } } _BotSettings.version = 2; _BotSettings.storeSetting(); }, migrate2to3: function() { for (var i in _BotSettings.settings) { if (_BotSettings.settings.hasOwnProperty(i)) { if (typeof _BotSettings.settings[i].auto.CreateKerosene === 'undefined') { _BotSettings.settings[i].auto.CreateKerosene = true; } } } _BotSettings.version = 3; _BotSettings.storeSetting(); }, migrate3to4: function() { for (var i in _BotSettings.settings) { if (_BotSettings.settings.hasOwnProperty(i)) { if (typeof _BotSettings.settings[i].auto.CreateThorium === 'undefined') { _BotSettings.settings[i].auto.CreateThorium = true; } } } _BotSettings.version = 4; _BotSettings.storeSetting(); }, migrate4to5: function() { for (var i in _BotSettings.settings) { if (_BotSettings.settings.hasOwnProperty(i)) { if (typeof _BotSettings.settings[i].auto.CreateEludium === 'undefined') { _BotSettings.settings[i].auto.CreateEludium = true; } } } _BotSettings.version = 5; _BotSettings.storeSetting(); }, migrateAll: function () { for (var i = 1; i < _BotSettingsMigrator.currentVersion; i++) { if (_BotSettings.version === i) { _BotSettings['migrate' + i + 'to' + (i + 1)](); _Helpers.console('Migrated from ' + i + ' to ' + (i + 1)); } } } }; var _BotSettings = { version: _BotSettingsMigrator.currentVersion, settingIdx: 0, settings: [zeroSetting], init: function () { for (var i = 1; i < 5; i++) { var newZeroSetting = _Helpers.clone(_BotSetting); _BotSettings.settings.push(newZeroSetting); } _BotUI.initSettingsLink(); _BotUI.initSettingsPage(); _BotSettings.restoreAll(); }, toggleSetting: function (settingName) { var currentSettingAuto = _BotSettings.settings[_BotSettings.settingIdx].auto; if (typeof currentSettingAuto[settingName] === 'boolean') { currentSettingAuto[settingName] = !currentSettingAuto[settingName]; _BotUI.initSettingsPage(); _BotSettings.storeSetting(); } return false; }, toggleBuySetting: function (name) { var currentSettingBuys = _BotSettings.settings[_BotSettings.settingIdx].buys; if (typeof currentSettingBuys[name] === 'boolean') { currentSettingBuys[name] = !currentSettingBuys[name]; _BotUI.initSettingsPage(); _BotSettings.storeSetting(); } else { currentSettingBuys[name] = true; _BotUI.initSettingsPage(); _BotSettings.storeSetting(); } return false; }, toggleResSetting: function (name) { var currentSettingKeeps = _BotSettings.settings[_BotSettings.settingIdx].keeps; if (typeof currentSettingKeeps[name] === 'boolean') { currentSettingKeeps[name] = !currentSettingKeeps[name]; _BotUI.initSettingsPage(); _BotSettings.storeSetting(); } else { currentSettingKeeps[name] = true; _BotUI.initSettingsPage(); _BotSettings.storeSetting(); } return false; }, restoreBuySettingOld: function() { var data = _BotSettings.restore('buy', false); var currentSetting = _BotSettings.settings[_BotSettings.settingIdx]; if (typeof data === 'string') { currentSetting.buys = JSON.parse(data); } else { currentSetting.buys = {}; } }, restoreResSettingOld: function() { var data = _BotSettings.restore('keeps', false); var currentSetting = _BotSettings.settings[_BotSettings.settingIdx]; if (typeof data === 'string') { currentSetting.keeps = JSON.parse(data); } else { currentSetting.keeps = {}; } }, 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; }, restoreAllNew: function() { var data = _BotSettings.restore('settings', data); if (data) { _BotSettings.settings = JSON.parse(data); } var settingIdx = _BotSettings.restore('settingsIdx'); if (settingIdx) { _BotSettings.settingIdx = parseInt(settingIdx); } var version = _BotSettings.restore('version'); if (version) { _BotSettings.version = parseInt(version); } _BotSettingsMigrator.migrateAll(); }, storeSetting: function() { var data = JSON.stringify(_BotSettings.settings); _BotSettings.store('settings', data); _BotSettings.store('settingsIdx', _BotSettings.settingIdx); _BotSettings.store('version', _BotSettings.version); }, restoreAllOld: function() { var autos = _BotSetting.auto; var currentSetting = _BotSettings.settings[_BotSettings.settingIdx]; for (var x in autos) { if (autos.hasOwnProperty(x)) { var oldValue = _BotSettings.restore('auto' + x, true); if (oldValue !== null) { currentSetting.auto[x] = oldValue; } } } _BotSettings.restoreBuySettingOld(); _BotSettings.restoreResSettingOld(); }, removeOldSettings: function() { if (typeof(Storage) === 'undefined') return; var autos = _BotSetting.auto; for (var x in autos) { if (autos.hasOwnProperty(x)) { localStorage.removeItem('auto' + x); } } localStorage.removeItem('buys'); localStorage.removeItem('keeps'); }, restoreAll: function () { if (_BotSettings.restore('version') === null) { _BotSettings.restoreAllOld(); _BotSettings.removeOldSettings(); _BotSettings.storeSetting() } else { _BotSettings.restoreAllNew(); } }, isCheckedBuySetting: function (bld) { var currentSettingBuys = _BotSettings.settings[_BotSettings.settingIdx].buys; if (typeof currentSettingBuys[bld] !== 'undefined') { return currentSettingBuys[bld] === true; } return false; }, isCheckedResSetting: function (res) { var currentSettingKeeps = _BotSettings.settings[_BotSettings.settingIdx].keeps; if (typeof currentSettingKeeps[res] !== 'undefined') { return currentSettingKeeps[res] === true; } return false; }, isAuto: function (autoSetting) { var currentSetting = _BotSettings.settings[_BotSettings.settingIdx]; var r = currentSetting.auto[autoSetting]; return typeof r !== 'undefined' && r; } }; 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); } }, oilToKerosene: function() { var oil = game.resPool.get('oil'); if (oil.value >= oil.maxValue && _Helpers.isResourceUnlocked('kerosene')) { var minVal = _Helpers.getMinCraft('kerosene'); _Helpers.log2('Oil to Kerosene x ' + minVal); game.craft('kerosene', minVal); } }, uraniumToThorium: function() { var uranium = game.resPool.get('uranium'); if (uranium.value >= uranium.maxValue && _Helpers.isResourceUnlocked('thorium')) { var minVal = _Helpers.getMinCraft('thorium'); _Helpers.log2('Uranium to Thorium x ' + minVal); game.craft('thorium', 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.buildLog(itemName); btn.click(); } }, promoteKittens: function() { var gold = game.resPool.get('gold'); if (!gold.unlocked) return; if (gold.value >= 15 && gold.value >= gold.maxValue && _Helpers.getKittensForPromoteInfo().count > 0) { game.village.promoteKittens(); } }, scienceToCompedium: 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 Compedium x ' + minVal); game.craft('compedium', minVal); } }, scienceToBlueprints: function() { var science = game.resPool.get('science'); var compediums = game.resPool.get('compedium'); var minVal = _Helpers.getMinCraft('blueprint'); if (science.value >= science.maxValue && _Helpers.isResourceUnlocked('blueprint') && compediums.value >= (25 * minVal) && science.value >= (25000 * minVal)) { _Helpers.log2('Science/Compedium to Blueprint x ' + minVal); game.craft('blueprint', minVal); } }, sendZebraCaravan: function () { var zebras = game.diplomacy.get('zebras'); if (zebras.unlocked) { var titanium = game.resPool.get('titanium'); if (titanium.value < titanium.maxValue) { var gold = game.resPool.get('gold'); var power = game.resPool.get('manpower'); var slab = game.resPool.get('slab'); if (gold.value >= gold.maxValue && power.value >= 50 && slab.value >= 50) { _Helpers.log2('Zebra trade x 1'); game.diplomacy.tradeMultiple(zebras, 1); } } } }, sendNagasCaravan: function () { var nagas = game.diplomacy.get('nagas'); if (nagas.unlocked) { var ivory = game.resPool.get('ivory'); var gold = game.resPool.get('gold'); if (ivory.value > 500 && ivory.perTickCached > 0 && gold.value >= gold.maxValue) { var minerals = game.resPool.get('minerals'); var power = game.resPool.get('manpower'); if (minerals.value < minerals.maxValue && power.value >= 50) { _Helpers.log2('Nagas trade x 1'); game.diplomacy.tradeMultiple(nagas, 1); } } } }, sendDragonsCaravan: function () { var dragons = game.diplomacy.get('dragons'); if (dragons.unlocked) { var uranium = game.resPool.get('uranium'); if (uranium.unlocked && uranium.value < uranium.maxValue) { var titanium = game.resPool.get('titanium'); var gold = game.resPool.get('gold'); var power = game.resPool.get('manpower'); if (titanium.value >= titanium.maxValue && titanium.value >= 250 && gold.value >= gold.maxValue && power.value >= 50) { _Helpers.log2('Dragons trade x 1'); game.diplomacy.tradeMultiple(dragons, 1); } } } }, turnOffMoonOutpost: function () { var bld = game.space.getBuilding('moonOutpost'); if (bld.val > 0 && bld.on > 0) { _Helpers.log('No uranium: Turn Off MoonOutpost'); bld.on--; } }, unobtainiumToEludium: function () { var unobtainium = game.resPool.get('unobtainium'); if (unobtainium.value >= unobtainium.maxValue && _Helpers.isResourceUnlocked('eludium')) { var alloy = game.resPool.get('alloy'); if (unobtainium.value >= 1000 && alloy.value >= 2500) { var minVal = _Helpers.getMinCraft('eludium'); _Helpers.log2('Unobtainium to Eludium x ' + minVal); game.craft('eludium', minVal); } } }, buyReligion: function () { if (game.religionTab.visible) { var blds = game.religion.religionUpgrades; for (var i in blds) { if (blds.hasOwnProperty(i)) { var bld = blds[i]; if (!bld.noStackable && _Helpers.canBuyModel(bld, true)) { // This is a hack. Can't find API function to buy religion buildings // TODO - check if it is OK var prices = _Helpers.getPricesForModel(bld, true); game.resPool.payPrices(prices); bld.val++; bld.on++; _Helpers.log('Autobuy ' + bld.label); _Helpers.buildLog('Religion: ' + bld.label); } } } } } }; // noinspection JSUnusedGlobalSymbols var _BotUI = { currentPage: 'log', cy: undefined, cyElements: undefined, $scienceLegend: undefined, $scienceLegendTitle: undefined, $scienceLegendDescr: undefined, $scienceLegendPrice: undefined, $scienceLegendUnlock: undefined, buildingsTranslations: {}, initTranslations: function() { var bg = game.bld.buildingGroups; for (var x in bg) { if (bg.hasOwnProperty(x)) { for (var i in bg[x].buildings) { if (bg[x].buildings.hasOwnProperty(i)) { var b = bg[x].buildings[i]; var name = _Helpers.getBuildingTitle(b); _BotUI.buildingsTranslations[name] = b; } } } } }, 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 = ''; $('body').append($(style)); }, addColorsToBuildingsButtons: function() { var $buttons = $('.bldGroupContainer .btn.modern'); if ($buttons.length) { var gatherMintCaption = $I('buildings.gatherCatnip.label'); var pressMintCaption = $I('buildings.refineCatnip.label'); for (var i = 0; i < $buttons.length; i++) { var $btn = $buttons[i]; var isDisabled = $btn.className.indexOf('disabled') >= 0; if (isDisabled) { var btnText = $btn.innerText; var isSpecial = btnText.indexOf(gatherMintCaption) === 0 || btnText.indexOf(pressMintCaption) === 0; if (!isSpecial) { var idx = btnText.indexOf(' ('); if (idx <= 0) { var bldName = btnText; } else { bldName = btnText.substr(0, idx); } var building_type = _BotUI.buildingsTranslations[bldName]; if (typeof building_type !== 'undefined') { var canBuild = _Helpers.canBuildNow(building_type); if (!canBuild) { $($btn).addClass('nochance'); } else { $($btn).removeClass('nochance'); } } } } } } }, addColorsToBuildingsButtonsWithTimeout: function() { setTimeout(function() { KittenTools.UI.addColorsToBuildingsButtons(); }, 700); }, addBotButton: function () { var $a = $('Bot (' + (_BotLogic.isAutoLogicStarted ? 'on' : 'off') + ')'); $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 = '', br = '
'; inner += '
'; for (var i = 0; i < _BotSettings.settings.length; i++) { var idx = 'option' + i; inner += ''+ ''; } inner += '
' + br; inner += 'Logic
'; var currentSettingAuto = _BotSettings.settings[_BotSettings.settingIdx].auto; for (var x in currentSettingAuto) { if (currentSettingAuto.hasOwnProperty(x)) { var isChecked = currentSettingAuto[x]; inner += '' + x + ' : ' + (isChecked ? 'ON' : '-') + br; } } inner += br + 'Autobuid
'; var bg = game.bld.buildingGroups; for (x in bg) { if (bg.hasOwnProperty(x)) { inner += bg[x].title + br; for (i in bg[x].buildings) { if (bg[x].buildings.hasOwnProperty(i)) { var b = bg[x].buildings[i]; var name = _Helpers.getBuildingTitle(b); isChecked = _BotSettings.isCheckedBuySetting(b); inner += '' + name + ' : ' + (isChecked ? 'ON' : '-') + br; } } inner += br; } } inner += br + 'Keep resource
'; var rm = game.resPool.resourceMap; for (var r in rm) { if (rm.hasOwnProperty(r)) { if (rm[r].unlocked) { name = rm[r].title; isChecked = _BotSettings.isCheckedResSetting(r); inner += '' + name + ' : ' + (isChecked ? 'ON' : '-') + br; } } } $('#IRCChatInner').html(inner); }, initInfoPage: function() { var inner = '', br = '
'; inner += 'Show Tech tree' + br; inner += br; inner += 'Main:' + br; var kittensPromoteInfo = _Helpers.getKittensForPromoteInfo(); inner += '- Need promote: ' + kittensPromoteInfo.count + br; if (kittensPromoteInfo.count) { inner += '- Gold for promote: ' + kittensPromoteInfo.gold + br; } inner += br; var tradeRatio = game.diplomacy.getTradeRatio(); var spiceMax = 25 + 49 + 49 * tradeRatio; inner += 'Trades:' + br; inner += '- Blueprint chance: 10% (fixed)' + br; inner += '- Spice chance: 35% (fixed)' + br; inner += '- Spice amount max: ' + parseFloat(spiceMax).toFixed(2) + br; inner += '- Trade ratio: ' + parseFloat((tradeRatio + 1) * 100).toFixed(2) + '%' + br; var gameStanding = _Helpers.getGameStandingRatio(); inner += br; inner += 'Friendly trades:' + br; for (var rid in game.diplomacy.races) { if (game.diplomacy.races.hasOwnProperty(rid)) { var r = game.diplomacy.races[rid]; if (r.attitude === 'friendly' && r.standing) { var rStanding = r.standing * 100 + gameStanding/2; inner += '- ' + r.title +' +25% res chance: ' + parseFloat(rStanding).toFixed(2) + '%' + br; } } } inner += br; inner += 'Hostile trades:' + br; for (rid in game.diplomacy.races) { if (game.diplomacy.races.hasOwnProperty(rid)) { r = game.diplomacy.races[rid]; if (r.attitude === 'hostile' && r.standing) { rStanding = r.standing * 100 + gameStanding; inner += '- ' + r.title +' trade chance: ' + parseFloat(rStanding).toFixed(2) + '%' + br; } } } inner += br; inner += 'Neutral trades:' + br; var dragons = game.diplomacy.get('dragons'); var dragonsUranium = dragons.sells[0]; var minDragonsUranium = (1 - dragonsUranium.delta / 2) * (1 + tradeRatio); var maxDragonsUranium = (1 + dragonsUranium.delta / 2) * (1 + tradeRatio); inner += '- ' + dragons.title +' uranium: ' + parseFloat(minDragonsUranium).toFixed(2) + ' - ' + parseFloat(maxDragonsUranium).toFixed(2) + br; inner += '- ' + dragons.title +' trade chance: 95%' + br; inner += 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; inner += br; inner += 'Magneto bonus:' + br; var magnetoBonus = _Helpers.getMagnetoBonus(); var magnetoBonusAddSteam = _Helpers.getMagnetoBonus(1); var magnetoBonusAddMagneto = _Helpers.getMagnetoBonus(0, 1); inner += '- Current: ' + parseInt(magnetoBonus * 100) + '%' + br; inner += '- On +1 Steam: ' + parseInt(magnetoBonusAddSteam * 100) + '%' + br; inner += '- On +1 Magneto: ' + parseInt(magnetoBonusAddMagneto * 100) + '%' + br; $('#IRCChatInner').html(inner); }, initInfoButton: function () { $('.right-tab-header').append(' | Info'); }, initCustomLogButton: function(logName, buttonTitle) { $('.right-tab-header').append(' | ' + buttonTitle + ''); }, initCustomLogPage: function(logName) { var inner = ''; inner += 'Clear log
'; for (var i = (_Helpers._logs[logName].length - 1); i >= 0; i--) { if (_Helpers._logs[logName].hasOwnProperty(i)) { inner += '' + _Helpers._logs[logName][i] + ''; } } $('#IRCChatInner').html(inner); }, isCyInited: function() { return typeof _BotUI.cy !== 'undefined'; }, initCy: function() { var el = document.getElementById('scienceTree'); if (!_BotUI.isCyInited() && typeof cytoscape !== 'undefined' && el !== null) { var elems = [], elemsPositions = {}; var _addNode = function (name, connectTo, dx ,dy) { var t = game.science.get(name); if (!t) return; while (typeof elemsPositions[dx + '_' + dy] !== 'undefined') { dy += 100; } elemsPositions[dx + '_' + dy] = 1; var nodeData = { group: 'nodes', data: { id: t.name, researched: t.researched, unlocked: t.unlocked }, position: { x: dx, y: dy }, grabbable: false, locked: false }; /*if (typeof connectTo !== 'undefined') { nodeData.data.parent = connectTo; }*/ elems.push(nodeData); if (typeof connectTo !== 'undefined') { var linkName = t.name + '_' + connectTo; elems.push({ group: 'edges', data: { id: linkName, source: connectTo, target: t.name } }); } if (typeof t.unlocks !== 'undefined' && typeof t.unlocks.tech === 'object') { var offsetY = 0; for (var x in t.unlocks.tech) { if (t.unlocks.tech.hasOwnProperty(x)) { _addNode(t.unlocks.tech[x], name, dx + 150, dy + offsetY); offsetY += 100; } } } }; _addNode('calendar', undefined, 100, 100); _BotUI.cyElements = elems; _BotUI.cy = cytoscape({ container: el, // container to render in zoom: 0.5, wheelSensitivity: 0.25, style: [ { selector: 'node', style: { 'label': 'data(id)', 'background-color': function( ele ) { var unlocked = ele.data('unlocked'); var researched = ele.data('researched'); return researched ? 'green' : (unlocked ? 'lightblue' : 'gray'); } } }, { selector: ':selected', style: { 'background-color': 'white', 'border-width': '2px', 'border-style': 'solid', 'border-color': 'red' } } ] }); _BotUI.cy.add(_BotUI.cyElements); _BotUI.cy.on('click', _BotUI.onScienceNodeClick); } }, init: function () { _BotUI.fixStyles(); _BotUI.addBotButton(); _BotUI.initInfoButton(); _BotUI.initCustomLogButton('log2', 'Log2'); _BotUI.initCustomLogButton('trade', 'Trade'); _BotUI.initCustomLogButton('hunt', 'Hunts'); _BotUI.initCustomLogButton('wrkshp', 'Workshop'); _BotUI.initCustomLogButton('build', 'Build'); _BotUI.initScienceTree(); _BotUI.initScienceLegend(); _BotUI.initTranslations(); _BotUI.initLogLink(); //_BotUI.addColorsToBuildingsButtonsWithTimeout(); }, initScienceTree: function() { var closeDivButton = 'X'; var scienceDiv = ''; $('#gamePageContainer').prepend(scienceDiv); //_BotUI.initCy(); }, initScienceLegend: function() { var header = '
Название
'; var descr = '
Описание длинное
'; var prices = '
Цена: 1 crystal
'; var unlocks = '
Открывает: Religion
'; var blocks = header + descr + prices + unlocks; var inner = '
' + blocks + '
'; var scienceDiv = ''; $('#scienceTree').prepend(scienceDiv); _BotUI.$scienceLegend = $('#scienceLegend'); _BotUI.$scienceLegendTitle = $('#scienceLegendTitle'); _BotUI.$scienceLegendDescr = $('#scienceLegendDescr'); _BotUI.$scienceLegendPrice = $('#scienceLegendPrice'); _BotUI.$scienceLegendUnlock = $('#scienceLegendUnlock'); }, onCloseScienceTreeClick: function() { $('#scienceTree').hide(); }, onInfoButtonClick: function () { _BotUI.currentPage = 'info'; _BotUI.switchToChatAndMakeLinkActive('botinfobtn'); _BotUI.initInfoPage(); }, switchToChatAndMakeLinkActive: function(linkId) { game.ui.loadChat(); if (typeof linkId !== 'undefined') { $('.right-tab-header a.active').removeClass('active'); $('#' + linkId).addClass('active'); } }, onSettingsButtonClick: function () { _BotUI.currentPage = 'settings'; _BotUI.switchToChatAndMakeLinkActive(); _BotUI.initSettingsPage(); }, onCustomLogButtonClick: function(logName) { _BotUI.currentPage = logName; _BotUI.switchToChatAndMakeLinkActive('_log' + logName); _BotUI.initCustomLogPage(logName); }, initLogLink: function () { $('#logLink').attr('onclick', 'KittenTools.UI.onLogButtonClick()'); }, onLogButtonClick: function () { _BotUI.currentPage = 'log'; $('.right-tab-header a.active').removeClass('active'); game.ui.hideChat(); }, onClearCustonLogClick: function(logName) { _Helpers._logs[logName] = []; _BotUI.initCustomLogPage(logName); }, onOpenScienceTreeClick: function () { if (_BotUI.isCyInited()) { $('#scienceTree').show(); } else { _BotUI.initCy(); } }, onScienceNodeClick: function (e) { var clickedNode = e.target; var data = clickedNode.hasOwnProperty('0') ? clickedNode[0]._private.data : undefined; if (typeof data !== 'undefined') { var techName = data.id; if (techName.indexOf('_') === -1) { var tech = game.science.get(techName); _BotUI.initScienceLabel(tech); _BotUI.$scienceLegend.show(); } else { _BotUI.$scienceLegend.hide(); } } else { _BotUI.$scienceLegend.hide(); } }, getTechUnlocksTableHtml: function(tech) { var br = '
', hr = '
'; var unlocksTable = ''; var _addToUnlocksTable = function (title, techUnlocksUid, nameCallback) { var unlockArr = tech.unlocks[techUnlocksUid]; if (typeof unlockArr === 'undefined') return; unlocksTable += ''; }; var _translate = function(key, defValue) { return i18nLang.messages[key] ? $I(key) : defValue; }; _addToUnlocksTable( $I('tab.name.workshop'), 'crafts', function(name) { return $I('resources.' + name + '.title'); }); _addToUnlocksTable( $I('tab.name.science'), 'tech', function(name) { return game.science.get(name).label; }); _addToUnlocksTable( $I('workshop.upgradePanel.label'), 'upgrades', function(name) { return _translate('workshop.' + name + '.label', name); }); _addToUnlocksTable( 'Buildings', 'buildings', function(name) { return _translate('buildings.' + name + '.label', name); }); _addToUnlocksTable( 'Jobs', 'jobs', function(name) { return $I('village.job.' + name); }); _addToUnlocksTable( 'Tabs', 'tabs', function(name) { return $I('tab.name.' + name); }); _addToUnlocksTable( 'Chronoforge', 'chronoforge', function(name) { return _translate('time.cfu.' + name + '.label', name); }); _addToUnlocksTable( 'Void Space', 'voidSpace', function(name) { return _translate('time.vsu.' + name + '.label', name); }); _addToUnlocksTable( 'Challenges', 'challenges', function(name) { return _translate('challendge.' + name + '.label', name); }); _addToUnlocksTable( 'Stages', 'stages', function(name) { if (typeof name === 'object') { if (name.bld && typeof name.stage !== 'undefined') { var bld = game.bld.get(name.bld); var newName = name.stage; if (bld.stages && bld.stages[name.stage]) { newName = bld.stages[name.stage].label; } return _translate('buildings.' + name.bld + '.label', name.bld) + ' (' + newName + ')'; } else { return JSON.stringify(name); } } return name; }); unlocksTable += '
' + title + ':' + hr; for (var iid in unlockArr) { if (unlockArr.hasOwnProperty(iid)) { var aName = nameCallback(unlockArr[iid]); unlocksTable += aName + br; } } unlocksTable += '
'; return unlocksTable; }, getTechPriceTableHtml: function(tech) { var prices = game.science.getPrices(tech); var priceTable = ''; for (var pid in prices) { if (prices.hasOwnProperty(pid)) { var price = prices[pid]; var resName = $I('resources.' + price.name + '.title'); var value = game.getDisplayValueExt(parseInt(price.val)); priceTable += ''; } } priceTable += '
' + resName + '' + value + '
'; return priceTable; }, initScienceLabel: function (tech) { _BotUI.$scienceLegendTitle.text(tech.label); _BotUI.$scienceLegendDescr.text(tech.description); var priceTable = _BotUI.getTechPriceTableHtml(tech); _BotUI.$scienceLegendPrice.html(priceTable); if (tech.unlocks) { var unlocksTable = _BotUI.getTechUnlocksTableHtml(tech); _BotUI.$scienceLegendUnlock.html(unlocksTable).show(); } else { _BotUI.$scienceLegendUnlock.hide(); } }, onChangeSettingIdxClick: function (newIndex) { newIndex = parseInt(newIndex); if (_BotSettings.settingIdx !== newIndex) { _BotSettings.settingIdx = newIndex; _BotSettings.store('settingsIdx', _BotSettings.settingIdx); _BotUI.initSettingsPage(); } } }; 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.isAuto('Buy')) return; var currentSettingBuys = _BotSettings.settings[_BotSettings.settingIdx].buys; for (var x in currentSettingBuys) { if (currentSettingBuys.hasOwnProperty(x)) { if (currentSettingBuys[x] === true) { _BotLogic.autoBuyItem(x); } } } }, autoClick: function() { var field = game.bld.get('field'); if (field.on < 5) { game.bld.gatherCatnip() } else { var hut = game.bld.get('hut'); if (!hut.unlocked) { var catnip = game.resPool.get('catnip'); if (catnip.value >= 100) { game.bld.refineCatnip() } } } }, 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.oilToKerosene(); _BotLogic.unobtainiumToEludium(); _BotLogic.uraniumToThorium(); _BotLogic.spendScience(); _BotLogic.autoTrade(); _BotLogic.turnOffBuildings(); }, turnOffBuildings: function() { _BotLogic.turnOffMoonOutpost(); }, turnOffMoonOutpost: function() { var uranium = game.resPool.get('uranium'); if (uranium.unlocked && uranium.value <= 0 && game.getResourcePerTick('uranium', true) <= 0) { var bld = game.space.getBuilding('moonOutpost'); if (bld.val > 0 && bld.on > 0) { _BotActions.turnOffMoonOutpost(); } } }, autoTrade: function() { if (_BotSettings.isAuto('Trade')) { _BotActions.sendZebraCaravan(); _BotActions.sendDragonsCaravan(); _BotActions.sendNagasCaravan(); } }, promoteKittens: function () { if (_BotSettings.isAuto('PromoteKittens')) _BotActions.promoteKittens(); }, collectFaith: function () { if (_BotSettings.isAuto('CollectFaith')) _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 >= coal.maxValue && coal.value >= 100 && iron.value >= 100 && _Helpers.isResourceUnlocked('steel')) { _BotLogic.ironToSteel(); } else if (iron.value >= iron.maxValue && iron.value >= (125 * minPlate) && _Helpers.isResourceUnlocked('plate')) { _BotLogic.ironToPlates(); } } }, oilToKerosene: function () { if (_BotSettings.isAuto('CreateKerosene')) _BotActions.oilToKerosene(); }, unobtainiumToEludium: function () { if (_BotSettings.isAuto('CreateEludium')) _BotActions.unobtainiumToEludium(); }, uraniumToThorium: function () { if (_BotSettings.isAuto('CreateThorium')) _BotActions.uraniumToThorium(); }, ironToSteel: function () { if (_BotSettings.isAuto('CreateSteel')) _BotActions.ironToSteel(); }, ironToPlates: function () { if (_BotSettings.isAuto('CreatePlates')) _BotActions.ironToPlates(); }, sendAllHunters: function () { if (_BotSettings.isAuto('SendHunters')) _BotActions.sendAllHunters(); }, cultureToManuscript: function () { if (_BotSettings.isAuto('CreateManuscript')) _BotActions.cultureToManuscript(); }, catnipToWood: function () { if (_BotSettings.isAuto('CreateWood')) _BotActions.catnipToWood(); }, woodToBeams: function () { if (_BotSettings.isAuto('CreateBeams')) _BotActions.woodToBeams(); }, mineralsToSlabs: function () { if (_BotSettings.isAuto('CreateSlabs')) _BotActions.mineralsToSlabs(); }, spendScience: function() { var maxCompediums = _Helpers.getMaximumCompediumsToKeep(); var compediums = game.resPool.get('compedium'); var minBlueprintCanCraft = _Helpers.getMinCraft('blueprint'); if ((maxCompediums > 0 && compediums.value < maxCompediums) || compediums.value < (25 * minBlueprintCanCraft)) { _BotLogic.scienceToCompedium(); } else { _BotLogic.scienceToBlueprints(); } }, scienceToCompedium: function () { if (_BotSettings.isAuto('CreateCompedium')) _BotActions.scienceToCompedium(); }, scienceToBlueprints: function () { if (_BotSettings.isAuto('CreateBlueprints')) _BotActions.scienceToBlueprints(); } }; var _BotInjections = { game: { _oldMsg: undefined, msg: function (message, type, tag, noBullet) { if (tag === 'astronomicalEvent' || tag === 'meteor') { _Helpers.log2(message); } else if (tag === 'trade') { _Helpers.logCustom('trade', message); } else if (tag === 'hunt') { _Helpers.logCustom('hunt', message); } else if (tag === 'workshopAutomation') { _Helpers.logCustom('wrkshp', message); } else { _BotInjections.game._oldMsg.call(game, message, type, tag, noBullet); } }, tabs: { _oldRenderActiveGroup: undefined, renderActiveGroup: function (groupContainer) { _BotInjections.game.tabs._oldRenderActiveGroup.call(game.tabs[0], groupContainer); KittenTools.UI.addColorsToBuildingsButtonsWithTimeout(); } } }, init: function () { if (game && game.msg) { _BotInjections.game._oldMsg = game.msg; game.msg = _BotInjections.game.msg; } /*if (game && game.tabs && game.tabs[0] && game.tabs[0].__proto__.renderActiveGroup) { _BotInjections.game.tabs._oldRenderActiveGroup = game.tabs[0].__proto__.renderActiveGroup; game.tabs[0].__proto__.renderActiveGroup = _BotInjections.game.tabs.renderActiveGroup; }*/ } }; var KittenTools = { Helpers: _Helpers, Actions: _BotActions, UI: _BotUI, Settings: _BotSettings, Logic: _BotLogic }; var _starter = function() { if (typeof game.KittenTools === 'undefined') { game.KittenTools = KittenTools; } if (typeof unsafeWindow !== 'undefined') { unsafeWindow.KittenTools = KittenTools; unsafeWindow.cytoscape = cytoscape; } _BotLogic.tAutoLogic = setInterval(_BotLogic.autoLogic, 1000); _BotUI.init(); _BotSettings.init(); _Helpers.log('Started version ' + _Helpers.getBotVersion()); _BotInjections.init(); _Helpers.console('BOT: KittenTools version ' + _Helpers.getBotVersion() + ' started'); }; var _waiter = function() { if (_Helpers.isGameReady()) { _starter(); } else { setTimeout(_waiter, 1000); } }; _waiter(); })();