Automate KG as minimally as possible

This commit is contained in:
Nick Chambers 2022-05-16 17:22:01 -05:00
parent d73d718832
commit 91f9641665
1 changed files with 221 additions and 0 deletions

221
www/furball.js Normal file
View File

@ -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));
})();