// ==UserScript== // @name Cookie Clicker upgrade suggester // @namespace http://azzurite.tv // @version 1.0.3 // @description Clears the top bar and instead displays suggestions for next buy there // @author Azzurite // @match http://orteil.dashnet.org/cookieclicker/ // @grant none // @require https://code.jquery.com/jquery-3.3.1.slim.min.js // @downloadURL https://update.greasyfork.icu/scripts/389700/Cookie%20Clicker%20upgrade%20suggester.user.js // @updateURL https://update.greasyfork.icu/scripts/389700/Cookie%20Clicker%20upgrade%20suggester.meta.js // ==/UserScript== var myWindow = { skeleton: `
ALT MODE
Import save   Random name  | 
 |   | 
 |   |    Recalculate

Buildings tables  CpS Prices -/+ buttons:  | 
NameAmountLevelPrice CpSTime for+CpS +CpS w/ clicks Amortization [?]
Cursor- +- +1501s0.10.12m 30s
Grandma- +- +10005s111m 40s
Farm- +- +1,100055s882m 18s
Mine- +- +12,000010m47474m 16s
Factory- +- +130,00001h 48m 20s2602608m 20s
Bank- +- +1.4 M019h 26m 40s1,4001,40016m 40s
Temple- +- +20 M0277h 46m 40s7,8007,80042m 45s
Wizard tower- +- +330 M04,583h 20m44,00044,0002h 5m
Shipment- +- +5.1 B070,833h 20m260,000260,0005h 26m 56s
Alchemy lab- +- +75 B01.042 Mh 40m1.6 M1.6 M13h 1m 15s
Portal- +- +1 T013.889 M h 53m 20s10 M10 M27h 46m 40s
Time machine- +- +14 T0194.444 M h 26m 40s65 M65 M59h 49m 45s
Antimatter condenser- +- +170 T02.361 B h 6m 40s430 M430 M109h 49m 9s
Prism- +- +2.1 Qa029.167 B h 40m2.9 B2.9 B201h 8m 58s
Chancemaker- +- +26 Qa0361.111 B h 6m 40s21 B21 B343h 54m 56s
Fractal engine- +- +310 Qa04.306 T h 33m 20s150 B150 B574h 4m 27s
Upgrades & minigames0 (multiplier: 100%)
AchievementsMilk: 0% 0--- ---
Total0 0 Cookies per click: 1



 | 

Cookies per Second: 0
Cookies per Click: 1
Total: 20 Cookies per Second

Show bank:
 |  Building recommend #:
 |   |   
op 5 recommended purchases:
Chain for
Reinforced index finger
- Price: 115, +20.2 CpS, +2 achievements, Bank: 115

Chain for
Carpal tunnel prevention cream
- Price: 515, +20.2 CpS, +2 achievements, Bank: 515

Grandma #1-3 - Price: 348, +1 CpS, +3 achievements, Bank: 348
Cursor #1-2 - Price: 33, +0.1 CpS, +3 achievements, Bank: 33
Farm #1-7 - Price: 12,175, +8 CpS, +5 achievements, Bank: 12,175
- Nothing to recommend. -
(this list is recalculated every time you make a purchase)


Upgrades Achievements Prestige Buffs Golden Cookies Seasons Santa & Dragon Auras Pantheon Garden Blacklist

Golden Cookies

x0.5 x1 x7 x15 x666 x1
Frenzy CpS0---000---
Max Lucky!131313131313
x777 Click frenzy777777777777777777
x1111 Dragonflight1,1111,1111,1111,1111,1111,111




`}; myWindow.location = window.location; myWindow.document = window.document; var myDiv = window.document.createElement('div'); myDiv.innerHTML = myWindow.skeleton; window.document.body.appendChild(myDiv); $('#topBar').children().each((idx, child) => { var $child = $(child); if (idx !== 0 && $child.attr('id') !== 'heralds') { $child.css('display', 'none'); } }); var prevCookiesPS = null; setInterval(() => { if (!window.Game || !window.Game.cookiesPs || !window.Game.WriteSave) return; if (window.Game.cookiesPs !== prevCookiesPS) { console.log('Recommended update triggered'); prevCookiesPS = window.Game.cookiesPs; myWindow.Game.importSave(window.Game.WriteSave(1)); } }, 100); /* global Base64 */ /* eslint no-unused-vars: ["error", {"vars": "local"}] */ function utf8_to_b64(str) { try { return Base64.encode(unescape(encodeURIComponent(str))); } catch (err) { return ""; } } function b64_to_utf8(str) { try { return decodeURIComponent(escape(Base64.decode(str))); } catch (err) { // alert("There was a problem while decrypting from base64. (" + err + ")"); console.error(err); return ""; } } function UncompressBin(num) { //uncompress a number like 54 to a sequence like [0, 1, 1, 0, 1, 0]. return num.toString(2).slice(1, -1).split("").reverse(); } function UncompressLargeBin(arr) { var arr2 = arr.split(";"); var bits = []; for (var i in arr2) { bits.push(UncompressBin(parseInt(arr2[i], 10))); } arr2 = []; for (i in bits) { for (var ii in bits[i]) { arr2.push(bits[i][ii]); } } return arr2; } function unpack(str) { var bytes = []; var len = str.length; for (var i = 0, n = len; i < n; i++) { var char = str.charCodeAt(i); bytes.push(char >>> 8, char & 0xFF); } return bytes; } //modified from http://www.smashingmagazine.com/2011/10/19/optimizing-long-lists-of-yesno-values-with-javascript/ function pack2(/* string */ values) { var chunks = values.match(/.{1,14}/g); var packed = ""; for (var i = 0; i < chunks.length; i++) { var chunk = chunks[i]; //add dummy data to prevent packing to "|" if (chunk === "111100") { chunk += "00"; } packed += String.fromCharCode(parseInt("1" + chunk, 2)); } return packed; } // function pack3(values) { // //too many save corruptions, darn it to heck // return values; // } function unpack2(/* string */ packed) { var values = ""; for (var i = 0; i < packed.length; i++) { values += packed.charCodeAt(i).toString(2).substring(1); } return values; } //like str.split("|") but works around game's pack2() potentially outputting a "|", // by skipping over first pipe character of a pair in fields where pack2 is used // (the second field is intentionally empty as of this writing so still have to split that) function splitSave(str) { var arr = []; do { var index = str.indexOf("|"); if (index > -1 && arr.length > 2 && str.charAt(index + 1) === "|") { index++; } arr.push(str.slice(0, index > -1 ? index : undefined)); str = str.slice(index + 1); } while (index > -1); return arr; } function decodeSave(str) { return b64_to_utf8(unescape(str).split("!END!")[0]); } function encodeSave(str) { return escape(utf8_to_b64(str) + "!END!"); } myWindow.byId = function byId(id) { const elementById = document.getElementById(id); if (!elementById) { console.log('ID not found:', id) } return elementById; }; //seeded random function, courtesy of http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html //out of IIFE because strict mode //eslint-disable-next-line (function(a, b, c, d, e, f) { function k(a) { var b, c = a.length, e = this, f = 0, g = e.i = e.j = 0, h = e.S = []; for (c || (a = [c++]); d > f;) h[f] = f++; for (f = 0; d > f; f++) h[f] = h[g = j & g + a[f % c] + (b = h[f])], h[g] = b; (e.g = function(a) { for (var b, c = 0, f = e.i, g = e.j, h = e.S; a--;) b = h[f = j & f + 1], c = c * d + h[j & (h[f] = h[g = j & g + b]) + (h[g] = b)]; return e.i = f, e.j = g, c })(d) } function l(a, b) { var e, c = [], d = (typeof a)[0]; if (b && "o" == d) for (e in a) try {c.push(l(a[e], b - 1))} catch (f) {} return c.length ? c : "s" == d ? a : a + "\0" } function m(a, b) { for (var d, c = a + "", e = 0; c.length > e;) b[j & e] = j & (d ^= 19 * b[j & e]) + c.charCodeAt(e++); return o(b) } function n(c) { try {return a.crypto.getRandomValues(c = new Uint8Array(d)), o(c)} catch (e) { return [ +new Date, a, a.navigator.plugins, a.screen, o(b) ] } } function o(a) {return String.fromCharCode.apply(0, a)} var g = c.pow(d, e), h = c.pow(2, f), i = 2 * h, j = d - 1; c.seedrandom = function(a, f) { var j = [], p = m(l(f ? [a, o(b)] : 0 in arguments ? a : n(), 3), j), q = new k(j); return m(o(q.S), b), c.random = function() { for (var a = q.g(e), b = g, c = 0; h > a;) a = (a + c) * d, b *= d, c = q.g(1); for (; a >= i;) a /= 2, b /= 2, c >>>= 1; return (a + c) / b }, p }, m(c.random(), b) })(window, [], Math, 256, 6, 52); (function(window, $) { "use strict"; var document = window.document; var byId = window.byId; //#region definitions var Game = { version: 2.019, mainJS: "2.054", beta: window.location.href.indexOf("/beta") > -1, firstRun: true, fps: 30, ObjectPriceIncrease: 1.15, //price increase factor for buildings SpecialGrandmaUnlock: 15, //when farmer/worker/miner/etc. grandmas upgrades unlock maxClicksPs: 250, //maximum clicks per second Objects: {}, //buildings ObjectsById: [], ObjectsByGroup: {}, ObjectsOwned: 0, Upgrades: {}, UpgradesById: [], UpgradesByPool: {}, UpgradesByGroup: {}, UpgradesOwned: 0, numCountedUpgrades: 0, maxCountedUpgrades: 0, UpgradeOrder: [], //list of upgrades sorted by current settings Achievements: {}, AchievementsById: [], AchievementsByPool: {}, AchievementsByGroup: {}, AchievementsOwned: 0, AchievementsTotal: 0, defaultSeason: "", season: "", seasons: {}, seasonTriggerBasePrice: 1000000000, seasonUses: 0, pledges: 0, ascensionMode: 0, sellMultiplier: 0.5, startDate: Date.now(), //used for calculating Century egg stuff CenturyEggBoost: 1, objectGodMult: 1, numGoldenCookies: 0, ObjectPriceMultArray: [], //used for Object price caches UpgradePriceMultArray: [], heralds: 0, heavenlyPower: 1, //% cps bonus per prestige level cookiesPs: 0, cookiesPerClick: 0, cookiesPsPlusClicks: 0, globalCpsMult: 1, rawCookiesPs: 0, unbuffedCookiesPs: 0, prestige: 0, cookiesBaked: 0, buildingBuyInterval: 1, santa: {}, santaLevel: 0, santaLevels: [ "Festive test tube", "Festive ornament", "Festive wreath", "Festive tree", "Festive present", "Festive elf fetus", "Elf toddler", "Elfling", "Young elf", "Bulky elf", "Nick", "Santa Claus", "Elder Santa", "True Santa", "Final Claus" ], dragonLevel: 0, dragonAura: 0, dragonAura2: 0, maxWrinklers: 10, minCumulative: 0, //minimum cookies needed for everything (see getMinCumulative method) minCumulativeOffset: 0, //used to try to prevent minCumulative from being excessively wrong large due to saves from old game versions permanentUpgrades: [-1, -1, -1, -1, -1], //used for calculating min cumulative includeDragonSacrifices: true, //whether to include the cost of sacrificing buildings to train Krumblor (if relevant) Buffs: {}, BuffTypes: [], BuffTypesByName: {}, lumps: 0, effs: {}, pantheon: { gods: {}, godsById: [], slot: [-1, -1, -1], slotNames: ["Diamond", "Ruby", "Jade"] }, garden: { plants: {}, plantsById: [], numPlants: 0, seedSelected: -1, soils: {}, soilsById: [], plot: [], plotBoost: [], plotLimits: [], effs: {}, effsData: {}, tileSize: 40, stepT: 1, soil: 0 }, Milks: [ { name: "Rank I - Plain milk", icon: [1, 8] }, { name: "Rank II - Chocolate milk", icon: [2, 8] }, { name: "Rank III - Raspberry milk", icon: [3, 8] }, { name: "Rank IV - Orange milk", icon: [4, 8] }, { name: "Rank V - Caramel milk", icon: [5, 8] }, { name: "Rank VI - Banana milk", icon: [6, 8] }, { name: "Rank VII - Lime milk", icon: [7, 8] }, { name: "Rank VIII - Blueberry milk", icon: [8, 8] }, { name: "Rank IX - Strawberry milk", icon: [9, 8] }, { name: "Rank X - Vanilla milk", icon: [10, 8] }, { name: "Rank XI - Honey milk", icon: [21, 23] }, { name: "Rank XII - Coffee milk", icon: [22, 23] }, { name: "Rank XIII - Tea with a spot of milk", icon: [23, 23] }, { name: "Rank XIV - Coconut milk", icon: [24, 23] }, { name: "Rank XV - Cherry milk", icon: [25, 23] }, { name: "Rank XVI - Spiced milk", icon: [26, 23] }, { name: "Rank XVII - Maple milk", icon: [28, 23] } ], temp: { ObjectsOwned: 0, UpgradesOwned: 0, UpgradesToCheck: [], kittensOwned: 0, AchievementsOwned: 0, LockedAchievements: [], cpsObj: {}, prestige: 0, cookiesBaked: 0, santaLevel: 0, dragonAura: 0, dragonAura2: 0 }, storedImport: null, maxRecommend: 1, maxLookahead: 20, abbrOn: true, //whether to abbreviate with letters/words or with commas/exponential notation lockChecked: false, //sets behavior when clicking on upgrades, controlled by various checkboxes on the page predictiveMode: false, //prevents predictive calculations overwriting current state by changing which properties are read/written showDebug: false, //whether to always show debug upgrades altMode: false }; window.Game = Game; Game.santaMax = Game.santaLevels.length - 1; Game.lastUpdateTime = Game.startDate; if (Game.beta) { document.title += " Beta"; } //#endregion definitions //#region methods Game.choose = function(arr) { return arr[Math.floor(Math.random() * arr.length)]; }; Game.makeSeed = function() { var chars = "abcdefghijklmnopqrstuvwxyz".split(""); var str = ""; for (var i = 0; i < 5; i++) { str += Game.choose(chars); } return str; }; Game.setSeed = function(seed) { Game.seed = seed || Game.makeSeed(); //each run has its own seed, used for deterministic random stuff }; //sets obj[key] to an array if it is not already and pushes value to it Game.ArrayPush = function(obj, key, value) { if (!Array.isArray(obj[key])) { obj[key] = []; } obj[key].push(value); }; //checks event for keys for alt mode Game.checkEventAltMode = function(event) { return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey; }; var Abbreviations = [ { short: "", long: "" }, { short: "k", long: "thousand" }, { short: "M", long: "million" }, { short: "B", long: "billion" }, { short: "T", long: "trillion" }, { short: "Qa", long: "quadrillion" }, { short: "Qi", long: "quintillion" }, { short: "Sx", long: "sextillion" }, { short: "Sp", long: "septillion" }, { short: "Oc", long: "octillion" }, { short: "No", long: "nonillion" } ]; var longPrefixes = ["", "un", "duo", "tre", "quattuor", "quin", "sex", "septen", "octo", "novem"]; var longSuffixes = [ "decillion", "vigintillion", "trigintillion", "quadragintillion", "quinquagintillion", "sexagintillion", "septuagintillion", "octogintillion", "nonagintillion" ]; var shortPrefixes = ["", "Un", "Do", "Tr", "Qa", "Qi", "Sx", "Sp", "Oc", "No"]; var shortSuffixes = ["D", "V", "T", "Qa", "Qi", "Sx", "Sp", "O", "N"]; for (var i = 0; i < longSuffixes.length; i++) { for (var j = 0; j < longPrefixes.length; j++) { Abbreviations.push({ short: shortPrefixes[j] + shortSuffixes[i], long: longPrefixes[j] + longSuffixes[i] }); } } Abbreviations[11].short = "Dc"; var AbbreviationsMax = Abbreviations.length - 1; for (i = 1; i <= AbbreviationsMax; i++) { var abbr = Abbreviations[i]; abbr.shortRgx = new RegExp("(\\-?[\\d\\.]+)\\s*(" + abbr.short + ")\\s*$", "i"); abbr.longRgx = new RegExp("(\\-?[\\d\\.]+)\\s*(" + abbr.long + ")\\s*$", "i"); } var commaRgx = /\B(?=(\d{3})+(?!\d))/g; Game.addCommas = function(what) { var x = what.toString().split("."); x[0] = x[0].replace(commaRgx, ","); return x.join("."); }; Game.Beautify = function(what, floats) { //turns 9999999 into 9,999,999 if (what === "---") { return what; } if (!isFinite(what)) { return "Infinity"; } var absWhat = Math.abs(what); if (absWhat > 1 && what.toString().indexOf("e") > -1) { return what.toString(); } floats = absWhat < 1000 && floats > 0 ? Math.pow(10, floats) : 1; what = Math.round(what * floats) / floats; return Game.addCommas(what); }; Game.shortenNumber = function(value) { //if no scientific notation, return as is, else : //keep only the 5 first digits (plus dot), round the rest //may or may not work properly if (value >= 1000000 && isFinite(value)) { var num = value.toString(); var ind = num.indexOf("e+"); if (ind == -1) { return value; } var str = ""; for (var i = 0; i < ind; i++) { str += (i < 6 ? num[i] : "0"); } str += "e+"; str += num.split("e+")[1]; return parseFloat(str); } return value; }; //abbreviates numbers Game.abbreviateNumber = function(num, floats, abbrlong) { if (num === "---") { return num; } if (!isFinite(num)) { return "Infinity"; } if (Math.abs(num) < 1000000) { return Game.Beautify(num, floats); } num = Number(num).toExponential().split("e+"); var pow = Math.floor(num[1] / 3); if (pow > AbbreviationsMax) { num[0] = Math.round(num[0] * 1000) / 1000; return num.join("e+"); } num[0] *= Math.pow(10, num[1] % 3); num[0] = Math.round(num[0] * 1000) / 1000; if (Math.abs(num[0]) >= 1000 && pow < AbbreviationsMax) { pow += 1; num[0] /= 1000; } else { num[0] = Game.addCommas(num[0]); } num[1] = Abbreviations[Math.min(pow, AbbreviationsMax)][abbrlong ? "long" : "short"]; return num.join(" "); }; Game.BeautifyAbbr = function(what, floats, abbrlong) { return Game.abbrOn ? Game.abbreviateNumber(what, floats, abbrlong) : Game.Beautify(what, floats); }; Game.formatNumber = function(num, floats, abbrlong, extraStr, extraTitle) { var beaut = Game.Beautify(num, floats); var abbr = Game.abbreviateNumber(num, floats, abbrlong); var text = extraStr || ""; var title = text + (extraTitle || ""); if (beaut === abbr) { text = beaut + text; } else { text = (Game.abbrOn ? abbr : beaut) + text; var aLong = abbrlong || abbr === beaut ? abbr : Game.abbreviateNumber(num, floats, true); title = (Game.abbrOn ? beaut : aLong) + title; } return ("' : ">") + text + ""); }; Game.formatTime = function(seconds) { if (isNaN(seconds) || !isFinite(seconds) || seconds <= 0) { return "---"; } seconds = Math.ceil(seconds); var hours = Math.floor(seconds / 3600); if (hours > 0) { hours = Game.BeautifyAbbr(hours) + (hours >= 1e7 ? " " : "") + "h "; } else { hours = ""; } seconds %= 3600; var minutes = Math.floor(seconds / 60); minutes = minutes > 0 ? minutes + "m " : ""; seconds %= 60; seconds = seconds > 0 ? seconds + "s" : ""; return (hours + minutes + seconds).trim(); }; Game.getPlural = function(amount, singular, plural) { singular = singular || ""; plural = plural || (singular + "s"); return amount === 1 ? singular : plural; }; Game.sayTime = function(time, detail) { //time is a value where one second is equal to Game.fps (30). //detail skips days when >1, hours when >2, minutes when >3 and seconds when >4. //if detail is -1, output something like "3 hours, 9 minutes, 48 seconds" if (time <= 0) { return ""; } var str = ""; detail = detail || 0; time = Math.floor(time); if (detail == -1) { // var months = 0; var days = 0; var hours = 0; var minutes = 0; var seconds = 0; // if (time >= Game.fps * 60 * 60 * 24 * 30) { months = (Math.floor(time / (Game.fps * 60 * 60 * 24 * 30))); } if (time >= Game.fps * 60 * 60 * 24) { days = (Math.floor(time / (Game.fps * 60 * 60 * 24))); } if (time >= Game.fps * 60 * 60) { hours = (Math.floor(time / (Game.fps * 60 * 60))); } if (time >= Game.fps * 60) { minutes = (Math.floor(time / (Game.fps * 60))); } if (time >= Game.fps) { seconds = (Math.floor(time / (Game.fps))); } // days -= months * 30; hours -= days * 24; minutes -= hours * 60 + days * 24 * 60; seconds -= minutes * 60 + hours * 60 * 60 + days * 24 * 60 * 60; if (days > 10) { hours = 0; } if (days) { minutes = 0; seconds = 0; } if (hours) { seconds = 0; } var bits = []; // if (months > 0) { bits.push(Game.Beautify(months) + Game.getPlural(months, " month")); } if (days > 0) { bits.push(Game.Beautify(days) + Game.getPlural(days, " day")); } if (hours > 0) { bits.push(Game.Beautify(hours) + Game.getPlural(hours, " hour")); } if (minutes > 0) { bits.push(Game.Beautify(minutes) + Game.getPlural(minutes, " minute")); } if (seconds > 0) { bits.push(Game.Beautify(seconds) + Game.getPlural(seconds, " second")); } if (bits.length == 0) { str = "less than 1 second"; } else { str = bits.join(", "); } } else { /* if (time >= Game.fps * 60 * 60 * 24 * 30 * 2 && detail < 1) { str = Game.Beautify(Math.floor(time / (Game.fps * 60 * 60 * 24 * 30))) + " months"; } else if (time >= Game.fps * 60 * 60 * 24 * 30 && detail < 1) { str = "1 month"; } else */ if (time >= Game.fps * 60 * 60 * 24 * 2 && detail < 2) { str = Game.Beautify(Math.floor(time / (Game.fps * 60 * 60 * 24))) + " days"; } else if (time >= Game.fps * 60 * 60 * 24 && detail < 2) { str = "1 day"; } else if (time >= Game.fps * 60 * 60 * 2 && detail < 3) { str = Game.Beautify(Math.floor(time / (Game.fps * 60 * 60))) + " hours"; } else if (time >= Game.fps * 60 * 60 && detail < 3) { str = "1 hour"; } else if (time >= Game.fps * 60 * 2 && detail < 4) { str = Game.Beautify(Math.floor(time / (Game.fps * 60))) + " minutes"; } else if (time >= Game.fps * 60 && detail < 4) { str = "1 minute"; } else if (time >= Game.fps * 2 && detail < 5) { str = Game.Beautify(Math.floor(time / (Game.fps))) + " seconds"; } else if (time >= Game.fps && detail < 5) { str = "1 second"; } else { str = "less than 1 second"; } } return str; }; Game.costDetails = function(cost, force) { if (!force && !Game.HasUpgrade("Genius accounting")) { return ""; } if (!cost || !isFinite(cost)) { return ""; } var priceInfo = ""; var cps = Game.cookiesPs * (1 - Game.cpsSucked); if (!cps) { return ""; } // if (cost > Game.cookies) { priceInfo += "in " + Game.sayTime(((cost - Game.cookies) / cps + 1) * Game.fps) + "
"; } priceInfo += Game.sayTime((cost / cps + 1) * Game.fps) + " worth
"; // priceInfo += Game.Beautify((cost / Game.cookies) * 100, 1) + "% of bank
"; return ('
' + priceInfo + "
"); }; var cleanNumberRgx = /[^\deE\+\.\-]/g; Game.cleanNumber = function(str) { return str.replace(cleanNumberRgx, ""); }; var parseMatchRgx = /\s*(.*\d)(\D*)/; var parseReplaceRgx = /[^\d\.]/g; Game.parseNumber = function(num, min, max, floor) { if (typeof num === "string" && num.length) { var matches = num.match(parseMatchRgx); var c = false; if (matches) { var d = parseFloat(matches[1].replace(parseReplaceRgx, "")); var n = (d + matches[2]).trim(); for (var i = 1; i <= AbbreviationsMax; i++) { var abbrs = Abbreviations[i]; if (abbrs.shortRgx.test(n) || abbrs.longRgx.test(n)) { num = d * Math.pow(10, 3 * i); c = true; break; } } } if (!c) { num = parseFloat(Game.cleanNumber(num)); } } num = Number(num) || 0; num = Math.max(num, min || 0); if (!isNaN(max)) { num = Math.min(num, max); } if (floor) { num = Math.floor(num); } return num || 0; }; Game.setInput = function(ele, value) { var $ele = $(ele); ele = $ele[0]; var metaObj = ele.metaObj; var dataProp = ele.dataProp; if ($ele.hasClass("text")) { ele.value = value; } else { if (typeof value === "undefined") { value = ele.parsedValue || 0; //refresh values and stuff } value = Game.parseNumber(value, ele.minIn, ele.maxIn, !$ele.hasClass("deci")); var displayVal = value; ele.parsedValue = value; if ($ele.hasClass("exp")) { ele.dataset.title = value < 1e7 || Game.abbrOn ? Game.Beautify(value) : Game.abbreviateNumber(value, 0, true); displayVal = Game.BeautifyAbbr(value, 0, true); ele.displayValue = displayVal; } if (document.activeElement !== ele) { ele.value = displayVal; } if (ele.twin) { ele.twin.parsedValue = ele.parsedValue; if (ele.displayValue) { ele.twin.displayValue = ele.displayValue; } if (document.activeElement !== ele.twin) { ele.twin.value = ele.twin.displayValue || value; } if (typeof ele.dataset.title !== "undefined") { ele.twin.dataset.title = ele.dataset.title; } metaObj = metaObj || ele.twin.metaObj; dataProp = dataProp || ele.twin.dataProp; } } if ((ele === Game.tooltipAnchor || ele.twin === Game.tooltipAnchor) && typeof Game.updateTooltip === "function") { Game.updateTooltip(true); } if (metaObj && dataProp) { metaObj[dataProp] = value; } return value; }; Game.registerInput = function(ele, metaObj, dataProp) { ele = $(ele)[0]; if (ele) { ele.metaObj = metaObj || null; ele.dataProp = dataProp || null; } }; Game.registerInputs = function(metaObj, arr) { for (var i = 0; i < arr.length; i++) { var props = arr[i]; Game.registerInput(props[0], metaObj, props[1]); } }; Game.GetUpgrade = function(what) { if (what && what.type === "upgrade") { return what; } if (Game.Upgrades.hasOwnProperty(what)) { return Game.Upgrades[what]; } if (Game.UpgradesById.hasOwnProperty(what)) { return Game.UpgradesById[what]; } return false; }; Game.Has = Game.HasUpgrade = function(what, asNum) { var upgrade = Game.GetUpgrade(what); if (!upgrade) { return false; } if (Game.ascensionMode === 1 && upgrade.pool === "prestige") { return false; } return upgrade.getBought(asNum); }; Game.GetAchiev = Game.GetAchieve = function(what) { if (what && what.type === "achievement") { return what; } if (Game.Achievements.hasOwnProperty(what)) { return Game.Achievements[what]; } if (Game.AchievementsById.hasOwnProperty(what)) { return Game.AchievementsById[what]; } return false; }; Game.HasAchiev = Game.HasAchieve = function(what, asNum) { var achieve = Game.GetAchiev(what); return achieve ? achieve.getWon(asNum) : false; }; Game.Win = function(what, temp) { if (Array.isArray(what)) { for (var i = what.length - 1; i >= 0; i--) { Game.Win(what[i], temp); } } else { var achieve = Game.getAchieve(what); if (achieve) { achieve.setWon(true, temp); } } }; Game.countUpgradesByGroup = function(list, limit, includeUnlocked) { if (!Array.isArray(list)) { list = Game.UpgradesByGroup[list]; } var count = 0; if (list) { if (isNaN(limit) || limit < 0) { limit = list.length; } for (var i = list.length - 1; i >= 0 && count < limit; i--) { var upgrade = Game.GetUpgrade(list[i]); if (upgrade) { if (upgrade.getBought() || (includeUnlocked && upgrade.unlocked)) { count++; } } } } return count; }; Game.listTinyOwnedUpgrades = function(arr) { var str = ""; for (var i = 0; i < arr.length; i++) { var upgrade = Game.GetUpgrade(arr[i]); if (upgrade.getBought()) { str += upgrade.tinyIconStr; } } return str; }; Game.saySeasonSwitchUses = function() { if (Game.seasonUses == 0) { return "You haven't switched seasons this ascension yet."; } return ("You've switched seasons " + (Game.seasonUses == 1 ? "once" : Game.seasonUses == 2 ? "twice" : (Game.seasonUses + " times")) + " this ascension."); }; Game.hasAura = function(name) { if (Game.predictiveMode && Game.tempDragonAuraOff === name) { return false; } return Game.dragonAuras[Game.Get("dragonAura")].name === name || Game.dragonAuras[Game.Get("dragonAura2")].name === name; }; Game.hasBuff = function(what) { return Game.Buffs[what]; }; Game.hasGod = function(what) { var god = Game.pantheon.gods[what]; if (god) { for (var i = 0; i < 3; i++) { if (Game.pantheon.slot[i] === god.id) { return (i + 1); } } } return false; }; Game.GetTieredCpsMult = function(building) { var mult = 1; for (var i in building.tieredUpgrades) { var upgrade = building.tieredUpgrades[i]; if (!Game.Tiers[upgrade.tier].special && upgrade.getBought()) { mult *= 2; } } for (i = building.synergies.length - 1; i >= 0; i--) { var syn = building.synergies[i]; if (syn.getBought()) { if (syn.buildingTie1 === building) { mult *= 1 + 0.05 * syn.buildingTie2.getAmount(); } else if (syn.buildingTie2 === building) { mult *= 1 + 0.001 * syn.buildingTie1.getAmount(); } } } if (building.grandmaSynergy && building.grandmaSynergy.getBought()) { mult *= 1 + Game.Objects["Grandma"].getAmount() * 0.01 * (1 / (building.id - 1)); } return mult; }; Game.setDisabled = function(ele, disable) { ele = $(ele)[0]; if (!ele) { return; } disable = typeof disable === "undefined" ? !ele.disabled : Boolean(disable); ele.disabled = disable; var $par = $(ele.parentNode); if ($par.is("label")) { $par.toggleClass("disabled", disable); } else if ($par.is("select")) { $(ele).toggleClass("hidden", disable); } return ele.disable; }; var ObjectPriceMultStr = ""; var mapToNum = function(i) { return Number(i); }; //cache price reduction upgrade.bought values, for use in getPrice methods Game.setPriceMultArrays = function() { Game.ObjectPriceMultArray = [ Game.HasUpgrade("Season savings"), Game.HasUpgrade("Santa's dominion"), Game.HasUpgrade("Faberge egg"), Game.HasUpgrade("Divine discount"), Game.hasAura("Fierce Hoarder"), Boolean(Game.hasBuff("Everything must go")), Boolean(Game.hasBuff("Crafty pixies")), Boolean(Game.hasBuff("Nasty goblins")), Game.eff("buildingCost"), Number(Game.hasGod("creation")) //Dotjeiess ]; var newStr = Game.ObjectPriceMultArray.map(mapToNum).join(""); Game.UpgradePriceMultArray = [ Game.HasUpgrade("Toy workshop"), Game.HasUpgrade("Five-finger discount"), Game.ObjectPriceMultArray[1], //Santa's dominion Game.ObjectPriceMultArray[2], //Faberge egg Game.HasUpgrade("Divine sales"), Boolean(Game.hasBuff("Haggler's luck")), Boolean(Game.hasBuff("Haggler's misery")), Game.hasAura("Master of the Armory"), Game.eff("upgradeCost"), Game.HasUpgrade("Divine bakeries") ]; if (newStr !== ObjectPriceMultStr) { ObjectPriceMultStr = newStr; for (var i = Game.ObjectsById.length - 1; i >= 0; i--) { Game.ObjectsById[i].priceCache = {}; } } }; Game.modifyObjectPrice = function(building, price) { var arr = Game.ObjectPriceMultArray; if (arr[0]) { price *= 0.99; } //Season savings if (arr[1]) { price *= 0.99; } //Santa's dominion if (arr[2]) { price *= 0.99; } //Faberge egg if (arr[3]) { price *= 0.99; } //Divine discount if (arr[4]) { price *= 0.98; } //Fierce Hoarder if (arr[5]) { price *= 0.95; } //Everything must go if (arr[6]) { price *= 0.98; } //Crafty pixies if (arr[7]) { price *= 1.02; } //Nasty goblins price *= arr[8]; //buildingCost minigame effect var godLvl = arr[9]; //creation if (godLvl == 1) { price *= 0.93; } else if (godLvl == 2) { price *= 0.95; } else if (godLvl == 3) { price *= 0.98; } return price; }; Game.setObjectDisplays = function() { for (var i = Game.ObjectsById.length - 1; i >= 0; i--) { Game.ObjectsById[i].setDisplay(); } }; // var foolsNameCheck = byId("foolsNameCheck"); Game.setSeason = function(season) { var seasonObj = Game.seasons[season]; if (!seasonObj) { seasonObj = Game.seasons[Game.defaultSeason]; } if (!seasonObj) { seasonObj = {season: ""}; } Game.season = seasonObj.season || ""; $(".seasonBlock").addClass("hidden"); $('.seasonBlock[data-season="' + Game.season + '"]').removeClass("hidden"); //TODO revisit autoforce fools display names once? // if (Game.season === "fools" && !foolsNameCheck.manualChecked && Game.defaultSeason !== "fools") { // foolsNameCheck.checked = true; // } // Game.setObjectDisplays(); }; Game.getGoldCookieDurationMod = function(wrath) { var effectDurMod = 1; if (Game.HasUpgrade("Get lucky")) { effectDurMod *= 2; } if (Game.HasUpgrade("Lasting fortune")) { effectDurMod *= 1.1; } if (Game.HasUpgrade("Lucky digit")) { effectDurMod *= 1.01; } if (Game.HasUpgrade("Lucky number")) { effectDurMod *= 1.01; } if (Game.HasUpgrade("Green yeast digestives")) { effectDurMod *= 1.01; } if (Game.HasUpgrade("Lucky payout")) { effectDurMod *= 1.01; } if (Game.hasAura("Epoch Manipulator")) { effectDurMod *= 1.05; } if (wrath) { effectDurMod *= Game.eff("wrathCookieEffDur"); } else { effectDurMod *= Game.eff("goldenCookieEffDur"); } var godLvl = Game.hasGod("decadence"); //Vomitrax if (godLvl == 1) { effectDurMod *= 1.07; } else if (godLvl == 2) { effectDurMod *= 1.05; } else if (godLvl == 3) { effectDurMod *= 1.02; } return effectDurMod; }; //shortcut function to get either current or temporary property of Game Game.Get = function(key) { return Game.predictiveMode && key in Game.temp ? Game.temp[key] : Game[key]; }; //shortcut function to set either current or temporary property of Game Game.Set = function(key, value) { var obj = Game.predictiveMode && key in Game.temp ? Game.temp : Game; obj[key] = value; }; Game.getCookiesBaked = function(add) { return (Game.Get("cookiesBaked") + (Number(add) || 0)); }; Game.ComputeCps = function(base, mult, bonus) { return (base) * (Math.pow(2, mult)) + (bonus || 0); }; Game.addClickMult = function(mult) { for (var key in Game.Buffs) { var multClick = Game.Buffs[key].multClick; if (typeof multClick !== "undefined") { mult *= multClick; } } return mult; }; Game.calcCookiesPerClick = function(cps, includeBuffs) { var add = 0; if (Game.HasUpgrade("Thousand fingers")) { add += 0.1; } if (Game.HasUpgrade("Million fingers")) { add += 0.5; } if (Game.HasUpgrade("Billion fingers")) { add += 5; } if (Game.HasUpgrade("Trillion fingers")) { add += 50; } if (Game.HasUpgrade("Quadrillion fingers")) { add += 500; } if (Game.HasUpgrade("Quintillion fingers")) { add += 5000; } if (Game.HasUpgrade("Sextillion fingers")) { add += 50000; } if (Game.HasUpgrade("Septillion fingers")) { add += 500000; } if (Game.HasUpgrade("Octillion fingers")) { add += 5000000; } add *= Game.Get("ObjectsOwned") - Game.Objects["Cursor"].getAmount(); if (isNaN(cps)) { cps = Game.Get("cookiesPs"); } cps *= 0.01; if (Game.HasUpgrade("Plastic mouse")) { add += cps; } if (Game.HasUpgrade("Iron mouse")) { add += cps; } if (Game.HasUpgrade("Titanium mouse")) { add += cps; } if (Game.HasUpgrade("Adamantium mouse")) { add += cps; } if (Game.HasUpgrade("Unobtainium mouse")) { add += cps; } if (Game.HasUpgrade("Eludium mouse")) { add += cps; } if (Game.HasUpgrade("Wishalloy mouse")) { add += cps; } if (Game.HasUpgrade("Fantasteel mouse")) { add += cps; } if (Game.HasUpgrade("Nevercrack mouse")) { add += cps; } if (Game.HasUpgrade("Armythril mouse")) { add += cps; } if (Game.HasUpgrade("Technobsidian mouse")) { add += cps; } if (Game.HasUpgrade("Plasmarble mouse")) { add += cps; } var mult = 1; if (Game.HasUpgrade("Santa's helpers")) { mult = 1.1; } if (Game.HasUpgrade("Cookie egg")) { mult *= 1.1; } if (Game.HasUpgrade("Halo gloves")) { mult *= 1.1; } mult *= Game.eff("click"); var godLvl = Game.hasGod("labor"); //Muridal if (godLvl == 1) { mult *= 1.15; } else if (godLvl == 2) { mult *= 1.1; } else if (godLvl == 3) { mult *= 1.05; } if (includeBuffs) { mult = Game.addClickMult(mult); } if (Game.hasAura("Dragon Cursor")) { mult *= 1.05; } var out = mult * Game.ComputeCps(1, Game.HasUpgrade("Reinforced index finger") + Game.HasUpgrade("Carpal tunnel prevention cream") + Game.HasUpgrade("Ambidextrous"), add); if (Game.hasBuff("Cursed finger")) { out = Game.Buffs["Cursed finger"].power; } return out; }; Game.eff = function(name, def) { if (typeof Game.effs[name] === "undefined") { return (typeof def === "undefined" ? 1 : def); } else { return Game.effs[name]; } }; Game.setEffs = function() { //add up effect bonuses from building minigames var effs = {}; for (i = Game.ObjectsById.length - 1; i >= 0; i--) { var building = Game.ObjectsById[i]; if (building.minigame && building.minigame.effs) { var myEffs = Game.ObjectsById[i].minigame.effs; for (var ii in myEffs) { if (effs[ii]) { effs[ii] *= myEffs[ii]; } else { effs[ii] = myEffs[ii]; } } } } Game.effs = effs; }; Game.CalculateCookiesPs = function(earnedAchs, method) { if (!Array.isArray(earnedAchs)) { earnedAchs = []; } if (!method || typeof Game[method] !== "function") { method = "CalculateGains"; } var cpsObj = Game[method](); if (Game.predictiveMode && cpsObj.rawCookiesPs < Game.rawCookiesPs) { return cpsObj; } var earned = 0; for (var i = Game.CpsAchievements.length - 1; i >= 0; i--) { var achieve = Game.CpsAchievements[i]; if (!achieve.getWon() && achieve.require(cpsObj.rawCookiesPs)) { achieve.setWon(true); earned++; if (Game.predictiveMode) { earnedAchs.push(achieve); } } } if (earned > 0) { Game.Set("AchievementsOwned", Game.Get("AchievementsOwned") + earned); if (Game.Get("kittensOwned") > 0) { //recurse to see if you'd earn more cps achievements just from the milk gained //(probably not but better safe than sorry) cpsObj = Game.CalculateCookiesPs(earnedAchs, method); } } return cpsObj; }; Game.GetHeavenlyMultiplier = function() { var heavenlyMult = 0; if (Game.HasUpgrade("Heavenly chip secret")) { heavenlyMult += 0.05; } if (Game.HasUpgrade("Heavenly cookie stand")) { heavenlyMult += 0.20; } if (Game.HasUpgrade("Heavenly bakery")) { heavenlyMult += 0.25; } if (Game.HasUpgrade("Heavenly confectionery")) { heavenlyMult += 0.25; } if (Game.HasUpgrade("Heavenly key")) { heavenlyMult += 0.25; } if (Game.hasAura("Dragon God")) { heavenlyMult *= 1.05; } if (Game.HasUpgrade("Lucky digit")) { heavenlyMult *= 1.01; } if (Game.HasUpgrade("Lucky number")) { heavenlyMult *= 1.01; } if (Game.HasUpgrade("Lucky payout")) { heavenlyMult *= 1.01; } var godLvl = Game.hasGod("creation"); //Dotjeiess if (godLvl == 1) { heavenlyMult *= 0.7; } else if (godLvl == 2) { heavenlyMult *= 0.8; } else if (godLvl == 3) { heavenlyMult *= 0.9; } return heavenlyMult; }; Game.CalculateGains = function(heavenlyMult) { var mult = 1; var cpsObj = { cookiesPs: 0, cookiesPsBase: 0, cookiesPsByType: {}, cookiesMultByType: {} }; if (Game.ascensionMode !== 1) { if (isNaN(heavenlyMult)) { heavenlyMult = Game.GetHeavenlyMultiplier(); } mult += Game.Get("prestige") * 0.01 * Game.heavenlyPower * heavenlyMult; } mult *= Game.eff("cps"); if (Game.Has("Heralds") && Game.ascensionMode !== 1) { mult *= 1 + 0.01 * Game.heralds; } var hasResidualLuck = Game.HasUpgrade("Residual luck"); var goldenSwitchMult = 1.5; var eggMult = 1; for (var i = Game.UpgradesNoMisc.length - 1; i >= 0; i--) { var upgrade = Game.UpgradesNoMisc[i]; if (upgrade.getBought()) { if (upgrade.pool === "cookie" || upgrade.pseudoCookie) { mult *= 1 + (typeof upgrade.power === "function" ? upgrade.power(upgrade) : upgrade.power) * 0.01; } if (typeof upgrade.groups.plus === "number") { mult *= upgrade.groups.plus; } var addCps = upgrade.groups.addCps; if (typeof addCps === "number") { //"egg" cpsObj.cookiesPs += addCps; cpsObj.cookiesPsByType[upgrade.name] = addCps; } if (hasResidualLuck && upgrade.groups.goldSwitchMult) { goldenSwitchMult += 0.1; } if (upgrade.groups.commonEgg) { eggMult *= 1.01; } } } cpsObj.addCpsBase = cpsObj.cookiesPs; var godLvl = Game.hasGod("asceticism"); //Holobore if (godLvl == 1) { mult *= 1.15; } else if (godLvl == 2) { mult *= 1.1; } else if (godLvl == 3) { mult *= 1.05; } godLvl = Game.hasGod("ages"); //Cyclius if (godLvl == 1) { mult *= 1 + 0.15 * Math.sin((Game.lastUpdateTime / 1000 / (60 * 60 * 3)) * Math.PI * 2); } else if (godLvl == 2) { mult *= 1 + 0.15 * Math.sin((Game.lastUpdateTime / 1000 / (60 * 60 * 12)) * Math.PI * 2); } else if (godLvl == 3) { mult *= 1 + 0.15 * Math.sin((Game.lastUpdateTime / 1000 / (60 * 60 * 24)) * Math.PI * 2); } if (Game.HasUpgrade("Santa's legacy")) { mult *= 1 + (Game.Get("santaLevel") + 1) * 0.03; } Game.addBuildingCps(cpsObj); if (Game.HasUpgrade("Century egg")) { eggMult *= Game.CenturyEggBoost; } cpsObj.cookiesMultByType["eggs"] = eggMult; mult *= eggMult; if (Game.HasUpgrade("Sugar baking")) { mult *= (1 + Math.min(100, Game.lumps) * 0.01); } if (Game.hasAura("Radiant Appetite")) { mult *= 2; } if (Game.hasAura("Dragon's Fortune")) { for (i = 0; i < Game.numGoldenCookies; i++) { mult *= 2.23; } } cpsObj.preMilkMult = mult; mult = Game.addMilkMult(cpsObj, mult); cpsObj.rawMult = mult; cpsObj.rawCookiesPs = cpsObj.cookiesPs * mult; var extraMult = 1; var name = Game.bakeryNameLowerCase; if (name === "orteil") { extraMult *= 0.99; } else if (name === "ortiel") { //or so help me extraMult *= 0.98; } if (Game.HasUpgrade("Elder Covenant")) { extraMult *= 0.95; } if (Game.HasUpgrade("Golden switch [off]")) { extraMult *= goldenSwitchMult; } if (Game.HasUpgrade("Shimmering veil [off]")) { var veilMult = 0.5; if (Game.HasUpgrade("Reinforced membrane")) { veilMult += 0.1; } extraMult *= 1 + veilMult; } if (Game.HasUpgrade("Magic shenanigans")) { extraMult *= 1000; } if (Game.HasUpgrade("Occult obstruction")) { extraMult *= 0; } var multCpSTotal = 1; for (var key in Game.Buffs) { var multCpS = Game.Buffs[key].multCpS; if (typeof multCpS !== "undefined") { multCpSTotal *= multCpS; } } cpsObj.buffMultCps = multCpSTotal; cpsObj.unbuffedExtraMult = extraMult; var unbuffedMult = mult * extraMult; extraMult *= multCpSTotal; cpsObj.extraMult = extraMult; mult *= extraMult; cpsObj.globalCpsMult = mult; cpsObj.unbuffedGlobalCpsMult = unbuffedMult; cpsObj.unbuffedCookiesPs = cpsObj.cookiesPs * unbuffedMult; cpsObj.unbuffedCookiesPerClick = Game.calcCookiesPerClick(cpsObj.unbuffedCookiesPs, false); cpsObj.unbuffedCookiesPsPlusClicks = cpsObj.unbuffedCookiesPs + cpsObj.unbuffedCookiesPerClick * Game.clicksPs; cpsObj.cookiesPs *= mult; cpsObj.cookiesPerClick = Game.calcCookiesPerClick(cpsObj.cookiesPs, true); cpsObj.cookiesPsPlusClicks = cpsObj.cookiesPs + cpsObj.cookiesPerClick * Game.clicksPs; return cpsObj; }; //bit of a pain to do this, but optimizations help when there's so many .chains to check Game.CalculateBuildingGains = function() { var cpsObj = { cookiesPs: Game.addCpsBase, cookiesPsBase: 0, cookiesPsByType: {}, cookiesMultByType: {}, preMilkMult: Game.temp.cpsObj.preMilkMult, extraMult: Game.temp.cpsObj.extraMult }; Game.addBuildingCps(cpsObj); var mult = Game.temp.AchievementsOwned > Game.AchievementsOwned ? Game.addMilkMult(cpsObj, cpsObj.preMilkMult) : Game.temp.cpsObj.rawMult; cpsObj.rawMult = mult; cpsObj.rawCookiesPs = cpsObj.cookiesPs * mult; mult *= cpsObj.extraMult; cpsObj.globalCpsMult = mult; cpsObj.cookiesPs *= mult; cpsObj.cookiesPerClick = Game.calcCookiesPerClick(cpsObj.cookiesPs, true); cpsObj.cookiesPsPlusClicks = cpsObj.cookiesPs + cpsObj.cookiesPerClick * Game.clicksPs; return cpsObj; }; Game.setObjectGodMultiplier = function() { var buildMult = 1; var godLvl = Game.hasGod("decadence"); //Vomitrax if (godLvl == 1) { buildMult *= 0.93; } else if (godLvl == 2) { buildMult *= 0.95; } else if (godLvl == 3) { buildMult *= 0.98; } godLvl = Game.hasGod("industry"); //Jeremy if (godLvl == 1) { buildMult *= 1.1; } else if (godLvl == 2) { buildMult *= 1.06; } else if (godLvl == 3) { buildMult *= 1.03; } godLvl = Game.hasGod("labor"); //Muridal if (godLvl == 1) { buildMult *= 0.97; } else if (godLvl == 2) { buildMult *= 0.98; } else if (godLvl == 3) { buildMult *= 0.99; } Game.objectGodMult = buildMult; }; Game.addBuildingCps = function(cpsObj) { for (var i = Game.ObjectsById.length - 1; i >= 0; i--) { var building = Game.ObjectsById[i]; var amount = building.getAmount(); var cps = building.calcCps(building); if (Game.ascensionMode !== 1) { cps *= (1 + building.level * 0.01) * Game.objectGodMult; } var cpsTotal = cps * amount; cpsObj.cookiesPsBase += building.baseCps * amount; if (!Game.predictiveMode) { building.storedCps = cps; building.storedTotalCps = cpsTotal; } cpsObj.cookiesPs += cpsTotal; cpsObj.cookiesPsByType[building.name] = cpsTotal; } return cpsObj; }; Game.addMilkMult = function(cpsObj, mult) { var milkProgress = Game.Get("AchievementsOwned") / 25; cpsObj.milkProgress = milkProgress; if (Game.Get("kittensOwned") > 0) { var milkMult = 1; if (Game.HasUpgrade("Santa's milk and cookies")) { milkMult *= 1.05; } if (Game.hasAura("Breath of Milk")) { milkMult *= 1.05; } var godLvl = Game.hasGod("mother"); //Mokalsium if (godLvl == 1) { milkMult *= 1.1; } else if (godLvl == 2) { milkMult *= 1.05; } else if (godLvl == 3) { milkMult *= 1.03; } milkMult *= Game.eff("milk"); var catMult = 1; if (Game.HasUpgrade("Kitten helpers")) { catMult *= 1 + milkProgress * 0.1 * milkMult; } if (Game.HasUpgrade("Kitten workers")) { catMult *= 1 + milkProgress * 0.125 * milkMult; } if (Game.HasUpgrade("Kitten engineers")) { catMult *= 1 + milkProgress * 0.15 * milkMult; } if (Game.HasUpgrade("Kitten overseers")) { catMult *= 1 + milkProgress * 0.175 * milkMult; } if (Game.HasUpgrade("Kitten managers")) { catMult *= 1 + milkProgress * 0.2 * milkMult; } if (Game.HasUpgrade("Kitten accountants")) { catMult *= 1 + milkProgress * 0.2 * milkMult; } if (Game.HasUpgrade("Kitten specialists")) { catMult *= 1 + milkProgress * 0.2 * milkMult; } if (Game.HasUpgrade("Kitten experts")) { catMult *= 1 + milkProgress * 0.2 * milkMult; } if (Game.HasUpgrade("Kitten consultants")) { catMult *= 1 + milkProgress * 0.2 * milkMult; } if (Game.HasUpgrade("Kitten assistants to the regional manager")) { catMult *= 1 + milkProgress * 0.175 * milkMult; } if (Game.HasUpgrade("Kitten marketeers")) { catMult *= 1 + milkProgress * 0.15 * milkMult; } if (Game.HasUpgrade("Kitten analysts")) { catMult *= 1 + milkProgress * 0.125 * milkMult; } if (Game.HasUpgrade("Kitten angels")) { catMult *= 1 + milkProgress * 0.1 * milkMult; } cpsObj.cookiesMultByType["kittens"] = catMult; mult *= catMult; } return mult; }; Game.resetObjects = function() { for (var i = Game.ObjectsById.length - 1; i >= 0; i--) { Game.ObjectsById[i].resetTemp(); } Game.temp.ObjectsOwned = Game.ObjectsOwned; }; Game.resetUpgrades = function() { for (var i = Game.UpgradesById.length - 1; i >= 0; i--) { Game.UpgradesById[i].resetTemp(); } }; Game.resetAchievements = function(achsList, force) { if (!Array.isArray(achsList)) { achsList = Game.AchievementsById; } force = force || achsList === Game.AchievementsById; for (var i = achsList.length - 1; i >= 0; i--) { var achieve = achsList[i]; if (!force && !achieve.won && achieve.tempWon && Game.CountsAsAchievementOwned(achieve.pool)) { Game.temp.AchievementsOwned--; } achieve.tempWon = achieve.won; } if (force) { Game.temp.AchievementsOwned = Game.AchievementsOwned; } }; Game.setPredictiveMode = function() { Game.predictiveMode = true; Game.resetObjects(); Game.resetUpgrades(); Game.resetAchievements(); for (i in Game.temp) { var val = Game[i]; if (Array.isArray(val)) { val = val.slice(0); } else if (typeof val === "object" && val !== null) { val = $.extend({}, val); } Game.temp[i] = val; } }; // writes to children elements, where obj's keys map to class attributes Game.writeChildren = function($parent, obj) { $parent = $($parent); for (var c in obj) { var val = obj[c]; if (typeof val === "number") { val = Game.formatNumber(val, 1); } $parent.find("." + c).html(val); } return $parent; }; var recommendListSort = function(a, b) { return ((a.rate - b.rate) || (a.order - b.order) || ((a.chain ? a.chain.amount : 0) - (b.chain ? b.chain.amount : 0))); }; //#endregion methods //#region update() var updateScheduleTimer = null; var lastUpdateDelay = 1; var updateDelayedFuncs = []; // Delay update so page reflows happen first and/or to throttle inputs Game.scheduleUpdate = function(delay, afterUpdateFunc) { if (!isFinite(delay)) { delay = 1; } if (typeof afterUpdateFunc === "function") { updateDelayedFuncs.push(afterUpdateFunc); } delay = Math.max(delay, lastUpdateDelay) || lastUpdateDelay || 1; lastUpdateDelay = delay; clearTimeout(updateScheduleTimer); updateScheduleTimer = setTimeout(function() { Game.update(); for (var i = 0; i < updateDelayedFuncs.length; i++) { updateDelayedFuncs[i](); } updateDelayedFuncs = []; }, delay); }; Game.update = function() { Game.predictiveMode = false; clearTimeout(Game.updateTimer); clearTimeout(updateScheduleTimer); lastUpdateDelay = 1; Game.lastUpdateTime = Date.now(); var i, building, upgrade, achieve, req; for (i = Game.ObjectsById.length - 1; i >= 0; i--) { building = Game.ObjectsById[i]; if (building.minigame && building.minigame.updateFunc) { building.minigame.updateFunc(); } } Game.setEffs(); Game.setPriceMultArrays(); Game.ascensionMode = Number(byId("bornAgainCheck").checked); Game.sellMultiplier = Game.hasAura("Earth Shatterer") ? 0.5 : 0.25; Game.cookiesBaked = byId("cookiesBaked").parsedValue; Game.cookiesPs = 0; Game.buildingBuyInterval = 1; if (byId("multiBuildRecCheck").checked && byId("quantityTen").checked) { Game.buildingBuyInterval = 10; } Game.heavenlyMultiplier = Game.GetHeavenlyMultiplier(); var mult = Game.prestige * Game.heavenlyPower * Game.heavenlyMultiplier; //the boost increases a little every day, with diminishing returns up to +10% on the 100th day var day = Math.floor(Math.max(Game.lastUpdateTime - Game.startDate, 0) / 1000 / 10) * 10 / 60 / 60 / 24; day = Math.min(day, 100); Game.CenturyEggBoost = 1 + (1 - Math.pow(1 - day / 100, 3)) * 0.1; Game.clicksPs = 20; Game.maxChain = 1000; if (Game.maxChain < 0 || Game.maxChain > 1000) { Game.maxChain = 1000; } if (Game.clicksPs > 0 && Game.HasUpgrade("Shimmering veil [off]")) { Game.GetUpgrade("Shimmering veil [on]").setBought(true); } var santaIndex = Game.santa.dropEle.selectedIndex; Game.santaLevel = Math.max(Math.min(santaIndex - 1, Game.santaMax), 0) || 0; Game.setObjectGodMultiplier(); // Game.setDisabled(foolsNameCheck, Game.season === "fools"); // foolsNameCheck.checked = Game.season === "fools" ? true : foolsNameCheck.manualChecked; // var isFools = Game.season === "fools" || foolsNameCheck.checked; // var isFools = foolsNameCheck.checked; var bulkAmount = 1; //set building name and amounts and associated properties Game.ObjectsOwned = 0; Game.HighestBuilding = null; for (i = Game.ObjectsById.length - 1; i >= 0; i--) { building = Game.ObjectsById[i]; var amount = building.amountIn.parsedValue; building.amount = amount; building.level = building.levelIn.parsedValue; building.price = building.getPrice(); building.bulkPrice = building.getPriceSum(amount, amount + bulkAmount); building.$tooltipBlock = null; Game.ObjectsOwned += amount; if (!Game.HighestBuilding && amount) { Game.HighestBuilding = building; } } Game.UpgradesOwned = 0; Game.kittensOwned = 0; Game.UpgradesToCheck = []; Game.hasClickPercent = false; for (i = Game.UpgradesById.length - 1; i >= 0; i--) { upgrade = Game.UpgradesById[i]; if (upgrade.runFunc) { upgrade.runFunc(); } upgrade.isPerm = false; upgrade.statsStr = null; upgrade.cpsObj = null; upgrade.cps = 0; upgrade.rate = 0; upgrade.amort = 0; upgrade.recommendObj = null; if (upgrade.chain) { upgrade.chain.recommendObj = null; upgrade.chain.rate = 0; } upgrade.$blacklistEle.toggleClass("hidden", !upgrade.bought || !upgrade.blacklistCheckbox.checked) .toggleClass("strike", upgrade.bought && upgrade.blacklistCheckbox.checked); upgrade.$tooltipBlock = null; if (upgrade.noBuy && upgrade.bought) { //safety switch upgrade.bought = false; } if (upgrade.bought) { if (Game.CountsAsUpgradeOwned(upgrade.pool)) { Game.UpgradesOwned++; } if (upgrade.groups.kitten) { Game.kittensOwned++; } if (upgrade.groups.clickPercent) { Game.hasClickPercent += true; } } } if (Game.ascensionMode !== 1) { for (i = Game.permanentUpgrades.length - 1; i >= 0; i--) { upgrade = Game.GetUpgrade(Game.permanentUpgrades[i]); if (upgrade) { upgrade.isPerm = true; } } } Game.minCumulative = Math.max(Game.getMinCumulative() - Game.minCumulativeOffset, 0); $("#setCookiesBakedSpan").toggleClass("hidden", !isFinite(Game.cookiesBaked + Game.minCumulative) || Game.cookiesBaked >= Game.minCumulative); Game.cookiesBaked = Math.max(Game.cookiesBaked, Game.minCumulative); Game.AchievementsOwned = 0; var achievementsOwnedOther = 0; var showResetAchs = false; var showEnableAchs = false; var showDisableAchs = false; Game.LockedAchievements = []; for (i = Game.AchievementsById.length - 1; i >= 0; i--) { achieve = Game.AchievementsById[i]; req = achieve.require ? achieve.require() : false; if (!achieve.won && achieve.require && !achieve.groups.cpsAch) { if (req) { achieve.won = true; } else { Game.LockedAchievements.push(achieve); } } if (achieve.won) { if (Game.CountsAsAchievementOwned(achieve.pool)) { Game.AchievementsOwned++; } else { achievementsOwnedOther++; } if (!achieve.groups.cpsAch) { //ugh if (achieve.require) { showResetAchs = showResetAchs || !req; } showDisableAchs = showDisableAchs || !req; } } else if (!showEnableAchs && !achieve.groups.cpsAch && achieve.pool !== "dungeon") { showEnableAchs = true; } achieve.$crateNodes.toggleClass("enabled", achieve.won); } Game.buffMultClicks = Game.addClickMult(1); var cpsObj = Game.CalculateCookiesPs(); $.extend(Game, cpsObj); Game.cpsObj = cpsObj; //Game.garden.updateHarvestBonus(); for (i = Game.CpsAchievements.length - 1; i >= 0 && (!showResetAchs || !showDisableAchs); i--) { achieve = Game.CpsAchievements[i]; if (achieve.won) { req = achieve.require(); if (achieve.require) { showResetAchs = showResetAchs || !req; } showDisableAchs = showDisableAchs || !req; } else { showEnableAchs = true; } } var milkStr = Math.round(Game.milkProgress * 100); // byId("achMilk").innerHTML = Math.round(Game.milkProgress * 100) + "% (" + // Game.Milks[Math.min(Math.floor(Game.milkProgress), Game.Milks.length - 1)].name + ")"; var checkUpgrades = byId("hardcoreCheck").checked; var checkResearch = byId("researchCheck").checked; for (i = Game.UpgradesById.length - 1; i >= 0; i--) { upgrade = Game.UpgradesById[i]; upgrade.setPrice(); if (!upgrade.unlocked && upgrade.require) { upgrade.unlocked = Boolean(upgrade.require()); } if (checkUpgrades && !upgrade.bought && !upgrade.blacklistCheckbox.checked && Game.CountsAsUpgradeOwned(upgrade.pool) && (upgrade.pool !== "tech" || checkResearch) && (!upgrade.requiredUpgrade || Game.HasUpgrade(upgrade.requiredUpgrade))) { Game.UpgradesToCheck.push(upgrade); } upgrade.$crateNodes.toggleClass("unlocked", upgrade.unlocked).toggleClass("enabled", upgrade.bought); } Game.nextTech = null; if (Game.HasUpgrade("Bingo center/Research facility")) { for (i = Game.UpgradesByPool.tech.length - 1; i >= 0; i--) { upgrade = Game.UpgradesByPool.tech[i]; if (!upgrade.bought) { if (!upgrade.unlocked) { Game.nextTech = upgrade; } break; } } } // $('#researchCheckSpan').toggleClass('hidden', !Game.nextTech); var suckRate = 1 / 20; suckRate *= Game.eff("wrinklerEat"); var numWrinklers = Math.min(byId("numWrinklersIn").parsedValue, Game.maxWrinklers); Game.cpsSucked = numWrinklers * suckRate; var witherMult = 1 - Game.cpsSucked; Game.filterAchievements(); Game.updateDragon(); Game.updateBuffs(); Game.setPredictiveMode(); Game.recommendList = []; Game.updatePrestige(); Game.updateGoldenCookies(); var nextCps = "---"; var nextCpsPlusClicks = "---"; if (Game.cookiesPs > 0 && Game.kittensOwned > 0 && Game.AchievementsOwned < Game.AchievementsTotal) { Game.temp.AchievementsOwned = Game.AchievementsOwned + 1; var nextAchCpsObj = Game.CalculateGains(); nextCps = Math.abs(nextAchCpsObj.cookiesPs - Game.cookiesPs); nextCpsPlusClicks = Math.abs(nextAchCpsObj.cookiesPsPlusClicks - Game.cookiesPsPlusClicks); } Game.temp.AchievementsOwned = 0; var upgradeCpSDiff = Game.cookiesPs - Game.cookiesPsBase; if (Game.unbuffedGlobalCpsMult !== 0 && Game.buffMultCps === 0) { //sigh upgradeCpSDiff = 0; } Game.temp.AchievementsOwned = Game.AchievementsOwned; //santa var cond = santaIndex > 0 && Game.santaLevel < Game.santaMax; var price = Math.pow(Game.santaLevel + 1, Game.santaLevel + 1); Game.santa.price = price; var santaStr = cond ? Game.santaLevels[Game.santaLevel + 1] : "---"; Game.setDisabled("#noSantaOpt", Game.HasUpgrade("A festive hat")); var calcNextSanta = cond && Game.cookiesPs > 0 && Game.HasUpgrade("Santa's legacy"); Game.santa.recommendObj = null; var isSantaBlacklisted = Game.santa.blacklistCheckbox.checked; if (cond) { var nextSanta = santaStr; santaStr += " - Cost: " + Game.formatNumber(price); if (calcNextSanta) { Game.temp.santaLevel++; var santaCpsObj = Game.calculateChanges(price, []); santaStr += ", +" + Game.formatNumber(santaCpsObj.cookiesPsPlusClicksDiff, 1) + " cps"; Game.temp.santaLevel = Game.santaLevel; Game.resetAchievements(santaCpsObj.earnedAchs, true); if (!isSantaBlacklisted && santaCpsObj.rate > 0) { Game.santa.recommendObj = { type: "santa", gameObj: Game.santa, name: nextSanta + " (santa level)", price: price, cpsObj: santaCpsObj, earnedAchs: santaCpsObj.earnedAchs, rate: santaCpsObj.rate }; Game.recommendList.push(Game.santa.recommendObj); } } } Game.santa.$blacklistEle.toggleClass("hidden", !calcNextSanta && !isSantaBlacklisted) .toggleClass("strike", !calcNextSanta && isSantaBlacklisted); Game.updateBuildings(); Game.updateUpgrades(); Game.recommendList.sort(recommendListSort); Game.updateRecommended(); Game.updateBlacklist(); Game.predictiveMode = false; Game.sortAndFilterUpgrades(); if (typeof Game.updateTooltip === "function") { Game.updateTooltip(true); } upgrade = Game.Upgrades["Century egg"]; var check = Game.cookiesPs > 0 && (Game.hasGod("ages") || //Cyclius (day < 100 && (upgrade.unlocked || upgrade.bought || Game.tooltipUpgrade === upgrade))); if (check) { Game.updateTimer = setTimeout(Game.update, 1000 * 10); //10 seconds } }; function updateTab() { if (this && typeof this.updateTabFunc === "function") { this.updateTabFunc(); } } Game.updateBuildings = function() { var sum = { amount: Game.addCommas(Game.ObjectsOwned), desired: 0, buy1: 0, buy10: 0, buy100: 0, buyDesired: 0, cumu: 0, sell: 0 }; for (var i = Game.ObjectsById.length - 1; i >= 0; i--) { var building = Game.ObjectsById[i]; building.recommendObj = null; var cpsObj = Game.setChanges([{gameObj: building}], [], "CalculateBuildingGains"); var cps = building.storedTotalCps * Game.globalCpsMult; var percent = building.amount > 0 && Game.cookiesPs > 0 ? Game.Beautify(cps / Game.cookiesPs * 100, 1) : 0; var cpsWrite = Game.formatNumber(cps, 1, false, "", building.amount > 0 ? " (" + percent + "%)" : ""); Game.writeChildren(building.$cpsRow, { buildPrice: building.bulkPrice, cps: cpsWrite, time: Game.formatTime(Math.ceil(building.price / Game.cookiesPsPlusClicks)), nextCps: cpsObj.cookiesPsDiff, cpsPlus: cpsObj.cookiesPsPlusClicksDiff, amort: Game.formatTime(cpsObj.amort) }); var amount = building.amount; var desired = building.amountInDesired.parsedValue; var buy10 = building.getPriceSum(amount, amount + 10); var buy100 = building.getPriceSum(amount, amount + 100); var buyDesired = building.getPriceSum(amount, desired); var cumu = building.getPriceSum(0, amount); var sell = building.getSellSum(amount, desired); Game.writeChildren(building.$priceRow, { buy1: building.price, buy10: buy10, buy100: buy100, buyDesired: buyDesired, cumu: cumu, sell: sell }); sum.desired += desired; sum.buy1 += building.price; sum.buy10 += buy10; sum.buy100 += buy100; sum.buyDesired += buyDesired; sum.cumu += cumu; sum.sell += sell; if (!building.blacklistCheckbox.checked) { building.recommendObj = { type: building.type, name: building.getRecommendedName(building.amount + Game.buildingBuyInterval), gameObj: building, toAmount: building.amount + Game.buildingBuyInterval, price: Game.buildingBuyInterval === 10 ? buy10 : building.price, order: building.id, cpsObj: cpsObj, rate: cpsObj.rate }; Game.recommendList.push(building.recommendObj); } } Game.writeChildren("#buildPriceTotal", sum); }; Game.updateUpgrades = function() { if (!byId("hardcoreCheck").checked) { return; } var recommendChains = byId("multiBuildRecCheck").checked && Game.maxChain > 0; var recommendResearch = byId("researchCheck").checked; for (var i = Game.UpgradesToCheck.length - 1; i >= 0; i--) { var upgrade = Game.UpgradesToCheck[i]; if (upgrade.unlocked) { var cpsObj = upgrade.calcCps(); if (cpsObj && cpsObj.amort > 0 && cpsObj.rate > 0 && (upgrade.pool !== "tech" || recommendResearch) && (!upgrade.recommendFunc || upgrade.recommendFunc())) { upgrade.recommendObj = { type: upgrade.type, name: upgrade.iconName, price: upgrade.price, gameObj: upgrade, order: upgrade.order, cpsObj: cpsObj, rate: cpsObj.rate }; Game.recommendList.push(upgrade.recommendObj); upgrade.$blacklistEle.removeClass("hidden strike"); } } //upgrade chains (are a pain) var chain = upgrade.chain; if (chain && recommendChains && !upgrade.unlocked && chain.require()) { var chainCpsObj = Game.setChanges(Game.getUpgradeBuildChainChangeArr(upgrade, chain), [], "CalculateBuildingGains"); chain.rate = chainCpsObj.rate; if (chain.rate > 0) { var chainAmount = Game.getUpgradeBuildChainAmount(chain); chain.recommendObj = { type: "upgrade chain", name: "Chain for " + upgrade.iconName + ' ' + chain.building.getRecommendedName(chainAmount), title: chain.building.getRecommendedName(chainAmount) + "\n" + upgrade.iconName, gameObj: upgrade, price: chainCpsObj.price, building: chain.building, toAmount: chainAmount, order: upgrade.order, cpsObj: chainCpsObj, rate: chainCpsObj.rate }; Game.recommendList.push(chain.recommendObj); upgrade.$blacklistEle.removeClass("hidden strike"); } } } }; //sets temporary changes to the game state to calculate them, takes an array of js objects //{gameObj: [either Game.Object (aka building) or upgrade], amount: number (for buildings, defaults to current amount + 1)} //will pass setCpsNegative if set as an argument, as a property of the js obj, or if on the gameObj Game.setChanges = function(changeArr, earnedAchs, method, noCalc) { Game.predictiveMode = true; var resetArr = []; var price = 0; var setCpsNegative = false; var ObjectsOwned = Game.temp.ObjectsOwned; for (var i = changeArr.length - 1; i >= 0; i--) { var c = changeArr[i]; if (!c) { continue; } var gObj = c.gameObj; if (!gObj) { continue; } if (gObj.type === "building") { var nextAmount = c.amount || gObj.amount + Game.buildingBuyInterval; price += c.price || gObj.getPriceSum(gObj.tempAmount, nextAmount); Game.temp.ObjectsOwned += nextAmount - gObj.tempAmount; gObj.tempAmount = nextAmount; resetArr.push(gObj); } else if (gObj.type === "upgrade") { price += gObj.price; if (gObj.toggleInto && gObj.isChild) { gObj.toggleInto.setBought(); } else { gObj.setBought(); } if (Game.CountsAsUpgradeOwned(gObj.pool)) { Game.temp.UpgradesOwned += gObj.tempBought ? 1 : -1; } if (gObj.groups.kitten) { Game.temp.kittensOwned += gObj.tempBought ? 1 : -1; } resetArr.push(gObj); } setCpsNegative = setCpsNegative || c.setCpsNegative || gObj.setCpsNegative; } if (earnedAchs && earnedAchs.length) { for (i = earnedAchs.length - 1; i >= 0; i--) { var achieve = earnedAchs[i]; if (!achieve.tempWon && Game.CountsAsAchievementOwned(achieve.pool)) { Game.temp.AchievementsOwned++; } achieve.tempWon = true; } } if (noCalc) { return; } var toReturn = Game.calculateChanges(price, earnedAchs, setCpsNegative, method); for (i = resetArr.length - 1; i >= 0; i--) { resetArr[i].resetTemp(); } Game.temp.ObjectsOwned = ObjectsOwned; Game.temp.UpgradesOwned = Game.upgradesOwned; Game.temp.kittensOwned = Game.kittensOwned; Game.resetAchievements(toReturn.earnedAchs); return toReturn; }; //calculates cps changes and achievements earned based on changes //pass setCpsNegative to set the difference in cps from current as a loss Game.calculateChanges = function(price, earnedAchs, setCpsNegative, method) { price = Number(price) || 0; if (!Array.isArray(earnedAchs)) { earnedAchs = []; } Game.predictiveMode = true; for (i = Game.LockedAchievements.length - 1; i >= 0; i--) { var achieve = Game.LockedAchievements[i]; var arg = achieve.groups.bankAch ? price : undefined; //bit hacky but what can you do if (!achieve.tempWon && achieve.require && achieve.require(arg)) { achieve.tempWon = true; earnedAchs.push(achieve); if (Game.CountsAsAchievementOwned(achieve.pool)) { Game.temp.AchievementsOwned++; } } } var cpsObj = Game.CalculateCookiesPs(earnedAchs, method); var gameCpsObj = Game.temp.cpsObj; var mult = setCpsNegative ? -1 : 1; var cpscDiff = Math.abs(gameCpsObj.cookiesPsPlusClicks - cpsObj.cookiesPsPlusClicks) * mult; cpsObj.cookiesPsDiff = Math.abs(gameCpsObj.cookiesPs - cpsObj.cookiesPs) * mult; cpsObj.cookiesPerClickDiff = Math.abs(gameCpsObj.cookiesPerClick - cpsObj.cookiesPerClick) * mult; cpsObj.cookiesPsPlusClicksDiff = cpscDiff; cpsObj.earnedAchs = earnedAchs; cpsObj.price = price; cpsObj.rate = cpscDiff > 0 ? Math.max(price * cpsObj.cookiesPsPlusClicks / cpscDiff, 0) || 0 : 0; cpsObj.amort = cpscDiff > 0 ? Math.ceil(price / cpscDiff) || 0 : 0; return cpsObj; }; Game.updateDragon = function() { var lvlObj = Game.dragonLevels[Game.dragonLevel] || { name: "---", action: "---" }; var str = lvlObj.action || "---"; if (lvlObj.costStr) { str += " - Cost: " + lvlObj.costStr(); } byId("dragonName").textContent = lvlObj.name; $("#dragonAction").html(str).attr("data-title", lvlObj.actionTitle || "") .toggleClass("clickme", Game.dragonLevel < Game.dragonLevelMax && Boolean(lvlObj.cost ? lvlObj.cost() : true)); var $switchAura = $("#auraAvailable .aura.enabled"); var switchId = $switchAura.attr("data-aura"); var currentId = Game.$enabledAuraSlot ? Game.$enabledAuraSlot.attr("data-aura") : null; var otherId = Game.$enabledAuraSlot ? Game.$enabledAuraSlot.siblings().attr("data-aura") : null; $("#switchAuraBuy").html("Change aura (" + (Game.HighestBuilding ? "sacrifice 1 " + Game.HighestBuilding.displayName : "---") + ")") .toggleClass("hidden", !Game.HighestBuilding || !Game.$enabledAuraSlot || !$switchAura.length || currentId == switchId || (switchId > 0 && otherId == switchId)); $("#switchAuraFree").toggleClass("hidden", Game.$enabledAuraSlot && $switchAura.length && currentId == switchId); for (var i = Game.dragonAuras.length - 1; i >= 1; i--) { Game.dragonAuras[i].$crateNode.toggleClass("unlocked", Game.dragonLevel >= i + 4 && i != otherId); } $("#auraSlot0").toggleClass("unlocked", Game.dragonLevel > 4); $("#auraSlot1").toggleClass("unlocked", Game.dragonLevel >= Game.dragonLevelMax); }; Game.HCfactor = 3; Game.HowMuchPrestige = function(cookies) { //how much prestige [cookies] should land you return Math.pow(cookies / 1e12, 1 / Game.HCfactor); }; Game.HowManyCookiesReset = function(chips) { //how many cookies [chips] are worth //this must be the inverse of the above function (ie. if cookies = chips^2, chips = cookies^(1/2) ) return (Math.pow(chips, Game.HCfactor) * 1e12); //1 trillion }; //ugh floating point why must you be a pain Game.HowManyCookiesResetAdjusted = function(chips) { var cookies = Game.HowManyCookiesReset(chips); var i = 0; if (Game.HowMuchPrestige(cookies) < chips) { i = 1; while (Game.HowMuchPrestige(cookies + i) < chips) { i *= 10; } } return (cookies + i); }; Game.updateBuffs = function() { for (var i = Game.BuffTypes.length - 1; i >= 0; i--) { Game.BuffTypes[i].updateFunc(); } }; Game.updatePrestige = function() { Game.predictiveMode = true; var cookiesReset = byId("cookiesReset").parsedValue; var cookiesBakedAllTime = Game.cookiesBaked + cookiesReset; var cpsObj; var prestigeFromCookiesReset = Math.floor(Game.HowMuchPrestige(cookiesReset)); $("#setPrestigeSpan, #setCookiesResetSpan").toggleClass("hidden", prestigeFromCookiesReset === Game.prestige); byId("setPrestigeNum").innerHTML = Game.formatNumber(prestigeFromCookiesReset); var cookiesResetFromPrestige = Game.HowManyCookiesResetAdjusted(Game.prestige); var ele = byId("setCookiesResetNum"); ele.innerHTML = Game.formatNumber(cookiesResetFromPrestige); ele.setValue = cookiesResetFromPrestige; var heavenlyMult = Game.heavenlyMultiplier; if (!heavenlyMult) { heavenlyMult = 1; if (Game.hasAura("Dragon God")) { heavenlyMult *= 1.05; } } $("#prestigeGainCpsHelp, #prestigeDesiredCpsHelp").toggleClass("hidden", Game.heavenlyMultiplier > 0 || !Game.cookiesPs); //prestige gained from resetting var prestigeGain = Math.floor(Game.HowMuchPrestige(cookiesBakedAllTime)); var prestigeGainDiff = Math.max(prestigeGain - Game.prestige, 0) || 0; var gainStr = Game.formatNumber(prestigeGain) + " (+" + Game.formatNumber(prestigeGainDiff) + ")"; if (prestigeGainDiff > 0 && Game.prestige > 0) { gainStr += " (+" + Game.Beautify(prestigeGainDiff / prestigeGain * 100, 1) + "%)"; } byId("prestigeGain").innerHTML = gainStr; var cpsStr = "--- CpS"; if (prestigeGainDiff > 0 && Game.cookiesPs > 0) { Game.temp.prestige = prestigeGain; cpsObj = Game.CalculateGains(heavenlyMult); cpsStr = Game.formatNumber(cpsObj.cookiesPs, 1) + " CpS (+" + Game.formatNumber(Math.max(cpsObj.cookiesPs - Game.cookiesPs, 0), 1) + ")"; if (Game.clicksPs > 0) { cpsStr += ", " + Game.formatNumber(cpsObj.cookiesPsPlusClicks, 1) + " CpS (+" + Game.formatNumber(Math.max(cpsObj.cookiesPsPlusClicks - Game.cookiesPsPlusClicks, 0), 1) + ")"; } } byId("prestigeGainCps").innerHTML = cpsStr; var cookiesForNextLevel = Math.max(Game.HowManyCookiesResetAdjusted(prestigeGain + 1) - cookiesBakedAllTime, 0) || 0; var timeForNextLevel = Game.cookiesPsPlusClicks > 0 && cookiesForNextLevel > 0 ? Math.ceil(cookiesForNextLevel / Game.cookiesPsPlusClicks) : "---"; byId("cookiesNextPrestige").innerHTML = Game.formatNumber(cookiesForNextLevel); byId("cookiesNextPrestigeTime").innerHTML = Game.formatTime(timeForNextLevel); //prestige gained from desired (if applicable) var prestigeDesired = byId("prestigeDesiredIn").parsedValue; var prestigeDesiredDiff = Math.max(prestigeDesired - Game.prestige, 0) || 0; $("#prestigeDesiredGainRow, #cookiesPrestigeNeedRow").toggleClass("hidden", !prestigeDesiredDiff); gainStr = Game.formatNumber(prestigeDesired) + " (+" + Game.formatNumber(prestigeDesiredDiff) + ")"; if (prestigeDesiredDiff > 0 && Game.prestige > 0) { gainStr += " (+" + Game.Beautify(prestigeDesiredDiff / prestigeDesired * 100, 1) + "%)"; } byId("prestigeDesiredGain").innerHTML = gainStr; cpsStr = "--- CpS"; if (prestigeDesiredDiff > 0 && Game.cookiesPs > 0) { Game.temp.prestige = prestigeDesired; cpsObj = Game.CalculateGains(heavenlyMult); cpsStr = Game.formatNumber(cpsObj.cookiesPs, 1) + " CpS (+" + Game.formatNumber(Math.max(cpsObj.cookiesPs - Game.cookiesPs, 0), 1) + ")"; if (Game.clicksPs > 0) { cpsStr += ", " + Game.formatNumber(cpsObj.cookiesPsPlusClicks, 1) + " CpS (+" + Game.formatNumber(Math.max(cpsObj.cookiesPsPlusClicks - Game.cookiesPsPlusClicks, 0), 1) + ")"; } } byId("prestigeDesiredCps").innerHTML = cpsStr; var cookiesForDesired = Math.max(Game.HowManyCookiesResetAdjusted(prestigeDesired) - cookiesBakedAllTime, 0) || 0; var timeForDesired = Game.cookiesPsPlusClicks > 0 && cookiesForDesired > 0 ? Math.ceil(cookiesForDesired / Game.cookiesPsPlusClicks) : "---"; byId("cookiesPrestigeNeed").innerHTML = Game.formatNumber(cookiesForDesired); byId("cookiesPrestigeNeedTime").innerHTML = Game.formatTime(timeForDesired); Game.temp.prestige = Game.prestige; }; //golden cookies var gcShowClicks = false; var gcEffectMult = 1; var gcWrathEffectMult = 1; var gcDurationMult = 1; //list of effects; .calc for the table and .details if it's selected var gcEffectsList = [ { name: "Frenzy CpS", detailName: " frenzy", calc: function(str, cpsMultObj) { if (cpsMultObj.base || (cpsMultObj.current && (Game.buffMultCps === 1 || Game.buffMultCps === 0))) { return (str + '---'); } var html = Game.BeautifyAbbr(cpsMultObj.cookiesPs); var sum = Game.BeautifyAbbr(cpsMultObj.cookiesPs * cpsMultObj.duration); var title = cpsMultObj.duration + " seconds at " + Game.BeautifyAbbr(cpsMultObj.cookiesPs) + " CpS"; if (gcShowClicks) { title += " + " + Game.BeautifyAbbr(cpsMultObj.cookiesPerClick) + " per click"; sum = Game.BeautifyAbbr(cpsMultObj.cookiesPsPlusClicks * cpsMultObj.duration); } title += " = " + sum; return (str + "' + html + ""); }, details: function(cpsMultObj) { var sum = Game.formatNumber(cpsMultObj.cookiesPs * cpsMultObj.duration); var str = cpsMultObj.duration + " seconds at " + Game.formatNumber(cpsMultObj.cookiesPs) + " CpS"; if (gcShowClicks) { str += " + " + Game.formatNumber(cpsMultObj.cookiesPerClick) + " per click"; sum = Game.formatNumber(cpsMultObj.cookiesPsPlusClicks * cpsMultObj.duration); } return (str + " = " + sum); } }, { name: "Max Lucky!", detailName: " Max Lucky!", calc: function(str, cpsMultObj) { var mult = cpsMultObj.type === "wrath" ? gcWrathEffectMult : gcEffectMult; var html = mult * cpsMultObj.cookiesPs * 900 + 13; var title = "Bank: " + Game.BeautifyAbbr(Math.ceil(cpsMultObj.cookiesPs * 6000)); //60 * 15 / 0.15 return (str + "' + Game.BeautifyAbbr(html) + ""); }, details: function(frenzy) { var mult = frenzy.type === "wrath" ? gcWrathEffectMult : gcEffectMult; return (Game.formatNumber(mult * frenzy.cookiesPs * 900 + 13) + " - Bank: " + Game.formatNumber(Math.ceil(frenzy.cookiesPs * 6000))); } }, { name: "x777 Click frenzy", calc: function(str, cpsMultObj) { var cookiesPerClick = cpsMultObj.cookiesPerClick; if (!Game.hasBuff("Click frenzy")) { cookiesPerClick *= 777; } var duration = Math.ceil(13 * gcDurationMult); var html = Game.BeautifyAbbr(cookiesPerClick); var title = duration + " seconds at " + html + " per click"; if (Game.clicksPs > 0) { title += " = " + Game.BeautifyAbbr(cookiesPerClick * Game.clicksPs * duration); } return (str + "' + html + ""); }, details: function(cpsMultObj) { var cookiesPerClick = cpsMultObj.cookiesPerClick; if (!Game.hasBuff("Click frenzy")) { cookiesPerClick *= 777; } if (cpsMultObj.current && Game.hasBuff("Click frenzy")) { cookiesPerClick = cpsMultObj.cookiesPerClick; } var duration = Math.ceil(13 * gcDurationMult); return (duration + " seconds at " + Game.formatNumber(cookiesPerClick) + " per click" + (Game.clicksPs > 0 ? " = " + Game.formatNumber(cookiesPerClick * Game.clicksPs * duration) : "")); } }, { name: "x1111 Dragonflight", className: "dragonflight", calc: function(str, cpsMultObj) { var cookiesPerClick = cpsMultObj.cookiesPerClick; if (!Game.hasBuff("Dragonflight")) { cookiesPerClick *= 1111; } var duration = Math.ceil(10 * gcDurationMult); var html = Game.BeautifyAbbr(cookiesPerClick); var title = duration + " seconds at " + html + " per click"; if (Game.clicksPs > 0) { title += " = " + Game.BeautifyAbbr(cookiesPerClick * Game.clicksPs * duration); } return (str + "' + html + ""); }, details: function(cpsMultObj) { var cookiesPerClick = cpsMultObj.cookiesPerClick; if (!Game.hasBuff("Dragonflight")) { cookiesPerClick *= 1111; } var duration = Math.ceil(10 * gcDurationMult); return (duration + " seconds at " + Game.formatNumber(cookiesPerClick) + " per click" + (Game.clicksPs > 0 ? " = " + Game.formatNumber(cookiesPerClick * Game.clicksPs * duration) : "")); } } ]; var $gcTableTbody = $("#gCookiesTable tbody"); var gcCpsMults = [ { mult: 0.5, baseDuration: 66, type: "wrath" }, { mult: 1, baseDuration: 0, base: true }, { mult: 7, baseDuration: 77, reindeerMult: 0.75 }, { mult: 15, baseDuration: 60, type: "harvest" }, { mult: 666, baseDuration: 6, type: "wrath", reindeerMult: 0.5 } ]; var gcCpsMultCurrent = { mult: 1, baseDuration: 0, type: "current", current: true, reindeerMult: 1, header: byId("gCookiesCurrentBuffHeader") }; gcCpsMults.push(gcCpsMultCurrent); for (i = gcCpsMults.length - 1; i >= 0; i--) { var cpsMultObj = gcCpsMults[i]; cpsMultObj.className = cpsMultObj.type ? ' class="' + cpsMultObj.type + '"' : ""; } Game.updateGoldenCookies = function() { gcShowClicks = Game.cookiesPs > 0 && Game.clicksPs > 0 && Game.hasClickPercent; var gMult = Game.HasUpgrade("Green yeast digestives") ? 1.01 : 1; gcEffectMult = gMult * (Game.hasAura("Unholy Dominion") ? 1.1 : 1) * Game.eff("goldenCookieGain"); gcWrathEffectMult = gMult * (Game.hasAura("Ancestral Metamorphosis") ? 1.1 : 1) * Game.eff("wrathCookieGain"); /* $('#gCookiesInfo').toggleClass('hideWrath', !Game.HasUpgrade('One mind')) .toggleClass('hideHarvest', !Game.hasAura('Reaper of Fields')) .toggleClass('hideFlight', !Game.hasAura('Dragonflight')); */ gcDurationMult = Game.getGoldCookieDurationMod(); var duration; var mult = 1; if (Game.buffMultCps !== 1) { for (var name in Game.Buffs) { var buff = Game.Buffs[name]; if (buff.multCpS) { var time = buff.time / Game.fps; if (duration) { duration = Math.min(duration, time); } else { duration = time; } } } if (Game.hasBuff("Frenzy")) { mult *= 0.75; } if (Game.hasBuff("Elder frenzy")) { mult *= 0.5; } } gcCpsMultCurrent.mult = Game.buffMultCps; gcCpsMultCurrent.baseDuration = duration || 0; gcCpsMultCurrent.reindeerMult = mult; gcCpsMultCurrent.header.innerHTML = "x" + Game.formatNumber(Game.buffMultCps, 1); var reindeerHtml = ""; var reindeerBonusMult = 1; var reindeerBonusText = ""; if (Game.HasUpgrade("Ho ho ho-flavored frosting")) { reindeerBonusMult = 2; } reindeerBonusMult *= Game.eff("reindeerGain"); if (reindeerBonusMult !== 1) { reindeerBonusText = " x" + Game.Beautify(reindeerBonusMult, 2); } var currentIsRedundant = false; for (var i = gcCpsMults.length - 1; i >= 0; i--) { var cpsMultObj = gcCpsMults[i]; if (!cpsMultObj.current && cpsMultObj.mult === Game.buffMultCps) { currentIsRedundant = true; break; } } for (i = gcCpsMults.length - 1; i >= 0; i--) { cpsMultObj = gcCpsMults[i]; cpsMultObj.duration = Math.ceil(cpsMultObj.baseDuration * gcDurationMult); cpsMultObj.cookiesPs = Game.unbuffedCookiesPs * cpsMultObj.mult; cpsMultObj.cookiesPerClick = Game.calcCookiesPerClick(cpsMultObj.cookiesPs, true); cpsMultObj.cookiesPsPlusClicks = cpsMultObj.cookiesPs + Game.clicksPs * cpsMultObj.cookiesPerClick; if (cpsMultObj.current && currentIsRedundant) { continue; } var reindeerCookies = cpsMultObj.cookiesPs * 60; var frenzyReindeerMultText = ""; if (cpsMultObj.reindeerMult && cpsMultObj.reindeerMult !== 1) { reindeerCookies *= cpsMultObj.reindeerMult; frenzyReindeerMultText = " x" + cpsMultObj.reindeerMult; } reindeerHtml = "1 minute x" + Game.formatNumber(cpsMultObj.mult, 1) + " production" + reindeerBonusText + frenzyReindeerMultText + ": " + Game.formatNumber(Math.max(25, reindeerCookies) * reindeerBonusMult) + "" + reindeerHtml; } $("#reindeerWrite").html(reindeerHtml); $gcTableTbody.empty(); var len = gcEffectsList.length; for (i = 0; i < len; i++) { var effects = gcEffectsList[i]; var tr = $("").html("" + effects.name + "" + gcCpsMults.reduce(effects.calc, "")) .appendTo($gcTableTbody); if (effects.className) { tr.addClass(effects.className); } } Game.updateGoldenCookiesDetails(); }; Game.gcSelectedCells = []; Game.getGCCellFrenzyIndeces = function(cell) { var $cell = $(cell); var $par = $cell.parent(); return [$gcTableTbody.children().index($par), $par.children().index(cell)]; }; var gcTableTbody = $gcTableTbody[0]; var $gcClose = $('x'); Game.updateGoldenCookiesDetails = function() { $("#gCookiesTable .gcSelected").removeClass("gcSelected"); var $par = $("#gCookiesDetails").empty(); var hasSelected = false; // show details for cells that currently exist and are not hidden for (var i = Game.gcSelectedCells.length - 1; i >= 0; i--) { var indeces = Game.gcSelectedCells[i].split(","); var tr = gcTableTbody.children[indeces[0]]; if (!tr) { continue; } var cell = tr.children[indeces[1]]; var $cell = $(cell); if (cell && !$cell.hasClass("noSel")) { hasSelected = true; var effects = gcEffectsList[indeces[0]]; var cpsMultObj = gcCpsMults[indeces[1] - 1]; var $ele = $("x" + cpsMultObj.mult + (effects.detailName || (" + " + effects.name)) + ": " + effects.details(cpsMultObj) + "") .prependTo($par); $gcClose.clone().prependTo($ele)[0].gcIndex = Game.gcSelectedCells[i]; $cell.addClass("gcSelected"); } } $("#gCookiesDetailsBlock").toggleClass("hidden", !hasSelected); }; function processAchs(achs) { if (!achs || !Array.isArray(achs)) { return []; } var u = {}; var a = []; for (var i = 0, len = achs.length; i < len; i++) { if (!u.hasOwnProperty(achs[i].id)) { a.push(achs[i]); u[achs[i].id] = true; } } return a.sort(Game.sortByOrderFunc); } Game.updateRecommended = function () { var mode = Game.predictiveMode; if ($('#recommended').length === 0) { $("#topBar").append('