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