KittenManager

Manage resources in bloodrizer's kittens game.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         KittenManager
// @namespace    http://inithello.net/
// @version      1.1
// @description  Manage resources in bloodrizer's kittens game.
// @author       InitHello
// @license      CC-BY-NC-SA-4.0
// @supportURL   https://github.com/InitHello/greasemonkey/issues
// @match        http://bloodrizer.ru/games/kittens/
// @require      https://code.jquery.com/jquery-3.3.1.min.js#sha256=FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=
// @grant        none
// ==/UserScript==
/* jshint esversion: 6 */

class KittenManagement {
    constructor() {
        this.resources = {};
        this.capless_resources = ['hunters', 'astronomers', 'log', 'furs']
        this.managed_resources = ['faith', 'science', 'culture', 'catnip', 'wood', 'minerals', 'coal', 'iron'];
        this.loadConfig();
        window.setTimeout(this.mainTick.bind(null, this), 2500);
    }

    checkResources() {
        let products = {catnip: ['wood'],
                        wood: ['beam'],
                        minerals: ['slab'],
                        iron: ['steel', 'plate'],
                        coal: ['steel'],
                        culture: ['manuscript'],
                        science: ['compendium', 'blueprint']};
        for (let resource in products) {
            let over = this.overThreshold(resource);
            if (over) {
                try {
                    var resname = products[resource];
                    this.game.craft(game.resPool.get(resname).name, 1);
                }
                catch (err) {
                    console.log(`Error crafting ${resname} (${typeof(resname)}): ${err}`);
                }
            }
        }
        try {
            let furs = this.game.resPool.get('furs');
            if (furs.value >= 175 && this.config.resource_management.furs.manage) {
                this.game.craft(game.resPool.get('parchment').name, 1);
            }
        }
        catch (err) {
            console.log(`Error checking furs: ${err}`);
        }
        let faith = this.game.resPool.get('faith');
        let faithcap = faith.maxValue * 0.95;
        if (faith.value >= faithcap) {
            this.game.religion.praise();
        }
    }

    getCap(resource) {
        let threshold = 1000;
        try {
            threshold = this.config.resource_management[resource.name].threshold;
        }
        catch (err) {
            console.log(`Error getting cap for ${resource}: ${err}`);
        }
        return threshold == 0 ? 0 : threshold / 100;
    }

    initialStartup() {
        let tab = ['<span> | </span>',
                   '<a href="#" id="KittenManager" class="tab" style="white-space: nowrap;">Tools</a>'].join('');
        let tabRow = $('#gameContainerId').find('div.tabsContainer');
        tabRow.append($(tab));
        $('#KittenManager').on('click', () => {
            this.showConfig();
        });
        let css = $(['<style type="text/css">',
                     '#custom-handle { width: 3em; height: 1.6em; top: 50%; margin-top: -.8em; text-align: center; line-height: 1.6em; }',
                     '.resourcecap { width: 2em; height: 12px; border: none; }',
                     '.management-tools { padding-left: 2px; float: right; cursor: pointer; }',
                     '</style>'].join(''));
        $(document.body).append(css);
    }

    loadConfig() {
        if (localStorage.getItem('KittenManager') !== null) {
            this.config = JSON.parse(localStorage.getItem('KittenManager'));
        }
        else {
            this.config = {logLevel: 0, resource_management: {}};
            for (let resource in this.capless_resources) {
                this.config.resource_management[this.capless_resources[resource]] = {manage: false};
            }
            for (let resource in this.managed_resources) {
                this.config.resource_management[this.managed_resources[resource]] = {manage: false, threshold: 80};
            }
            this.saveConfig();
        }
    }

    mainTick(self) {
        self.game = window.game;
        let child = $('#KittenManager');
        if (!child.length) {
            self.initialStartup();
        }
        let controller = $('#KittenManager');
        let hunters = self.config.resource_management.hunters.manage;
        let astro = self.config.resource_management.astronomers.manage;
        let log = self.config.resource_management.log.manage;
        self.checkResources();
        if (hunters && self.game.resPool.get('manpower').value >= 100) {
            self.game.village.huntAll();
        }
        if (astro && self.game.calendar.observeRemainingTime && !game.workshop.get("seti").researched) {
            self.game.calendar.observeHandler();
        }
        if (log) {
            $('#clearLogHref').click();
        }
        window.setTimeout(self.mainTick.bind(null, self), self.config.heartbeat);
    }

    managing(resource) {
        if (!this.config.resource_management.hasOwnProperty(resource.name)) {
            this.config.resource_management[resource.name] = {manage: false, threshold: 80};
            this.saveConfig();
        }
        return this.config.resource_management[resource.name].manage;
    }

    overThreshold(material) {
        let resource = this.game.resPool.get(material);
        let adj = 0;
        if (!this.managing(resource)) {
            return false;
        }
        let cap = this.getCap(resource);
        try {
            adj = resource.maxValue * cap;
        }
        catch (err) {
            console.log(`Error checking cap for ${resource.name}: ${err}`);
            return false;
        }
        if (resource.value >= adj) {
            return true;
        }
        return false
    }

    saveConfig() {
        localStorage.removeItem('KittenManager');
        localStorage.setItem('KittenManager', JSON.stringify(this.config));
    }

    setCap(resource, cap) {
        if (this.config.resource_management.hasOwnProperty(resource)) {
            if (this.config.resource_management[resource].hasOwnProperty('threshold')) {
                this.config.resource_management[resource].threshold = cap;
                this.saveConfig();
            }
            else {
                this.config.resource_management[resource] = {manage: false, threshold: cap};
            }
        }
    }

    showConfig() {
        let tab_contents = ['<div class="bldGroupContainer">'];
        $('.tab').removeClass('activeTab');
        $('#KittenManager').addClass('activeTab');
        for (let idx in this.capless_resources) {
            let resource = this.capless_resources[idx];
            if (this.config.resource_management.hasOwnProperty(resource)) {
                let enabled = this.config.resource_management[resource].manage ? 'on' : 'off';
                let chtclass = this.config.resource_management[resource].manage ? ' bldEnabled' : '';
                let label = resource[0].toUpperCase() + resource.slice(1);
                tab_contents = tab_contents.concat([
                         `<div id="cht-${resource}" class="btn nosel modern${chtclass}" style="position: relative; display: block; margin-left: auto; margin-right: auto;">`,
                         `<div class="btnContent" title=""><span>${label}</span>`,
                         '<span class="linkBreak" style="float: right; padding-left: 2px; margin-right: 1px;">|</span>',
                         `<a href="#" class="management-tools" data-item="${resource}" style="" title="Active">${enabled}</a>`,
                         '<span class="linkBreak" style="float: right; padding-left: 2px;">|</span></div></div>']);
            }
        }

        for (let idx in this.managed_resources) {
            let resource = this.managed_resources[idx];
            if (this.config.resource_management.hasOwnProperty(resource)) {
                let enabled = this.config.resource_management[resource].manage ? 'on' : 'off';
                let chtclass = this.config.resource_management[resource].manage ? ' bldEnabled' : '';
                let label = resource[0].toUpperCase() + resource.slice(1);
                let cap = this.config.resource_management[resource].threshold;
                tab_contents = tab_contents.concat([
                         `<div id="cht-${resource}" class="btn nosel modern${chtclass}" style="position: relative; display: block; margin-left: auto; margin-right: auto;">`,
                         `<div class="btnContent" title=""><span>${label}</span>`,
                         '<span class="linkBreak" style="float: right; padding-left: 2px; margin-right: 1px;">|</span>',
                         `<div style="float: right;"><input type="text" id="cap_${resource}" class="resourcecap" data-resource="${resource}" value="${cap}" /></div>`,
                         '<span class="linkBreak" style="float: right; padding-left: 2px; margin-right: 1px;">|</span>',
                         `<a href="#" class="management-tools" data-item="${resource}" style="" title="Active">${enabled}</a>`,
                         '<span class="linkBreak" style="float: right; padding-left: 2px;">|</span></div></div>']);
            }
        }
        tab_contents.push('</div>');
        let elm = $(tab_contents.join(''));
        let tabContents = $('#gameContainerId').find('div.tabInner');
        tabContents.html(elm);
        $('.resourcecap').on('change', ev => {
            let elm = $(ev.currentTarget);
            let item = elm.attr('data-resource');
            let newvalue = parseInt(elm.val());
            this.setCap(item, newvalue);
        });
        $('.management-tools').on('click', (ev) => {
            let elm = $(ev.currentTarget);
            let item = elm.attr('data-item');
            let isactive = this.config.resource_management[item];
            if (isactive.manage) {
                $('#cht-' + item).removeClass('bldEnabled');
                isactive.manage = false;
                this.config.resource_management[item] = isactive;
                this.saveConfig();
                elm.html('off')
            }
            else {
                $('#cht-' + item).addClass('bldEnabled');
                isactive.manage = true;
                this.config.resource_management[item] = isactive;
                this.saveConfig();
                elm.html('on')
            }
        });
    }
}


let $ = window.jQuery;


$(function() {
    'use strict';
    const kittenManagement = new KittenManagement();
});