// ==UserScript== // @name Kittens tools // @namespace http://bloodrizer.ru/games/kittens/ // @version 1.199 // @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 = { 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'; }, 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 craftLevel = _BotSettings.getCraftLevel(); var ratioCount = Math.floor(allCount * craftLevel / 100); return ratioCount < 1 ? 1 : ratioCount; }, getPricesForModel: function(model, isReligion) { var ratio = model.priceRatio || 1; var prices = _Helpers.clone(model.prices); if (isReligion) { prices = game.village.getEffectLeader("wise", prices); } for (var i = 0; i< prices.length; i++){ prices[i].val = prices[i].val * Math.pow(ratio, model.val); } return prices; }, canBuyBuilding: function(bldName) { var prices = game.bld.getPrices(bldName); return _Helpers.isEnoughResourcesForPrice(prices); }, isEnoughResourcesForPrice: function(prices) { if (isNaN(prices.length)) { return false; // if it is not an array } 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; }, getMaximumScienceResourcesToKeep: function () { var maxCompediums = 0; var maxParchment = 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; } } else if (prices[p].name === 'parchment') { if (prices[p].val > maxParchment) { maxParchment = prices[p].val; } } } } } } } return { maxCompediums: maxCompediums, maxParchment: maxParchment }; }, getUnicornRiftChance: function () { var unicornChanceRatio = 1; if (game.prestige.getPerk("unicornmancy").researched){ unicornChanceRatio = 1.1; } unicornChanceRatio *= (1 + game.getEffect("timeRatio") * 0.25); var riftChance = game.getEffect("riftChance"); //5 OPTK return (riftChance * unicornChanceRatio) / 10000; }, getAlicornChance: function () { var aliChance = game.getEffect("alicornChance"); //0.2 OPTK return aliChance / 100000; }, getAstronomyChance: function () { var chanceRatio = 1; if (game.prestige.getPerk("chronomancy").researched){ chanceRatio = 1.1; } chanceRatio *= (1 + game.getEffect("timeRatio") * 0.25); var chance = 25; //25 OPTK of event per day (0.25%) chance += (game.getEffect("starEventChance") * 10000); chance *= chanceRatio; if (game.prestige.getPerk("astromancy").researched){ chance *= 2; } return chance / 10000; }, getCorruptionSpeed: function () { var sorrow = game.resPool.get("sorrow").value * 0.1; var alicorns = game.resPool.get("alicorn"); var corruption = 0; if (alicorns.value > 0){ corruption = ( game.getEffect("corruptionRatio") * (1 + Math.sqrt( sorrow * game.getEffect("blsCorruptionRatio") )) ) * (game.resPool.get("necrocorn").value > 0 ? 0.25 * (1 + game.getEffect("corruptionBoostRatio")) : //75% penalty 1); } return corruption; }, getSecondsFor1Corruption: function () { if (game.religion.corruption < 1) { var corruptionSpeed = _Helpers.getCorruptionSpeed(); if (corruptionSpeed > 0) { return Math.floor((1 - game.religion.corruption) / corruptionSpeed / 10); } } return 0; }, secondsToTimeStr: function (seconds) { seconds = parseInt(seconds); if (seconds > 0) { var hours = parseInt(seconds / 3600); var minutes = parseInt((seconds - 3600 * hours) / 60); var sec = seconds - 3600 * hours - 60 * minutes; var _lz = function(x) { return (x < 10 ? '0' + x : x); }; return _lz(hours) + ':' + _lz(minutes) + ':' + _lz(sec); } return '00:00:00'; }, getAlicornsPerSecond: function () { return game.getEffect('alicornPerTick') * 5; } }; var _Statistics = { _statTitle: 'Bot statistics', _collector: { crafts: {}, craftsCount: {}, counters: {}, diplomacyCount: {} }, addStatistics: function (group, name, value) { if (!_Statistics._collector[group].hasOwnProperty(name)) { _Statistics._collector[group][name] = parseFloat(value); } else { _Statistics._collector[group][name] += parseFloat(value); } }, addCraft: function (name, value) { _Statistics.addStatistics('crafts', name, value); }, addCraftCount: function (name, value) { _Statistics.addStatistics('craftsCount', name, value); }, addCounter: function (name, value) { _Statistics.addStatistics('counters', name, value); }, getStatsGroup: function () { var result = { group: [], title: _Statistics._statTitle }; for (var statGrp in _Statistics._collector) { if (_Statistics._collector.hasOwnProperty(statGrp)) { var groupName = statGrp; var statItems = _Statistics._collector[statGrp]; for (var statItemIdx in statItems) { if (statItems.hasOwnProperty(statItemIdx)) { var item = statItems[statItemIdx]; result.group.push({ name: groupName + ': ' + statItemIdx, title: groupName + ': ' + statItemIdx, val: item, unlocked: true }); } } } } return result; } }; var _Logs = { _logs: { log2: [], hunt: [], wrkshp: [], trade: [], build: [], craft: [] }, mainLog: function(message) { var mes = 'BOT: ' + message; if (game && game.msg && game.ui) { game.msg(mes, 'msg'); game.ui.renderConsoleLog(); } }, buildLog: function(message) { _Logs.logCustom('build', message, true); }, log2: function(message) { _Logs.logCustom('log2', message); }, logCustom: function(logName, message, withDateTime) { while (_Logs._logs[logName].length >= 100) { _Logs._logs[logName].shift(); } if (withDateTime === true) { message = '[' + _Helpers.getCurrentDateTime() + '] ' + message; } _Logs._logs[logName].push(message); if (_BotUI.currentPage === logName) { _BotUI.initCustomLogPage(logName); } }, console: function(message) { if (console) console.log(message); }, getCustomLogItem: function(logName, index) { if (_Logs._logs[logName].hasOwnProperty(index)) { return _Logs._logs[logName][index]; } return ''; }, getCustomLogSize: function(logName) { return _Logs._logs[logName].length }, clearCustomLog: function (logName) { _Logs._logs[logName] = []; }, logTrade: function (message) { _Logs.logCustom('trade', message); }, logCraft: function (message) { _Logs.logCustom('craft', message); } }; 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, BuyReligion: true }, craftLevel: 2, buys: {}, keeps: {} }; var zeroSetting = _Helpers.clone(_BotSetting); // noinspection JSUnusedGlobalSymbols var _BotSettingsMigrator = { currentVersion: 7, 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(); }, migrate5to6: function() { for (var i in _BotSettings.settings) { if (_BotSettings.settings.hasOwnProperty(i)) { if (typeof _BotSettings.settings[i].auto.BuyReligion === 'undefined') { _BotSettings.settings[i].auto.BuyReligion = true; } } } _BotSettings.version = 6; _BotSettings.storeSetting(); }, migrate6to7: function() { for (var i in _BotSettings.settings) { if (_BotSettings.settings.hasOwnProperty(i)) { if (typeof _BotSettings.settings[i].craftLevel === 'undefined') { _BotSettings.settings[i].craftLevel = 2; } } } _BotSettings.version = 7; _BotSettings.storeSetting(); }, migrateAll: function () { for (var i = 1; i < _BotSettingsMigrator.currentVersion; i++) { if (_BotSettings.version === i) { _BotSettingsMigrator['migrate' + i + 'to' + (i + 1)](); _Logs.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; }, getCraftLevel: function () { var currentSetting = _BotSettings.settings[_BotSettings.settingIdx]; return currentSetting.craftLevel; }, setCraftLevel: function (newLevel) { var currentSetting = _BotSettings.settings[_BotSettings.settingIdx].craftLevel; newLevel = parseInt(newLevel); if (newLevel > 0 && newLevel <= 100 && currentSetting !== newLevel) { _BotSettings.settings[_BotSettings.settingIdx].craftLevel = newLevel; _BotUI.initSettingsPage(); _BotSettings.storeSetting(); } } }; var _BotActions = { craftAll: function(res) { if (_Helpers.isResourceUnlocked(res)) { _Logs.log2('Crafting ' + res); var minAmt = game.workshop.getCraftAllCount(res); if (minAmt > 0 && minAmt < Number.MAX_VALUE) { var craftRatio = game.getResCraftRatio({name: res}); var bonus = minAmt * craftRatio; _Statistics.addCraft(res, minAmt + bonus); game.craftAll(res); _Statistics.addCraftCount(res, minAmt); } } }, craft: function(res, amount) { var craftRatio = game.getResCraftRatio({name: res}); var bonus = amount * craftRatio; _Statistics.addCraft(res, amount + bonus); game.craft(res, amount); _Statistics.addCraftCount(res, amount); }, collectAstronomy: function() { if (game.calendar.observeRemainingTime > 0) { if (typeof game.calendar.observeHandler === 'function') { game.calendar.observeHandler(); _Statistics.addCounter('astronomy', 1); } } }, 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) { _Logs.log2('Catnip to Wood x ' + minWood); _BotActions.craft('wood', minWood); _Statistics.addCraftCount('wood', minWood); } } }, collectFaith: function() { var faith = game.resPool.get('faith'); if (faith.value >= faith.maxValue) { _Logs.log2('Praise'); game.religion.praise(); _Statistics.addCounter('praise', 1); } }, sendAllHunters: function() { var manpower = game.resPool.get('manpower'); if (manpower.value >= manpower.maxValue) { _Logs.log2('Sending hunters'); game.village.huntAll(); _Statistics.addCounter('hunt', 1); _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) { _Logs.log2('Iron to Steel x ALL'); _BotActions.craftAll('steel'); } } } }, ironToPlates: function() { var iron = game.resPool.get('iron'); var minPlate = _Helpers.getMinCraft('plate'); if (iron.value >= (125 * minPlate) && _Helpers.isResourceUnlocked('plate')) { _Logs.log2('Iron to Plate x ' + minPlate); _BotActions.craft('plate', minPlate); } }, woodToBeams: function() { var wood = game.resPool.get('wood'); if (wood.value >= wood.maxValue && _Helpers.isResourceUnlocked('beam')) { var minVal = _Helpers.getMinCraft('beam'); _Logs.log2('Wood to Beam x ' + minVal); _BotActions.craft('beam', minVal); } }, mineralsToSlabs: function() { var minerals = game.resPool.get('minerals'); if (minerals.value >= minerals.maxValue && _Helpers.isResourceUnlocked('slab')) { var minVal = _Helpers.getMinCraft('slab'); _Logs.log2('Minerals to Slab x ' + minVal); _BotActions.craft('slab', minVal); } }, oilToKerosene: function() { var oil = game.resPool.get('oil'); if (oil.value >= oil.maxValue && _Helpers.isResourceUnlocked('kerosene')) { var minVal = _Helpers.getMinCraft('kerosene'); _Logs.log2('Oil to Kerosene x ' + minVal); _BotActions.craft('kerosene', minVal); } }, uraniumToThorium: function() { var uranium = game.resPool.get('uranium'); if (uranium.value >= uranium.maxValue && _Helpers.isResourceUnlocked('thorium')) { var minVal = _Helpers.getMinCraft('thorium'); _Logs.log2('Uranium to Thorium x ' + minVal); _BotActions.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)) { _Logs.log2('Culture to Manuscript x ' + minVal); _BotActions.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) { _Logs.mainLog('Autobuy ' + itemName); _Logs.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(); _Statistics.addCounter('promote', 1); } }, 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)) { _Logs.log2('Science/Manuscript to Compedium x ' + minVal); _BotActions.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)) { _Logs.log2('Science/Compedium to Blueprint x ' + minVal); _BotActions.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) { _Logs.logTrade('[Zebra trade] x 1'); game.diplomacy.tradeMultiple(zebras, 1); _Statistics.addStatistics('diplomacyCount', '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) { _Logs.logTrade('[Nagas trade] x 1'); game.diplomacy.tradeMultiple(nagas, 1); _Statistics.addStatistics('diplomacyCount', '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) { _Logs.logTrade('[Dragons trade] x 1'); game.diplomacy.tradeMultiple(dragons, 1); _Statistics.addStatistics('diplomacyCount', 'dragons', 1); } } } }, turnOffMoonOutpost: function () { var bld = game.space.getBuilding('moonOutpost'); if (bld.val > 0 && bld.on > 0) { _Logs.mainLog('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'); _Logs.log2('Unobtainium to Eludium x ' + minVal); _BotActions.craft('eludium', minVal); } } }, buyReligionBuilding: function(bld) { var prices = _Helpers.getPricesForModel(bld, true); if (_Helpers.isEnoughResourcesForPrice(prices)) { // It is a hack. Can't find API function to buy religion buildings game.resPool.payPrices(prices); bld.val++; bld.on++; if (bld.breakIronWill) { game.ironWill = false; } if (bld.unlocks) { game.unlock(bld.unlocks); } if (bld.upgrades) { game.upgrade(bld.upgrades); } _Logs.mainLog('Autobuy ' + bld.label); _Logs.buildLog('Religion: ' + bld.label); _Statistics.addCounter('buyReligion', 1); } }, buyReligion: function () { if (game.religionTab.visible) { var blds = game.religion.religionUpgrades; for (var i in blds) { if (blds.hasOwnProperty(i)) { var bld = blds[i]; var isVisible = bld.faith <= game.religion.faith; var needBuy = !bld.noStackable || bld.val < 1; if (isVisible && needBuy) { _BotActions.buyReligionBuilding(bld); } } } } }, craftResource: function(resName, minimumAmountInStorage) { var res = game.resPool.get(resName); if (res.value < minimumAmountInStorage && _Helpers.isResourceUnlocked(resName)) { var craftRatio = game.getResCraftRatio({name: resName}); var craftAmt = 1 + craftRatio; var needCrafts = Math.ceil((minimumAmountInStorage - res.value) / craftAmt); _Logs.log2('"' + resName + '" craft x ' + needCrafts); _BotActions.craft(resName, needCrafts); } } }; // 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) { _Logs.mainLog('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; _Logs.mainLog((_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 () { if (_BotUI.currentPage !== 'settings') return; 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 + 'Craft speed (%)
'; inner += '
'; var currentCraftLevel = _BotSettings.getCraftLevel(); var n1 = 1, n2 = 1; for (i = 0; i < 8; i++) { var lvl = n1 + n2; n1 = n2; n2 = lvl; // Fibbonacci idx = 'craftlevel' + lvl; inner += ''+ ''; } inner += '
' + 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 = '
'; var floatToStr = function (num, maxDigits) { var resultStr = 0; num = parseFloat(num); if (num >= 0.01) { if (typeof maxDigits === 'undefined') maxDigits = 2; resultStr = num.toFixed(maxDigits); } else if (num >= 0.001) { if (typeof maxDigits === 'undefined') maxDigits = 3; resultStr = num.toFixed(maxDigits); } else if (num >= 0.0001) { if (typeof maxDigits === 'undefined') maxDigits = 4; resultStr = num.toFixed(maxDigits); } else if (num >= 0.00001) { if (typeof maxDigits === 'undefined') maxDigits = 5; resultStr = num.toFixed(maxDigits); } else if (num >= 0.1) { if (typeof maxDigits === 'undefined') maxDigits = 1; resultStr = num.toFixed(maxDigits); } else { resultStr = num > 1 ? num.toFixed(0) : '0+'; } return resultStr; }; var percentToStr = function(chanceInPercent) { return floatToStr(chanceInPercent) + '%'; }; var chanceToStr = function(chance) { return percentToStr(parseFloat(chance) * 100); }; 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 += '- Rift chance: ' + chanceToStr(_Helpers.getUnicornRiftChance()) + br; inner += '- Alicorn chance: ' + chanceToStr(_Helpers.getAlicornChance()) + br; inner += '- Astronomy chance: ' + chanceToStr(_Helpers.getAstronomyChance()) + br; var timeForCorruption = _Helpers.secondsToTimeStr(_Helpers.getSecondsFor1Corruption()); inner += '- To Corruption: ' + timeForCorruption + br; var alicornsPerSecond = _Helpers.getAlicornsPerSecond(); inner += '- Alicorn/sec: ' + floatToStr(alicornsPerSecond, 5) + 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: ' + chanceToStr(tradeRatio + 1) + br; var gameStanding = _Helpers.getGameStandingRatio(); inner += br; inner += 'Friendly trades (+25% res):' + 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 +': ' + percentToStr(rStanding) + br; } } } inner += br; inner += 'Hostile trades chance:' + 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 +': ' + percentToStr(rStanding) + 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: ' + percentToStr(zebraTitanium.percent)+ 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: ' + chanceToStr(magnetoBonus) + br; inner += '- On +1 Steam: ' + chanceToStr(magnetoBonusAddSteam) + br; inner += '- On +1 Magneto: ' + chanceToStr(magnetoBonusAddMagneto) + 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
'; var lastLogIndex = _Logs.getCustomLogSize(logName) - 1; for (var i = lastLogIndex; i >= 0; i--) { inner += '' + _Logs.getCustomLogItem(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.initCustomLogButton('craft', 'Craft'); _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) { _Logs.clearCustomLog(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(); } }, initStatsPage: function () { for (var i in game.stats.statGroups) { if (game.stats.statGroups.hasOwnProperty(i)) { var grp = game.stats.statGroups[i]; if (grp.title === _Statistics._statTitle) { game.stats.statGroups[i] = _Statistics.getStatsGroup(); return; } } } game.stats.statGroups.push(_Statistics.getStatsGroup()); }, onChangeCraftLevel: function (newLevel) { _BotSettings.setCraftLevel(newLevel); } }; 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'); var wood = game.resPool.get('wood'); if (!hut.unlocked || wood.value < 10) { var catnip = game.resPool.get('catnip'); if (catnip.value >= 100) { game.bld.refineCatnip() } } } }, autoLogic: function() { _BotUI.fixFontSize(); _BotUI.initStatsPage(); _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.buyReligion(); _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')) { if (_Helpers.isResourceUnlocked('eludium')) { var unobtainium = game.resPool.get('unobtainium'); if (unobtainium.value >= unobtainium.maxValue && unobtainium.value >= 1000) { _BotActions.craftResource('alloy', 2500); } _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')) { var maxScienceResources = _Helpers.getMaximumScienceResourcesToKeep(); if (maxScienceResources.maxParchment === 0) { _BotActions.cultureToManuscript(); } else { var parchments = game.resPool.get('parchment'); if ((parchments.value - 25) >= maxScienceResources.maxParchment) { _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 maxScienceResources = _Helpers.getMaximumScienceResourcesToKeep(); var compediums = game.resPool.get('compedium'); var minBlueprintCanCraft = _Helpers.getMinCraft('blueprint'); if ((maxScienceResources.maxCompediums > 0 && compediums.value < maxScienceResources.maxCompediums) || (compediums.value < (25 * minBlueprintCanCraft))) { _BotLogic.scienceToCompedium(); } else { _BotLogic.scienceToBlueprints(); _BotLogic.scienceToCompedium(); } }, scienceToCompedium: function () { if (_BotSettings.isAuto('CreateCompedium')) _BotActions.scienceToCompedium(); }, scienceToBlueprints: function () { if (_BotSettings.isAuto('CreateBlueprints')) _BotActions.scienceToBlueprints(); }, buyReligion: function () { if (_BotSettings.isAuto('BuyReligion')) _BotActions.buyReligion(); } }; var _BotInjections = { game: { _oldMsg: undefined, msg: function (message, type, tag, noBullet) { if (tag === 'astronomicalEvent' || tag === 'meteor') { _Logs.log2(message); } else if (tag === 'trade') { _Logs.logTrade(message); } else if (tag === 'hunt') { _Logs.logCustom('hunt', message); } else if (tag === 'craft') { _Logs.logCraft(message); } else if (tag === 'workshopAutomation') { _Logs.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, Logs: _Logs }; 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, 2000); _BotUI.init(); _BotSettings.init(); _Logs.mainLog('Started version ' + _Helpers.getBotVersion()); _BotInjections.init(); _Logs.console('BOT: KittenTools version ' + _Helpers.getBotVersion() + ' started'); }; var _waiter = function() { if (_Helpers.isGameReady()) { _starter(); } else { setTimeout(_waiter, 1000); } }; _waiter(); })();