Trimps tools

Trimps tools (visual)

目前為 2018-12-04 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Trimps tools
// @namespace    trimps.github.io
// @version      1.262
// @description  Trimps tools (visual)
// @author       Anton
// @match        https://trimps.github.io
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// ==/UserScript==

(function () {
    'use strict';

    var tAutoBuy, tStyleFix, tPassiveWatcher, $ = jQuery, isStarted = false,
        version = typeof GM_info === 'function' ? GM_info().script.version :
            (typeof GM_info === 'object' ? GM_info.script.version : '?');

    var _isPortal = function () {
        return portalWindowOpen;
    };

    var _getJobPrice = function (jobName, resource) {
        return game.jobs[jobName].cost[resource][0] * Math.pow(game.jobs[jobName].cost[resource][1], game.jobs[jobName].owned);
    };

    var _hasFormation = function(what) {
        what = parseInt(what);
        if (!game.global.preMapsActive && !game.global.lockTooltip) {
            if (game.upgrades.Formations.done && what === 0) return true;
            if (game.upgrades.Formations.done && what === 1) return true;
            if (game.upgrades.Dominance.done && what === 2) return true;
            if (game.upgrades.Barrier.done && what === 3) return true;
            if (game.upgrades.Formations.done && game.global.highestLevelCleared >= 180 && what === 4) return true;
        }
        return false;
    };

    var _getEnemyAttack = function() {
        var cellNum, cell;
        if (game.global.mapsActive) {
            cellNum = game.global.lastClearedMapCell + 1;
            cell = game.global.mapGridArray[cellNum];
        } else {
            cellNum = game.global.lastClearedCell + 1;
            cell = game.global.gridArray[cellNum];
        }
        return calculateDamage(cell.attack, false, false, false, cell);
    };

    var _middleGameStrategy = function() {
        if (game.global.world < 60) return;

        if (game.global.formation === 0) {
            if (_hasFormation(1)) setFormation('1');
        }

        var enemy = _getEnemyAttack();
        var me = game.global.soldierCurrentBlock + game.global.soldierHealthMax;
        if (enemy >= me && parseInt(game.global.formation) !== 1) {
            if (_hasFormation(1)) setFormation('1');
        }

        if (parseInt(game.global.formation) !== 2 && _hasFormation(2)) {
            var formation2health = game.global.soldierHealthMax / 8;
            var me2 = formation2health + game.global.soldierCurrentBlock;
            if (me2 > enemy) {
                setFormation('2');
            }
        }
    };

    var _log = function (mes, type) {
        if (typeof type === 'undefined') type = "Story";
        message("BOT: " + mes, type);
    };

    var _getBreedingBaseSpeed = function () {
        if (game.global.challengeActive === "Trapper") return 0;
        var base = 0.0085;
        var currentCalc = _getBreeding() * base;
        if (game.upgrades.Potency.done > 0) {
            currentCalc *= Math.pow(1.1, game.upgrades.Potency.done);
        }
        return currentCalc;
    };

    var _getBreedingTotalSpeed = function () {
        if (game.global.challengeActive === "Trapper") return 0;
        var trimps = game.resources.trimps;
        var base = 0.0085;
        //Add job count
        var breeding = trimps.owned - trimps.employed;
        var currentCalc = breeding * base;
        //Add Potency
        if (game.upgrades.Potency.done > 0){
            currentCalc *= Math.pow(1.1, game.upgrades.Potency.done);
        }
        //Add Nurseries
        if (game.buildings.Nursery.owned > 0){
            currentCalc *= Math.pow(1.01, game.buildings.Nursery.owned);
        }
        //Add Venimp
        if (game.unlocks.impCount.Venimp > 0){
            var venimpStrength = Math.pow(1.003, game.unlocks.impCount.Venimp);
            currentCalc *= (venimpStrength);
        }
        if (game.global.brokenPlanet){
            currentCalc /= 10;
        }
        //Add pheromones
        if (game.portal.Pheromones.level > 0){
            var PheromonesStrength = (game.portal.Pheromones.level * game.portal.Pheromones.modifier);
            currentCalc  *= (PheromonesStrength + 1);
        }
        //Add Geneticist
        if (game.jobs.Geneticist.owned > 0) {
            currentCalc *= Math.pow(.98, game.jobs.Geneticist.owned);
        }
        //Add quick trimps
        if (game.unlocks.quickTrimps){
            currentCalc *= 2;
        }
        if (game.global.challengeActive === "Daily"){
            var mult = 0;
            if (typeof game.global.dailyChallenge.dysfunctional !== 'undefined'){
                mult = dailyModifiers.dysfunctional.getMult(game.global.dailyChallenge.dysfunctional.strength);
                currentCalc *= mult;
            }
            if (typeof game.global.dailyChallenge.toxic !== 'undefined'){
                mult = dailyModifiers.toxic.getMult(game.global.dailyChallenge.toxic.strength, game.global.dailyChallenge.toxic.stacks);
                currentCalc *= mult;
            }
        }
        if (game.global.challengeActive === "Toxicity" && game.challenges.Toxicity.stacks > 0){
            currentCalc *= Math.pow(game.challenges.Toxicity.stackMult, game.challenges.Toxicity.stacks);
        }
        if (game.global.voidBuff === "slowBreed"){
            currentCalc *= 0.2;
        }
        var heirloomBonus = calcHeirloomBonus("Shield", "breedSpeed", 0, true);
        if (heirloomBonus > 0){
            currentCalc *= ((heirloomBonus / 100) + 1);
        }
        return currentCalc;
    };

    var _hasUpgradeForEquipment = function (equipName) {
        for (var item in game.upgrades) {
            if (game.upgrades.hasOwnProperty(item)) {
                var upgrade = game.upgrades[item];
                if (parseInt(upgrade.locked) === 1) continue;
                if (typeof upgrade.prestiges !== 'undefined' && upgrade.prestiges === equipName) {
                    return true;
                }
            }
        }
        return false;
    };

    var _getMetalNeededForEquipment = function (equipName) {
        var price = getBuildingItemPrice(game.equipment[equipName], 'metal', true, 1);
        var artMult = Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.level);
        if (game.global.challengeActive === "Daily" && typeof game.global.dailyChallenge.metallicThumb !== 'undefined'){
            artMult *= dailyModifiers.metallicThumb.getMult(game.global.dailyChallenge.metallicThumb.strength);
        }
        if (game.global.challengeActive === "Obliterated"){
            artMult = (artMult === -1) ? 1e12 : (1e12 * artMult);
        }
        price = Math.ceil(price * artMult);
        return price;
    };

    var _autoEquipment = function () {
        var maxEquipLevel = game.global.challengeActive === 'Frugal' ? 10000 : 7;
        for (var x in game.equipment) {
            if (game.equipment.hasOwnProperty(x) && game.equipment[x].locked === 0) {
                if (_hasUpgradeForEquipment(x)) continue;
                var maxLevel = game.equipment[x].prestige > maxEquipLevel ? 1 : (maxEquipLevel + 1 - game.equipment[x].prestige) * 2;
                if (x === 'Shield' && !game.equipment['Shield'].blockNow) {
                    maxLevel = 1;
                }
                if (game.equipment[x].level < maxLevel && canAffordBuilding(x, null, null, true)) {
                    if (game.equipment[x].cost.hasOwnProperty('metal')) {
                        // save metal for upgrades
                        var currentMetal = game.resources['metal'].owned;
                        var equipMetal = _getMetalNeededForEquipment(x);
                        var upgradesMetal = _getUpgradePriceSumForRes('metal');
                        if (currentMetal >= (upgradesMetal + equipMetal)) {
                            buyEquipment(x, true, true);
                            _log('Upgrading equipment ' + x);
                        }
                    } else {
                        buyEquipment(x, true, true);
                        _log('Upgrading equipment ' + x);
                    }
                }
            }
        }
    };

    var _getMinimumBreeding = function () {
        var battleTrimps = (game.portal.Coordinated.level) ? game.portal.Coordinated.currentSend : game.resources.trimps.maxSoldiers;
        if (battleTrimps < 5) return 5; else return battleTrimps + 1;
    };

    var _buyStorage = function () {
        var packratLevel = (1 + game.portal.Packrat.level * (game.portal.Packrat.modifier * 100) / 100);
        var buildingsForResources = {
            food: "Barn",
            wood: "Shed",
            metal: "Forge"
        };

        for (var res in buildingsForResources) {
            if (buildingsForResources.hasOwnProperty(res)) {
                var bldName = buildingsForResources[res];
                if (game.resources[res].owned / (game.resources[res].max * packratLevel) >= 0.8) {
                    if (canAffordBuilding(bldName, false, false, false, true)) {
                        buyBuilding(bldName, true, true);
                        _log('Building ' + bldName);
                    }
                }
            }
        }
    };

    var _hasInQueue = function (item) {
        for (var x in game.global.buildingsQueue) {
            var queueItem = game.global.buildingsQueue[x].split('.')[0];
            if (queueItem === item) {
                return true;
            }
        }
        return false;
    };

    var _getBreeding = function () {
        var trimps = game.resources.trimps;
        return game.global.challengeActive === "Trapper" ? 0 : trimps.owned - trimps.employed;
    };

    var _earlyGameStrategy = function (isPassive) {
        if (_isPortal()) return;

        var playerStrength = getPlayerModifier();
        var minimumSpeedToHelp = 1 + playerStrength;

        if (parseInt(game.global.eggLoc) !== -1) {
            _log('Destroying Easter Egg');
            easterEggClicked();
        }

        _buyStorage();
        if (isPassive === false) {
            _autoJobs();
        }

        var breeding = _getBreeding();
        var unemployed = Math.ceil(game.resources.trimps.realMax() / 2) - game.resources.trimps.employed;

        if (game.buildings.Trap.owned >= 1 && game.resources.trimps.owned < game.resources.trimps.realMax() &&
            (breeding < _getMinimumBreeding() || unemployed > 0) &&
            _getBreedingBaseSpeed() < 1) {
            setGather('trimps');
            return;
        }

        var canGetScience = game.global.challengeActive !== "Scientist";

        var hasTrap = _hasInQueue('Trap');
        var cnt = game.global.challengeActive === "Trapper" ? 100 : (breeding < unemployed ? 25 : 1);
        if (!hasTrap && game.buildings.Trap.owned < 1 && game.resources.food.owned >= 10 && game.resources.wood.owned >= 10) {
            buyBuilding('Trap', true, true, cnt);
            return;
        }

        if ((game.global.buildingsQueue.length > 0 && game.global.autoCraftModifier < 1) || (game.global.buildingsQueue.length > 5)) {
            setGather('buildings');
            return;
        }

        if (getPsString('food', true) < minimumSpeedToHelp && game.resources.food.owned < 10) {
            setGather('food');
            return;
        }

        if (getPsString('wood', true) < minimumSpeedToHelp && game.resources.wood.owned < 10) {
            setGather('wood');
            return;
        }

        if (canGetScience && getPsString('science', true) < minimumSpeedToHelp && game.resources.science.owned < 10) {
            setGather('science');
            return;
        }

        if (getPsString('metal', true) < minimumSpeedToHelp && game.resources.metal.owned < 100) {
            setGather('metal');
            return;
        }

        var needScientist = game.upgrades.Scientists.done === 0 && game.upgrades.Scientists.allowed === 1;
        if (canGetScience && getPsString('science', true) < minimumSpeedToHelp && (game.resources.science.owned < 60 || needScientist)) {
            setGather('science');
            return;
        }

        if ((game.global.playerGathering === 'trimps' && (game.buildings.Trap.owned === 0 || _getBreedingBaseSpeed() > 1)) ||
            (game.global.playerGathering === 'buildings' && game.global.buildingsQueue.length === 0)) {
            _selectAutoJob();
        }
    };

    var _selectAutoJob = function () {
        var canGetScience = game.global.challengeActive !== "Scientist";
        var upgradePrice = _getMaximumResourceUpgradePrice();
        var scienceNeeded = _getUpgradePriceSumForRes('science');
        if (scienceNeeded > game.resources.science.owned && canGetScience) {
            setGather('science');
        } else {
            if (upgradePrice !== false) {
                for (var x in upgradePrice) {
                    if (upgradePrice.hasOwnProperty(x)) {
                        if (x === 'wood' || x === 'metal' || x === 'science' || x === 'food') {
                            setGather(x);
                        } else {
                            if (canGetScience) {
                                setGather('science');
                            } else {
                                setGather('food');
                            }
                        }
                        break;
                    }
                }
            } else {
                if (canGetScience) {
                    setGather('science');
                } else {
                    setGather('food');
                }
            }
        }
    };

    var _passiveWatcher = function () {
        if (_isPortal()) return;

        _earlyGameStrategy(true);

        var canAfford = canAffordBuilding("Tribute", false, false, false, true);
        if (canAfford && game.buildings.Tribute.locked !== 1) {
            buyBuilding("Tribute", true, true);
            _log('Building ' + "Tribute");
        }

        canAfford = canAffordBuilding("Gym", false, false, false, true);
        if (canAfford && game.buildings.Gym.locked !== 1) {
            buyBuilding("Gym", true, true);
            _log('Building ' + "Gym");
        }

        _middleGameStrategy();
    };

    var _needAttackCurrentMap = function () {
        return (typeof game.mapsAttacked[game.global.world] === 'undefined');
    };

    var _hasMapOfCurrentLevel = function () {
        for (var x in game.global.mapsOwnedArray) {
            if (game.global.mapsOwnedArray.hasOwnProperty(x)) {
                var mapObj = game.global.mapsOwnedArray[x];
                if (parseInt(mapObj.level) === parseInt(game.global.world)) return true;
            }
        }
        return false;
    };

    var _buyNewMapOfCurrentLevel = function () {
        var money = game.resources.fragments.owned;
        var currentMapPrice = updateMapCost(true);
        if (money >= currentMapPrice) {
            var result = buyMap();
            if (result === 1) {
                _log('Bought new map level ' + game.global.world);
            } else {
                console.log('Buy map result = ' + result);
            }
        } else {
            console.log('No fragments (' + money + ') to buy map for ' + currentMapPrice);
        }
    };

    var _attackMapOfCurrentLevel = function (knownMapId, isPrestige) {
        var x, mapObj;
        var breeding = _getBreeding();

        game.global.lookingAtMap = '';
        if (typeof knownMapId === 'undefined') {
            for (x in game.global.mapsOwnedArray) {
                if (game.global.mapsOwnedArray.hasOwnProperty(x)) {
                    mapObj = game.global.mapsOwnedArray[x];
                    if (parseInt(mapObj.level) === parseInt(game.global.world)) {
                        game.global.lookingAtMap = mapObj.id;
                        break;
                    }
                }
            }
        } else {
            game.global.lookingAtMap = knownMapId;
        }

        if (game.global.lookingAtMap !== '') {
            _log('Attacking ' + (isPrestige ? 'prestige ' : '') + 'map ' + game.global.lookingAtMap);
            game.options.menu.alwaysAbandon.enabled = 1; // GO TO MAPS!
            mapsClicked(true);
            game.mapsAttacked[game.global.world] = true;
            game.global.repeatMap = true; // REPEAT
            repeatClicked(true);
            runMap();
            if (breeding < (_getMinimumBreeding() + 1)) fightManual();
        } else {
            console.log('where is my map?');
        }
    };

    var _getPrestigeMapToAttack = function () {
        for (var x in game.global.mapsOwnedArray) {
            if (game.global.mapsOwnedArray.hasOwnProperty(x)) {
                var mapObj = game.global.mapsOwnedArray[x];
                if (parseInt(mapObj.clears) === 0
                    && parseInt(mapObj.level) <= parseInt(game.global.world)
                    && mapObj.noRecycle) {
                    return mapObj.id;
                }
            }
        }
        return -1;
    };

    var _attackCurrentMap = function () {
        document.getElementById("mapLevelInput").value = game.global.world;

        var prestigeMapToAttack = _getPrestigeMapToAttack();
        if (prestigeMapToAttack !== -1) {
            _attackMapOfCurrentLevel(prestigeMapToAttack, true);
            return;
        }

        if (!_hasMapOfCurrentLevel()) {
            _buyNewMapOfCurrentLevel();
        }

        if (_hasMapOfCurrentLevel()) {
            _attackMapOfCurrentLevel();
        } else {
            console.log('no map of current level ' + game.global.world);
        }
    };

    var _mapAttackStrategy = function () {
        var x, mapObj;
        var breeding = _getBreeding();

        if (game.global.world < 6) return;
        if (game.global.preMapsActive) return;
        //if (!game.global.mapsUnlocked) return;
        if (game.global.pauseFight) {
            _log('Enabling auto attack!');
            fightManual();
            game.global.pauseFight = false;
            pauseFight(true); // update only
        } else {
            if (_needAttackCurrentMap()) {
                _attackCurrentMap();
            } else {
                if (_hasMapOfCurrentLevel() && game.global.currentMapId === '') {
                    game.global.lookingAtMap = '';
                    var map_id, map_name = '';
                    for (x in game.global.mapsOwnedArray) {
                        if (game.global.mapsOwnedArray.hasOwnProperty(x)) {
                            mapObj = game.global.mapsOwnedArray[x];
                            if (mapObj.level <= game.global.world && mapObj.noRecycle === true && mapObj.clears === 0) {
                                game.global.lookingAtMap = mapObj.id;
                                map_id = x;
                                map_name = mapObj.name;
                                break;
                            }
                        }
                    }
                    if (game.global.lookingAtMap !== '' && typeof map_id !== 'undefined') {
                        _log('Attacking prestige map ' + map_name + ' level (' + game.global.mapsOwnedArray[map_id].level + ')');
                        game.options.menu.alwaysAbandon.enabled = 1; // GO TO MAPS!
                        mapsClicked(true);
                        game.global.repeatMap = true; // REPEAT
                        repeatClicked(true);
                        game.global.mapsOwnedArray[map_id].clears = 1;
                        runMap();
                        if (breeding < (_getMinimumBreeding() + 1)) fightManual();
                    }
                } else {
                    if (game.global.currentMapId !== '') {
                        var lastMapCell = game.global.mapGridArray[game.global.mapGridArray.length - 1];
                        var specialGift = '';
                        if (lastMapCell.special !== '') {
                            specialGift = game.mapUnlocks[lastMapCell.special];
                        }
                        var needExitMap = (specialGift === '' || specialGift.prestige !== true) &&
                            lastMapCell.special !== 'Heirloom' &&
                            lastMapCell.name !== 'Warden' &&
                            lastMapCell.name !== 'Robotrimp' &&
                            specialGift.canRunOnce !== true;
                        if (needExitMap) {
                            mapsClicked(true); // go to maps
                            recycleMap(-1, true);
                            mapsClicked(); // go to world
                        }
                    }
                }
            }
        }
    };

    var _mapDeleter = function() {
        if (game.global.currentMapId === '') {
            for (var x in game.global.mapsOwnedArray) {
                var map = game.global.mapsOwnedArray[x];
                if (map.level < (game.global.world - 10) && map.noRecycle !== true) {
                    game.global.lookingAtMap = map['id'];
                    _log('Deleting map ' + map.name + ' (' + map.level + ')');
                    recycleMap(-1, true);
                    break;
                }
            }
        }
    };

    var _auto = function () {
        if (_isPortal()) return;
        _earlyGameStrategy(false);

        _autoUpgrade();
        _autoBuy();
        _autoEquipment();
        _mapAttackStrategy();

        _middleGameStrategy();

        _mapDeleter();
    };

    var _onStartButton = function () {
        if (isStarted) {
            _stop();
            _log('Stop.');
            isStarted = false;
        } else {
            _start();
            _log('Started!');
            isStarted = true;
        }
    };

    var _autoUpgrade = function () {
        for (var item in game.upgrades) {
            if (game.upgrades.hasOwnProperty(item)) {
                var upgrade = game.upgrades[item];
                if (parseInt(upgrade.locked) === 1) continue;
                var canAfford = canAffordTwoLevel(upgrade);
                if (canAfford) {
                    if (item === "Coordination") {
                        if (!canAffordCoordinationTrimps()) continue;
                    }
                    if (item === "Gigastation") {
                        var minAddon = Math.floor(game.global.highestLevelCleared / 6);
                        var minWaprstation = Math.floor(game.global.world / 6) + minAddon + game.upgrades.Gigastation.done * 2;
                        if (minWaprstation < 6 + minAddon) minWaprstation = 6 + minAddon;
                        if (game.buildings.Warpstation.owned < minWaprstation) continue;
                    }
                    buyUpgrade(item, true, true);
                    _log('Upgrading ' + item);
                    _selectAutoJob();
                    return 1;
                }
            }
        }
        return 0;
    };

    var getUpgradePrice = function (upgradeObject) {
        var price, result = {};
        for (var cost in upgradeObject.cost) {
            if (upgradeObject.cost.hasOwnProperty(cost)) {
                if (typeof upgradeObject.cost[cost] === 'object' && typeof upgradeObject.cost[cost][1] === 'undefined') {
                    var costItem = upgradeObject.cost[cost];
                    for (var item in costItem) {
                        if (costItem.hasOwnProperty(item)) {
                            price = costItem[item];
                            if (upgradeObject.prestiges && (item === "metal" || item === "wood")) {
                                if (game.global.challengeActive === "Daily" && typeof game.global.dailyChallenge.metallicThumb !== 'undefined') {
                                    price *= dailyModifiers.metallicThumb.getMult(game.global.dailyChallenge.metallicThumb.strength);
                                }
                                price *= Math.pow(1 - game.portal.Artisanistry.modifier, game.portal.Artisanistry.level);
                            }
                            if (typeof price === 'function') price = price();
                            if (typeof price[1] !== 'undefined') price = resolvePow(price, upgradeObject);
                            result[item] = price;
                        }
                    }
                }
            }
        }
        return result;
    };

    var _getAllUpgradePrice = function () {
        var totalPrice = {};
        for (var item in game.upgrades) {
            if (game.upgrades.hasOwnProperty(item)) {
                var upgrade = game.upgrades[item];
                if (parseInt(upgrade.locked) === 1) continue;
                var price = getUpgradePrice(upgrade);
                for (var res in price) {
                    if (price.hasOwnProperty(res)) {
                        if (typeof totalPrice[res] === 'undefined') totalPrice[res] = 0;
                        totalPrice[res] += price[res];
                    }
                }
            }
        }
        return totalPrice;
    };

    var _getUpgradePriceSumForRes = function (res) {
        var totalPrice = _getAllUpgradePrice();
        if (typeof totalPrice[res] !== 'undefined') {
            return totalPrice[res];
        } else {
            return 0;
        }
    };

    var _getMaximumResourceUpgradePrice = function () {
        var totalPrice = _getAllUpgradePrice(), maxPriceName = '', maxPrice = 0;
        for (var res in totalPrice) {
            if (totalPrice.hasOwnProperty(res)) {
                if (totalPrice[res] > maxPrice) {
                    maxPrice = totalPrice[res];
                    maxPriceName = res;
                }
            }
        }
        var result = {};
        if (maxPriceName !== '') {
            result[maxPriceName] = maxPrice;
            return result;
        } else {
            return false;
        }
    };

    var _autoBuy = function () {
        var toBuy;
        for (var item in game.buildings) {
            if (item === 'Barn' || item === 'Shed' || item === 'Forge' || item === 'Wormhole' || item === 'Trap') continue;
            if (!game.buildings.Collector.locked &&
                (item === 'Mansion' || item === 'Hotel' || item === 'Resort' || item === 'House' || item === 'Hut')) continue;
            if (game.upgrades.Gigastation.done >= 10 && item === 'Collector') continue;

            if (game.buildings.hasOwnProperty(item)) {
                if (parseInt(game.buildings[item].locked) === 1) continue;
                var canAfford = canAffordBuilding(item, false, false, false, true);
                if (canAfford) {
                    if (item === 'Nursery') {
                        var isElectro = game.global.challengeActive === "Electricity";
                        var mult = game.global.brokenPlanet ? (game.global.world >= 80 ? 2 : 1.5) : 1;
                        var enoughNursery = (game.buildings.Nursery.owned >= (game.buildings.Tribute.owned * mult) ||
                            game.buildings.Nursery.owned >= (game.buildings.Gym.owned * mult));

                        if ((isElectro || !enoughNursery) && !_hasInQueue('Nursery'))
                        {
                            toBuy = item;
                        }
                    } else {
                        toBuy = item;
                    }
                }
            }
        }
        if (typeof toBuy !== 'undefined') {
            buyBuilding(toBuy, true, true);
            _log('Building ' + toBuy);
            return 1;
        } else {
            return 0;
        }
    };

    var needFarmer = 25, needLumber = 25, needMiner = 25, needScientist = 1;
    var needAllMax = needFarmer + needLumber + needMiner + needScientist;

    var _buyJobs = function ($obj, unemployed, objName, jobId) {
        if ($obj.length > 0) {
            var breeding = _getBreeding();
            var cnt = 1;
            var minBreeding = _getMinimumBreeding();
            if (unemployed > needAllMax * 1000000000 && (breeding - 10000000000 > minBreeding)) {
                game.global.buyAmt = 10000000000;
                cnt = 10000000000;
            }
            else if (unemployed > needAllMax * 100000000 && (breeding - 1000000000 > minBreeding)) {
                game.global.buyAmt = 1000000000;
                cnt = 1000000000;
            }
            else if (unemployed > needAllMax * 10000000 && (breeding - 100000000 > minBreeding)) {
                game.global.buyAmt = 100000000;
                cnt = 100000000;
            }
            else if (unemployed > needAllMax * 1000000 && (breeding - 10000000 > minBreeding)) {
                game.global.buyAmt = 10000000;
                cnt = 10000000;
            }
            else if (unemployed > needAllMax * 100000 && (breeding - 1000000 > minBreeding)) {
                game.global.buyAmt = 1000000;
                cnt = 1000000;
            }
            else if (unemployed > needAllMax * 10000 && (breeding - 100000 > minBreeding)) {
                game.global.buyAmt = 100000;
                cnt = 100000;
            }
            else if (unemployed > needAllMax * 1000 && (breeding - 10000 > minBreeding)) {
                game.global.buyAmt = 10000;
                cnt = 10000;
            }
            else if (unemployed > needAllMax * 100 && (breeding - 1000 > minBreeding)) {
                game.global.buyAmt = 1000;
                cnt = 1000;
            }
            else if (unemployed > needAllMax * 10 && (breeding - 100 > minBreeding)) {
                numTab(4);
                cnt = 100;
            }
            else if (unemployed > needAllMax * 2.5 && (breeding - 25 > minBreeding)) {
                numTab(3);
                cnt = 25;
            }
            else if (unemployed > needAllMax && (breeding - 10 > minBreeding)) {
                numTab(2);
                cnt = 10;
            }
            else {
                numTab(1);
                cnt = 1;
            }
            buyJob(jobId, true, true); // confirmed, noTip
            numTab(1); // +1
            _log('New ' + objName + (cnt > 1 ? " x" + cnt : ''), 'Combat');
            return cnt;
        } else {
            return 0;
        }
    };

    var _getJobsNeededCounts = function () {
        var maxTrimps = game.resources.trimps.realMax();
        var unemployed = Math.ceil(maxTrimps / 2) - game.resources.trimps.employed;
        var jobsTotal =
            unemployed +
            game.jobs.Farmer.owned +
            game.jobs.Lumberjack.owned +
            game.jobs.Miner.owned +
            game.jobs.Scientist.owned;
        var hasFarmer = game.jobs.Farmer.locked === 0;
        var hasLumber = game.jobs.Lumberjack.locked === 0;
        var hasMiner = game.jobs.Miner.locked === 0;
        var hasScientist = game.jobs.Scientist.locked === 0;
        var needAll =
            (hasFarmer ? needFarmer : 0) +
            (hasLumber ? needLumber : 0) +
            (hasMiner ? needMiner : 0) +
            (hasScientist ? needScientist : 0);
        if (needAll < 1) needAll = 1;
        var minOwned = Math.min(
            game.jobs.Farmer.owned,
            game.jobs.Lumberjack.owned,
            game.jobs.Miner.owned,
            Math.floor(jobsTotal * 0.25)
            );
        if (minOwned > 30) minOwned = 30; // for science
        var jobsWithoutScientists = jobsTotal - minOwned;

        return {
            Scientist: needScientist ? minOwned : -1,
            Farmer: needFarmer ? Math.floor(jobsWithoutScientists * needFarmer / needAll) : -1,
            Lumberjack: needLumber ? Math.floor(jobsWithoutScientists * needLumber / needAll) : -1,
            Miner: needMiner ? Math.floor(jobsWithoutScientists * needMiner / needAll) : -1
        };
    };

    var _autoJobs = function () {
        var breeding = game.resources.trimps.owned - game.resources.trimps.employed;
        if (breeding < (_getMinimumBreeding() + 1) && game.global.challengeActive !== 'Trapper') return;

        var maxTrimps = game.resources.trimps.realMax();
        var unemployed = Math.ceil(maxTrimps / 2) - game.resources.trimps.employed;

        var trainerCost = _getJobPrice('Trainer', 'food');
        if ((trainerCost < game.resources.food.owned) && unemployed <= 0 && game.jobs.Farmer.owned > 1 && game.jobs.Trainer.locked === 0) {
            _log('Fire farmer, sorry');
            game.global.firing = true;
            buyJob('Farmer', true, true);
            game.global.firing = false;
        }

        if (unemployed <= 0) return;

        if (trainerCost <= game.resources.food.owned && game.jobs.Trainer.locked === 0) {
            buyJob('Trainer', true, true);
            _log('New trainer');
            return 1;
        }

        if (game.jobs.Geneticist.locked === 0 && _getBreedingTotalSpeed() > maxTrimps * 2) {
            buyJob('Geneticist', true, true);
            _log('New geneticist');
            return 1;
        }

        var cnt = 0;
        var $jobsBlock = $('#jobsHere');

        var $explorer = $jobsBlock.find('.thingColorCanAfford[id=Explorer]');
        if ($explorer.length > 0) {
            buyJob('Explorer', true, true);
            _log('New explorer');
            return ++cnt;
        }

        var $farmer = $jobsBlock.find('.thingColorCanAfford[id=Farmer]');

        var toHire = _getJobsNeededCounts();

        if (toHire.Farmer > 0 && game.jobs.Farmer.owned < toHire.Farmer) {
            cnt += _buyJobs($farmer, unemployed, 'farmer', 'Farmer');
        } else if (toHire.Lumberjack > 0 && game.jobs.Lumberjack.owned < toHire.Lumberjack) {
            var $lumber = $jobsBlock.find('.thingColorCanAfford[id=Lumberjack]');
            cnt += _buyJobs($lumber, unemployed, 'lumberjack', 'Lumberjack');
        } else if (toHire.Miner > 0 && game.jobs.Miner.owned < toHire.Miner) {
            var $miner = $jobsBlock.find('.thingColorCanAfford[id=Miner]');
            cnt += _buyJobs($miner, unemployed, 'miner', 'Miner');
        } else if (toHire.Scientist > 0 && game.jobs.Scientist.owned < toHire.Scientist) {
            var $science = $jobsBlock.find('.thingColorCanAfford[id=Scientist]');
            cnt += _buyJobs($science, unemployed, 'scientist', 'Scientist');
        }

        if (unemployed > 0 && cnt === 0) {
            cnt += _buyJobs($farmer, unemployed, 'farmer', 'Farmer');
        }

        return cnt;
    };

    var _styleUpdate = function () {
        // remove counts
        //noinspection CssUnusedSymbol
        $('head').append($("<style type=\"text/css\">\n" +
            "span.thingName{font-size:85%;}\n"+
            ".queueItem,.btn{padding:0}\n" +
            ".thingColorCanNotAfford.upgradeThing{background-color:#530053;}\n" +
            "#battleSideTitle{padding:0}\n" +
            ".battleSideBtnContainer{margin-top:0;}\n" +
            "#logBtnGroup{display:none}\n" +
            "#log{height:100%;}\n" +
            ".glyphicon-apple{color:orangered;}\n" +
            ".glyphicon-tree-deciduous{color:limegreen;}\n"+
            ".icomoon.icon-cubes{color:silver;}\n"+
            ".icomoon.icon-diamond{color:white;}\n"+
            "#buildingsTitleDiv,#upgradesTitleDiv,#equipmentTitleDiv{display:none}\n"+
            "#buildingsQueue{height:30px}\n"+
            "#buyHere .alert.badge{display:none}\n"+
            '</style>'));

        // remove tabs
        $('#buyTabs').hide();
        filterTabs('all');
        // fix height
        $('#topRow,#queueContainer').css('margin-bottom', '0');
        $('#jobsTitleDiv').css('padding', '0').css('font-size', 'smaller');
        $('#buyHere').css('margin', '0').css('padding', '0').css('overflow-x', 'hidden');
        $('#queueContainer').css('height', '70px');
        $('#numTabs').css('margin', '0');
        $('#buyContainer').css('height', 'calc(99vh - 20vw - 96px)');
        // add button
        $('#settingsTable').find('tr').append('<td class="btn btn-info" id="botStart" title="' + version + '">Bot start</td>');
        $('#botStart').on('click', _onStartButton);
        // add grid
        var $grid = $('<table style="width:100%;margin-top:4px;font-size:smaller;"><tr>' +
            '<td id="magnimp-cell"><span class="glyphicon glyphicon-magnet"></span><label style="margin-left:4px" title="Magimp">...</label></td>' +
            '<td id="venimp-cell"><span class="glyphicon glyphicon-glass"></span><label style="margin-left:4px" title="Venimp">...</label></td>' +
            '</tr><tr>' +
            '<td id="whipimp-cell"><span class="glyphicon glyphicon-star"></span><label style="margin-left:4px" title="Whipimp">...</label></td>' +
            '<td id="titimp-cell"><span class="icomoon icon-hammer"></span><label style="margin-left:4px" title="Titimp">' + prettify(game.global.titimpLeft) + '</label></td>' +
            '</tr></table>');
        $('#battleBtnsColumn').append($grid);
        _updateSuperTrimps();
    };

    var _styleFix = function () {
        _disableLog();

        var $buyBoxThings = $('.buyBox').find('.thing');
        $buyBoxThings.find('br').remove();
        $buyBoxThings.find('.thingOwned').css('margin-left', '4px');

        /*for (var x in game.upgrades) {
            if (game.upgrades.hasOwnProperty(x)) {
                if (game.upgrades[x].alert && game.upgrades[x].locked === 0) game.upgrades[x].alert = false;
            }
        }
        for (x in game.buildings) {
            if (game.buildings.hasOwnProperty(x)) {
                if (game.buildings[x].alert && game.buildings[x].locked === 0) game.buildings[x].alert = false;
            }
        }
        for (x in game.jobs) {
            if (game.jobs.hasOwnProperty(x)) {
                if (game.jobs[x].alert && game.jobs[x].locked === 0) game.jobs[x].alert = false;
            }
        }*/

        $('#buildingsTitleDiv,#upgradesTitleDiv,#equipmentTitleDiv').css('display', 'none');

        if (typeof game.passedMaps === 'undefined') game.passedMaps = {};
        if (typeof game.mapsAttacked === 'undefined') game.mapsAttacked = {};

        for (var x in game.passedMaps) if (x > game.global.world) {
            // Game restart?
            game.passedMaps = {};
            game.mapsAttacked = {};
            $('#venimp-cell').find('label').text('...');
            $('#magnimp-cell').find('label').text('...');
            $('#whipimp-cell').find('label').text('...');
            break;
        }

        var hasItem = false;
        if (typeof game.mapUnlocks === 'undefined') {
            clearInterval(tStyleFix);
            tStyleFix = setInterval(_styleFix, 2000);
        } else {
            for (x in game.mapUnlocks) {
                if (game.mapUnlocks.hasOwnProperty(x)) {
                    var notPass = game.mapUnlocks[x].startAt <= game.global.world && (typeof game.passedMaps[game.mapUnlocks[x].startAt] === 'undefined' || game.passedMaps[game.mapUnlocks[x].startAt] < 1);
                    if (notPass) {
                        $('#battleSideTitle').css('background-color', notPass ? '#A00' : '#600');
                        hasItem = true;
                        break;
                    }
                }
            }
        }
        if (!hasItem) {
            $('#battleSideTitle').css('background-color', 'transparent');
        }
        game.passedMaps[game.global.world] = game.global.mapBonus;
        if (game.global.mapBonus > 0) {
            for (x in game.mapUnlocks) {
                if (game.mapUnlocks.hasOwnProperty(x)) {
                    if (game.mapUnlocks[x].startAt < game.global.world) {
                        game.passedMaps[game.mapUnlocks[x].startAt] = 1;
                    }
                }
            }
        }
    };

    var _start = function () {
        _log('Passive watcher stop');
        clearInterval(tPassiveWatcher);

        _log('BOT start version ' + version);
        tAutoBuy = setInterval(_auto, 1000);

        $('#botStart').text('Bot stop');
    };

    var _stop = function () {
        _log('BOT stop');
        clearInterval(tAutoBuy);

        tPassiveWatcher = setInterval(_passiveWatcher, 1000);
        _log('Passive watcher started');

        $('#botStart').text('Bot start');
    };

    var logEnabled = true, tTitimp;

    var _updateSuperTrimps = function () {
        var whipStrength = Math.pow(1.003, game.unlocks.impCount.Whipimp);
        whipStrength = prettify((whipStrength - 1) * 100) + "%";
        var magimpStrength = Math.pow(1.003, game.unlocks.impCount.Magnimp);
        magimpStrength = prettify((magimpStrength - 1) * 100) + "%";
        var venimpStrength = Math.pow(1.003, game.unlocks.impCount.Venimp);
        venimpStrength = prettify((venimpStrength - 1) * 100) + "%";

        var mag = $('#magnimp-cell').find('label');
        if (mag.text() !== magimpStrength) mag.text(magimpStrength);
        var whip = $('#whipimp-cell').find('label');
        if (whip.text() !== whipStrength) whip.text(whipStrength);
        var ven = $('#venimp-cell').find('label');
        if (ven.text() !== venimpStrength) ven.text(venimpStrength);
    };

    var _disableLog = function () {
        if (logEnabled) {
            message = function (messageString, type, lootIcon, extraClass, extraTag, htmlPrefix) {
                if (type === 'Loot' && lootIcon === null) return;
                if (type === 'Combat' && (lootIcon === null || typeof lootIcon === 'undefined')) return;
                if (type === 'Loot' &&
                    (messageString.indexOf('You just found') > -1 ||
                        messageString.indexOf('You found') > -1 ||
                        messageString.indexOf('That guy just left') > -1 ||
                        (messageString.indexOf(' dropped ') > -1 && messageString.indexOf('That ') > -1) ||
                        messageString.indexOf(' manage to ') > -1 ||
                        messageString.indexOf('Then he died') > -1 ||
                        messageString.indexOf(' popped out!') > -1 ||
                        messageString.indexOf('That Feyimp gave you') > -1 ||
                        messageString.indexOf('in that dead Tauntimp') > -1 ||
                        messageString.indexOf('fragments from that Flutimp') > -1 ||
                        messageString.indexOf('That Jestimp gave you') > -1 ||
                        messageString.indexOf('That Titimp made your Trimps super strong') > -1 ||
                        messageString.indexOf('You scored ') > -1 ||
                        messageString.indexOf('Hulking Mutimp ') > -1 ||
                        messageString.indexOf('Cubist art is your favorite!') > -1 ||
                        messageString.indexOf('Reward encountered: ') > -1 ||
                        messageString.indexOf('Findings: ') > -1 ||
                        messageString.indexOf('Salvage results: ') > -1 ||
                        messageString.indexOf('You hear nearby Kittimps ') > -1
                    )) return;
                if (type === 'Story' && typeof lootIcon === 'undefined' &&
                    messageString.indexOf('BOT: New ') > -1) return;
                var showTimestamps = parseInt(game.options.menu.timestamps.enabled) === 1;
                if (type === 'Notices' && messageString === 'Game Saved!') {
                    var t = showTimestamps ? getCurrentTime() : updatePortalTimer(true);
                    $('#saveIndicator').find('.autosaving').text(t);
                    return;
                }
                if (messageString.indexOf('The ground up Venimp now increases your Trimps') > -1) {
                    _updateSuperTrimps();
                    return;
                }
                if (messageString.indexOf('You killed a Magnimp! The strong magnetic forces now increase your loot by') > -1) {
                    _updateSuperTrimps();
                    return;
                }
                if (messageString.indexOf('Seeing the Whipimps fall is causing all of your Trimps to work') > -1) {
                    _updateSuperTrimps();
                    return;
                }

                var log = document.getElementById("log");
                var displayType = "block";
                var prefix = "";
                var addId = "";
                if (messageString === "Game Saved!" || extraClass === 'save') {
                    addId = " id='saveGame'";
                    if (document.getElementById('saveGame') !== null) {
                        log.removeChild(document.getElementById('saveGame'));
                    }
                }
                if (game.options.menu.timestamps.enabled) {
                    messageString = (showTimestamps ? getCurrentTime() : updatePortalTimer(true)) + " " + messageString;
                }
                if (!htmlPrefix) {
                    if (lootIcon && lootIcon.charAt(0) === "*") {
                        lootIcon = lootIcon.replace("*", "");
                        prefix = "icomoon icon-";
                    }
                    else prefix = "glyphicon glyphicon-";
                    if (type === "Story") messageString = "<span class='glyphicon glyphicon-star'></span> " + messageString;
                    if (type === "Combat") messageString = "<span class='glyphicon glyphicon-flag'></span> " + messageString;
                    if (type === "Loot" && lootIcon) messageString = "<span class='" + prefix + lootIcon + "'></span> " + messageString;
                    if (type === "Notices") {
                        messageString = "<span class='glyphicon glyphicon-off'></span> " + messageString;
                    }
                } else {
                    messageString = htmlPrefix + " " + messageString;
                }
                var messageHTML = "<span" + addId + " class='" + type + "Message message" + " " + extraClass + "' style='display: " + displayType + "'>" + messageString + "</span>";
                pendingLogs.all.push(messageHTML);
                postMessages();

                var $allLogs = $('#log').find('span');
                $allLogs.slice(0, -30).remove();
            };
            logEnabled = false;
        }
    };

    var _titimpUpdate = function () {
        $('#titimp-cell').find('label').text(prettify(game.global.titimpLeft > 0 ? game.global.titimpLeft : 0));
    };

    setTimeout(function () {
        _log('Trimps BOT version ' + version);

        tStyleFix = setInterval(_styleFix, 2000);
        tTitimp = setInterval(_titimpUpdate, 500);

        _styleUpdate();
        _styleFix();

        if (typeof  game.TT === 'undefined') {
            game.TT = {};
            game.TT.getJobsNeededCounts = _getJobsNeededCounts;
            game.TT.hasUpgradeForEquipment = _hasUpgradeForEquipment;
            game.TT.hasMapOfCurrentLevel = _hasMapOfCurrentLevel;
            game.TT.needAttackCurrentMap = _needAttackCurrentMap;
            game.TT.getAllUpgradePrice = _getAllUpgradePrice;
            game.TT.getUpgradePriceSumForRes = _getUpgradePriceSumForRes;
        }

        _disableLog();

        _stop(); // start passive watcher
    }, 1000);

})();