Automate KG as minimally as possible
This commit is contained in:
parent
d73d718832
commit
91f9641665
|
@ -0,0 +1,221 @@
|
||||||
|
// ==UserScript==
|
||||||
|
// @name Furball
|
||||||
|
// @namespace https://spookyinternet.com/
|
||||||
|
// @version 0.1
|
||||||
|
// @description Kitten Game Automation. Sometimes clicking is hard.
|
||||||
|
// @author uplime
|
||||||
|
// @match https://kittensgame.com/web/*
|
||||||
|
// @grant unsafeWindow
|
||||||
|
// @grant GM.setValue
|
||||||
|
// @grant GM.getValue
|
||||||
|
// @grant GM.listValues
|
||||||
|
// ==/UserScript==
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There comes an end to all things; the most capacious measure is filled at
|
||||||
|
* last; and this brief condescension to evil finally destroyed the balance of
|
||||||
|
* my soul.
|
||||||
|
*
|
||||||
|
* - Dr. Jekyll
|
||||||
|
*/
|
||||||
|
|
||||||
|
(async function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public API stub.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const furball = { conf: { } };
|
||||||
|
unsafeWindow.furball = furball;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Boilerplate stubs for automating the game.
|
||||||
|
*/
|
||||||
|
|
||||||
|
let game = undefined;
|
||||||
|
const defer = { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const seconds = (amt) => amt * 1000;
|
||||||
|
const minutes = (amt) => seconds(amt * 60);
|
||||||
|
const hours = (amt) => minutes(amt * 60);
|
||||||
|
const days = (amt) => hours(amt * 24);
|
||||||
|
|
||||||
|
const log_msg = (msg) => {
|
||||||
|
const node = game.msg(`✨furball✨ ${msg}`);
|
||||||
|
node.span.style.color = "rgb(66, 227, 93)";
|
||||||
|
};
|
||||||
|
|
||||||
|
const should_run = (feat) => furball.conf[feat].enable && !game.isPaused;
|
||||||
|
|
||||||
|
const total_crafted = (res, amt) => amt * (1 + game.getResCraftRatio(res));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public API for controlling automation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
furball.set = (feat, key, val, ow=true) => {
|
||||||
|
if(furball.conf[feat] === undefined) {
|
||||||
|
furball.conf[feat] = { };
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ow || furball.conf[feat][key] === undefined) {
|
||||||
|
furball.conf[feat][key] = val;
|
||||||
|
GM.setValue(`furball.${feat}.${key}`, val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
furball.get = (feat, key, val=undefined) => {
|
||||||
|
if(furball.conf[feat] === undefined || furball.conf[feat][key] === undefined) {
|
||||||
|
return val;
|
||||||
|
} else {
|
||||||
|
return furball.conf[feat][key];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
furball.toggle = (feat, enable=true, ow=true) => {
|
||||||
|
furball.set(feat, "enable", enable, ow);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Neighborhood Skywatch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
defer.skywatch = () => {
|
||||||
|
furball.toggle("skywatch", true, false);
|
||||||
|
|
||||||
|
const skywatcher = new MutationObserver((muts, watcher) => {
|
||||||
|
if(should_run("skywatch") && muts[0].addedNodes.length > 0) {
|
||||||
|
muts[0].addedNodes[0].click();
|
||||||
|
log_msg("did a watch on the sky");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const sky = document.getElementById("observeButton");
|
||||||
|
|
||||||
|
if(sky !== null) {
|
||||||
|
skywatcher.observe(sky, {
|
||||||
|
childList: true, attributes: true, subtree: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Craft simple resources.
|
||||||
|
*/
|
||||||
|
|
||||||
|
defer.easybake = () => {
|
||||||
|
furball.toggle("easybake", true, false);
|
||||||
|
furball.set("easybake", "time", minutes(3), false);
|
||||||
|
furball.set("easybake", "amt", 10, false);
|
||||||
|
|
||||||
|
[ "beam", "slab", "plate", "steel" ].forEach((name) => {
|
||||||
|
const res = game.resPool.get(name);
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
if(should_run("easybake") && res.unlocked) {
|
||||||
|
game.craft(name, furball.conf.easybake.amt);
|
||||||
|
const total = total_crafted(name, furball.conf.easybake.amt);
|
||||||
|
log_msg(`crafted ${game.getDisplayValueExt(total, true)} ${name}`);
|
||||||
|
}
|
||||||
|
}, furball.conf.easybake.time);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Craft advanced resources.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// make sure parchment is handled
|
||||||
|
// manuscripts, compendium
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Download saves automagically.
|
||||||
|
*/
|
||||||
|
|
||||||
|
defer.lifesaver = () => {
|
||||||
|
furball.toggle("lifesaver", true, false);
|
||||||
|
furball.set("lifesaver", "time", hours(1), false);
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
if(should_run("lifesaver")) {
|
||||||
|
game.saveToFile(true);
|
||||||
|
log_msg("saved right before the boss fight");
|
||||||
|
}
|
||||||
|
}, furball.conf.lifesaver.time);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Praise the sun! \o/
|
||||||
|
*/
|
||||||
|
|
||||||
|
defer.faithfull = () => {
|
||||||
|
furball.toggle("faithfull", true, false);
|
||||||
|
furball.set("faithfull", "time", hours(2) + minutes(30), false);
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
if(should_run("faithfull")) {
|
||||||
|
game.religion.praise();
|
||||||
|
log_msg("Praise the sun \\o/");
|
||||||
|
}
|
||||||
|
}, furball.conf.faithfull.time);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trader Joe has the best deals around.
|
||||||
|
*/
|
||||||
|
|
||||||
|
defer.joe = () => {
|
||||||
|
furball.toggle("joe", true, false);
|
||||||
|
furball.set("joe", "time", minutes(5), false);
|
||||||
|
furball.set("joe", "amt", 5);
|
||||||
|
|
||||||
|
const races = game.diplomacy.races;
|
||||||
|
let idx = 0;
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
const race = races[idx];
|
||||||
|
|
||||||
|
if(should_run("joe") && race.unlocked) {
|
||||||
|
game.diplomacy.tradeMultiple(race, furball.conf.joe.amt);
|
||||||
|
log_msg(`did a trade with ${race.name} ${furball.conf.joe.amt} times`);
|
||||||
|
game.village.huntAll();
|
||||||
|
log_msg("hunted all the things on the way back");
|
||||||
|
|
||||||
|
if(idx === races.length - 1) {
|
||||||
|
idx = 0;
|
||||||
|
} else {
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, furball.conf.joe.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Driver for loading furball on ready.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const gm_keys = await GM.listValues();
|
||||||
|
|
||||||
|
await gm_keys.forEach(async (gm_key) => {
|
||||||
|
const val = await GM.getValue(gm_key);
|
||||||
|
const keys = gm_key.split(".");
|
||||||
|
furball.conf[keys[1]] = { };
|
||||||
|
furball.conf[keys[1]][keys[2]] = val;
|
||||||
|
});
|
||||||
|
|
||||||
|
const game_tmr = setInterval(() => {
|
||||||
|
if(unsafeWindow.gamePage !== undefined) {
|
||||||
|
clearInterval(game_tmr);
|
||||||
|
game = unsafeWindow.gamePage;
|
||||||
|
|
||||||
|
Object.keys(defer).forEach((entry) =>
|
||||||
|
defer[entry]()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, seconds(1));
|
||||||
|
})();
|
Loading…
Reference in New Issue