pages/kronos/js/game.js

538 lines
14 KiB
JavaScript

let player;
let needCanvasUpdate = true;
let gameEnded = false;
// Don't change this
const TMT_VERSION = {
tmtNum: "2.5.9.2",
tmtName: "Dreams Really Do Come True"
}
function getResetGain(layer, useType = null) {
let type = useType;
if (!useType) {
type = tmp[layer].type;
if (layers[layer].getResetGain !== undefined) {
return layers[layer].getResetGain();
}
}
if (tmp[layer].type === "none") {
return decimalZero;
}
if (tmp[layer].gainExp.eq(0)) {
return decimalZero;
}
if (type === "static") {
if ((!tmp[layer].canBuyMax) || tmp[layer].baseAmount.lt(tmp[layer].requires)) {
return decimalOne;
}
let gain = tmp[layer].baseAmount.div(tmp[layer].requires).div(tmp[layer].gainMult).max(1).log(tmp[layer].base).times(tmp[layer].gainExp).pow(Decimal.pow(tmp[layer].exponent, -1));
gain = gain.times(tmp[layer].directMult);
return gain.floor().sub(player[layer].points).add(1).max(1);
} else if (type === "normal") {
if (tmp[layer].baseAmount.lt(tmp[layer].requires)) {
return decimalZero;
}
let gain = tmp[layer].baseAmount.div(tmp[layer].requires).pow(tmp[layer].exponent).times(tmp[layer].gainMult).pow(tmp[layer].gainExp);
if (gain.gte(tmp[layer].softcap)) {
gain = gain.pow(tmp[layer].softcapPower).times(tmp[layer].softcap.pow(decimalOne.sub(tmp[layer].softcapPower)));
}
gain = gain.times(tmp[layer].directMult);
return gain.floor().max(0);
} else if (type === "custom") {
return layers[layer].getResetGain();
} else {
return decimalZero;
}
}
function getNextAt(layer, canMax = false, useType = null) {
let type = useType;
if (!useType) {
type = tmp[layer].type;
if (layers[layer].getNextAt !== undefined) {
return layers[layer].getNextAt(canMax);
}
}
if (tmp[layer].type === "none") {
return new Decimal(Infinity);
}
if (tmp[layer].gainMult.lte(0)) {
return new Decimal(Infinity);
}
if (tmp[layer].gainExp.lte(0)) {
return new Decimal(Infinity);
}
if (type === "static") {
if (!tmp[layer].canBuyMax) {
canMax = false;
}
let amt = player[layer].points.plus((canMax && tmp[layer].baseAmount.gte(tmp[layer].nextAt)) ? tmp[layer].resetGain : 0).div(tmp[layer].directMult);
let extraCost = Decimal.pow(tmp[layer].base, amt.pow(tmp[layer].exponent).div(tmp[layer].gainExp)).times(tmp[layer].gainMult);
let cost = extraCost.times(tmp[layer].requires).max(tmp[layer].requires);
if (tmp[layer].roundUpCost) {
cost = cost.ceil();
}
return cost;
} else if (type === "normal") {
let next = tmp[layer].resetGain.add(1).div(tmp[layer].directMult);
if (next.gte(tmp[layer].softcap)) {
next = next.div(tmp[layer].softcap.pow(decimalOne.sub(tmp[layer].softcapPower))).pow(decimalOne.div(tmp[layer].softcapPower));
}
next = next.root(tmp[layer].gainExp).div(tmp[layer].gainMult).root(tmp[layer].exponent).times(tmp[layer].requires).max(tmp[layer].requires);
if (tmp[layer].roundUpCost) {
next = next.ceil();
}
return next;
} else if (type === "custom") {
return layers[layer].getNextAt(canMax);
} else {
return decimalZero;
}
}
function softcap(value, cap, power = 0.5) {
if (value.lte(cap)) {
return value;
} else {
return value.pow(power).times(cap.pow(decimalOne.sub(power)));
}
}
// Return true if the layer should be highlighted. By default checks for upgrades only.
function shouldNotify(layer) {
for (let id in tmp[layer].upgrades) {
if (isPlainObject(layers[layer].upgrades[id])) {
if (canAffordUpgrade(layer, id) && !hasUpgrade(layer, id) && tmp[layer].upgrades[id].unlocked) {
return true;
}
}
}
if (player[layer].activeChallenge && canCompleteChallenge(layer, player[layer].activeChallenge)) {
return true;
}
if (tmp[layer].shouldNotify)
return true
if (isPlainObject(tmp[layer].tabFormat)) {
for (let subtab in tmp[layer].tabFormat) {
if (subtabShouldNotify(layer, "mainTabs", subtab)) {
tmp[layer].trueGlowColor = tmp[layer].tabFormat[subtab].glowColor
return true;
}
}
}
for (let family in tmp[layer].microtabs) {
for (let subtab in tmp[layer].microtabs[family]) {
if (subtabShouldNotify(layer, family, subtab)) {
tmp[layer].trueGlowColor = tmp[layer].microtabs[family][subtab].glowColor
return true;
}
}
}
return false;
}
function canReset(layer) {
if (layers[layer].canReset !== undefined) {
return run(layers[layer].canReset, layers[layer]);
} else if (tmp[layer].type === "normal") {
return tmp[layer].baseAmount.gte(tmp[layer].requires);
} else if (tmp[layer].type === "static") {
return tmp[layer].baseAmount.gte(tmp[layer].nextAt);
} else {
return false;
}
}
function rowReset(row, layer) {
for (let lr in ROW_LAYERS[row]) {
if (layers[lr].doReset) {
player[lr].activeChallenge = null; // Exit challenges on any row reset on an equal or higher row
run(layers[lr].doReset, layers[lr], layer);
} else if (tmp[layer].row > tmp[lr].row && row !== "side" && !isNaN(row)) {
layerDataReset(lr);
}
}
}
function layerDataReset(layer, keep = []) {
let storedData = {unlocked: player[layer].unlocked, forceTooltip: player[layer].forceTooltip, noRespecConfirm: player[layer].noRespecConfirm} // Always keep these
for (let thing in keep) {
if (player[layer][keep[thing]] !== undefined) {
storedData[keep[thing]] = player[layer][keep[thing]];
}
}
Vue.set(player[layer], "buyables", getStartBuyables(layer));
Vue.set(player[layer], "clickables", getStartClickables(layer));
Vue.set(player[layer], "challenges", getStartChallenges(layer));
layOver(player[layer], getStartLayerData(layer));
player[layer].upgrades = [];
player[layer].milestones = [];
player[layer].achievements = [];
player[layer].challenges = getStartChallenges(layer);
resetBuyables(layer);
if (layers[layer].clickables && !player[layer].clickables) {
player[layer].clickables = getStartClickables(layer);
}
for (let thing in storedData) {
player[layer][thing] = storedData[thing];
}
}
function resetBuyables(layer) {
if (layers[layer].buyables) {
player[layer].buyables = getStartBuyables(layer);
}
player[layer].spentOnBuyables = decimalZero;
}
function addPoints(layer, gain) {
if (isFunction(layers[layer].onAddPoints)) {
layers[layer].onAddPoints(gain);
}
player[layer].points = player[layer].points.add(gain).max(0);
if (player[layer].best) {
player[layer].best = player[layer].best.max(player[layer].points);
}
if (player[layer].total) {
player[layer].total = player[layer].total.add(gain);
}
}
function generatePoints(layer, diff) {
addPoints(layer, tmp[layer].resetGain.times(diff));
}
let prevOnReset;
function doReset(layer, force = false) {
if (tmp[layer].type === "none") {
return;
}
let row = tmp[layer].row;
if (!force) {
if (tmp[layer].baseAmount.lt(tmp[layer].requires)) {
return;
}
let gain = tmp[layer].resetGain;
if (tmp[layer].type === "static") {
if (tmp[layer].baseAmount.lt(tmp[layer].nextAt)) {
return;
}
gain = (tmp[layer].canBuyMax ? gain : 1);
}
if (tmp[layer].type === "custom") {
if (!tmp[layer].canReset) {
return;
}
}
if (layers[layer].onPrestige) {
run(layers[layer].onPrestige, layers[layer], gain);
}
addPoints(layer, gain);
updateMilestones(layer);
updateAchievements(layer);
if (!player[layer].unlocked) {
player[layer].unlocked = true;
needCanvasUpdate = true;
if (tmp[layer].increaseUnlockOrder) {
let lrs = tmp[layer].increaseUnlockOrder;
for (let lr in lrs) {
if (!player[lrs[lr]].unlocked) {
player[lrs[lr]].unlockOrder++;
}
}
}
}
tmp[layer].baseAmount = decimalZero; // quick fix
}
if (tmp[layer].resetsNothing) {
return;
}
for (let layerResetting in layers) {
if (row >= layers[layerResetting].row && (!force || layerResetting !== layer)) {
completeChallenge(layerResetting);
}
}
prevOnReset = {...player}; //Deep Copy
player.points = (row === 0 ? decimalZero : getStartPoints());
for (let x = row; x >= 0; x--) {
rowReset(x, layer);
}
rowReset("side", layer);
prevOnReset = undefined;
player[layer].resetTime = 0;
updateTemp();
updateTemp();
}
function startChallenge(layer, x) {
let enter = false;
if (!player[layer].unlocked) {
return;
}
if (player[layer].activeChallenge === x) {
completeChallenge(layer, x);
player[layer].activeChallenge = null;
} else {
enter = true;
}
doReset(layer, true);
if (enter) {
player[layer].activeChallenge = x;
run(layers[layer].challenges[x].onEnter, layers[layer].challenges[x]);
}
updateChallengeTemp(layer);
}
function canCompleteChallenge(layer, x) {
if (x !== player[layer].activeChallenge) {
return;
}
let challenge = tmp[layer].challenges[x];
if (challenge.canComplete !== undefined) {
return challenge.canComplete;
}
if (challenge.currencyInternalName) {
let name = challenge.currencyInternalName;
if (challenge.currencyLocation) {
return !(challenge.currencyLocation[name].lt(challenge.goal));
} else if (challenge.currencyLayer) {
let lr = challenge.currencyLayer;
return !(player[lr][name].lt(challenge.goal));
} else {
return !(player[name].lt(challenge.goal));
}
} else {
return !(player.points.lt(challenge.goal));
}
}
function completeChallenge(layer) {
let x = player[layer].activeChallenge;
if (!x) {
return;
}
let completions = canCompleteChallenge(layer, x);
if (!completions) {
player[layer].activeChallenge = null;
run(layers[layer].challenges[x].onExit, layers[layer].challenges[x]);
return;
}
if (player[layer].challenges[x] < tmp[layer].challenges[x].completionLimit) {
needCanvasUpdate = true;
player[layer].challenges[x] += completions;
player[layer].challenges[x] = Math.min(player[layer].challenges[x], tmp[layer].challenges[x].completionLimit);
if (layers[layer].challenges[x].onComplete) {
run(layers[layer].challenges[x].onComplete, layers[layer].challenges[x]);
}
}
player[layer].activeChallenge = null;
run(layers[layer].challenges[x].onExit, layers[layer].challenges[x]);
updateChallengeTemp(layer);
}
VERSION.withoutName = "v" + VERSION.num + (VERSION.pre ? " Pre-Release " + VERSION.pre : VERSION.pre ? " Beta " + VERSION.beta : "");
VERSION.withName = VERSION.withoutName + (VERSION.name ? ": " + VERSION.name : "");
function autobuyUpgrades(layer) {
if (!tmp[layer].upgrades) {
return;
}
for (let id in tmp[layer].upgrades) {
if (isPlainObject(tmp[layer].upgrades[id]) && (layers[layer].upgrades[id].canAfford === undefined || layers[layer].upgrades[id].canAfford() === true)) {
buyUpg(layer, id);
}
}
}
function gameLoop(diff) {
if (isEndgame() || gameEnded) {
gameEnded = 1;
}
if (isNaN(diff)) {
diff = 0;
}
if (gameEnded && !player.keepGoing) {
diff = 0;
player.tab = "gameEnded";
clearParticles();
}
if (maxTickLength) {
let limit = maxTickLength();
if (diff > limit) {
diff = limit;
}
}
addTime(diff);
const modifiedDiff = diff * ritualEffect("speed").toNumber();
player.points = player.points.add(tmp.pointGen.times(modifiedDiff)).max(0);
for (let x = 0; x <= maxRow; x++) {
for (let item in TREE_LAYERS[x]) {
let layer = TREE_LAYERS[x][item];
player[layer].resetTime += diff;
if (tmp[layer].passiveGeneration) {
generatePoints(layer, modifiedDiff * tmp[layer].passiveGeneration);
}
if (layers[layer].update) {
layers[layer].update(modifiedDiff);
}
}
}
for (let row in OTHER_LAYERS) {
for (let item in OTHER_LAYERS[row]) {
let layer = OTHER_LAYERS[row][item];
player[layer].resetTime += diff;
if (tmp[layer].passiveGeneration) {
generatePoints(layer, modifiedDiff * tmp[layer].passiveGeneration);
}
if (layers[layer].update) {
layers[layer].update(modifiedDiff);
}
}
}
for (let x = maxRow; x >= 0; x--) {
for (let item in TREE_LAYERS[x]) {
let layer = TREE_LAYERS[x][item];
if (tmp[layer].autoPrestige && tmp[layer].canReset) {
doReset(layer);
}
if (layers[layer].automate) {
layers[layer].automate();
}
if (tmp[layer].autoUpgrade) {
autobuyUpgrades(layer);
}
}
}
for (let row in OTHER_LAYERS) {
for (let item in OTHER_LAYERS[row]) {
let layer = OTHER_LAYERS[row][item];
if (tmp[layer].autoPrestige && tmp[layer].canReset) {
doReset(layer);
}
if (layers[layer].automate) {
layers[layer].automate();
}
player[layer].best = player[layer].best.max(player[layer].points);
if (tmp[layer].autoUpgrade) {
autobuyUpgrades(layer);
}
}
}
for (let layer in layers) {
if (layers[layer].milestones) {
updateMilestones(layer);
}
if (layers[layer].achievements) {
updateAchievements(layer);
}
}
}
function hardReset(override = false) {
if (!(override || confirm("Are you sure you want to do this? You will lose all your progress!"))) {
return;
}
player = null;
save();
window.location.reload();
}
let ticking = false;
let lastTenTicks = [];
const interval = setInterval(function () {
if (player === undefined || tmp === undefined) {
return;
}
if (ticking) {
return;
}
if (gameEnded && !player.keepGoing) {
return;
}
ticking = true;
let now = Date.now();
let diff = (now - player.time) / 1e3;
let trueDiff = diff;
if (player.offTime !== undefined) {
if (player.offTime.remain > modInfo.offlineLimit * 3600) {
player.offTime.remain = modInfo.offlineLimit * 3600;
}
if (player.offTime.remain > 0) {
let offlineDiff = Math.max(player.offTime.remain / 10, diff);
player.offTime.remain -= offlineDiff;
diff += offlineDiff;
}
if (!player.offlineProd || player.offTime.remain <= 0) {
player.offTime = undefined;
}
}
if (player.devSpeed != null) {
diff *= player.devSpeed;
}
player.time = now;
if (needCanvasUpdate) {
resizeCanvas();
needCanvasUpdate = false;
}
tmp.scrolled = document.getElementById("treeTab")?.scrollTop > 30;
updateTemp();
updateOomps(diff);
updateWidth()
updateTabFormats()
gameLoop(diff);
fixNaNs();
adjustPopupTime(trueDiff);
updateParticles(trueDiff);
lastTenTicks.push(trueDiff);
if (lastTenTicks.length > 10) {
lastTenTicks = lastTenTicks.slice(1);
}
Vue.set(app, "lastTenTicks", lastTenTicks);
ticking = false;
}, 50);
setInterval(function () {
needCanvasUpdate = true;
}, 500);