1. // ==UserScript==
  2. // @name CUnleash
  3. // @namespace http://tampermonkey.net/
  4. // @version 7.2
  5. // @description Unleash your cookie potential.
  6. // @author petar105
  7. // @match https://orteil.dashnet.org/cookieclicker/
  8. // @icon https://www.google.com/s2/favicons?domain=dashnet.org
  9. // @grant none
  10. // ==/UserScript==
  11. // If editing the script, ignore any "Game is not defined" warnings
  12. // Script is a mix of original code and other addons
  13. function tapNews() { if (Game.TickerEffect && Game.TickerEffect.type == 'fortune') { Game.tickerL.click(); } }
  14. setInterval(function () { tapNews(); }, 3000);
  15. (function() {
  16. 'use strict';
  17. let state = true; // initial state is ON
  18. let intervalId;
  19. document.addEventListener('keydown', function(event) {
  20. if (event.code === 'KeyX') {
  21. state = !state; // toggle state
  22. if (state) {
  23. // code to run when state is ON
  24. console.log('State is ON');
  25. startAutoClicker();
  26. } else {
  27. // code to run when state is OFF
  28. console.log('State is OFF');
  29. stopAutoClicker();
  30. }
  31. }
  32. });
  33. function startAutoClicker() {
  34. console.log('Auto-clicker started');
  35. Game.Notify(`Auto clicker ON`,`Press X to toggle`,[0,35],false);
  36. intervalId = setInterval(function() { Game.ClickCookie(); }, 4);
  37. }
  38. function stopAutoClicker() {
  39. console.log('Auto-clicker stopped');
  40. Game.Notify(`Auto clicker OFF`,`Press X to toggle`,[0,35],false);
  41. clearInterval(intervalId);
  42. }
  43. // Wait for the Game object to be defined, then start the auto-clicker
  44. const waitIntervalId = setInterval(function() {
  45. if (typeof Game !== 'undefined') {
  46. clearInterval(waitIntervalId);
  47. startAutoClicker();
  48. }
  49. }, 1000);
  50. })();
  51. setInterval(function() {
  52. Game.shimmers.forEach(function(shimmer)
  53. {
  54. if(shimmer.type == "golden" && shimmer.wrath == 0)
  55. {
  56. shimmer.pop()
  57. }
  58. })
  59. }, 500);
  60. var autoReindeer = setInterval(function() { for (var h in Game.shimmers){if(Game.shimmers[h].type=="reindeer"){Game.shimmers[h].pop();}} }, 100);
  61. var autoPopTwelveth = setInterval(function() {
  62. var wrinkCount = 0,
  63. wrinkEaten = 0,
  64. wrinkIndex = 10; // value for 10 shinies test
  65. for (var i in Game.wrinklers) {
  66. // count number of eating wrinks
  67. if (Game.wrinklers[i].sucked > 0) {
  68. wrinkCount += 1;
  69. }
  70. // find top wrink index, ignoring shiny wrinklers
  71. if (Game.wrinklers[i].sucked > wrinkEaten && Game.wrinklers[i].type == 0) {
  72. wrinkEaten = Game.wrinklers[i].sucked;
  73. wrinkIndex = i;
  74. }
  75. }
  76. // pop top wrinkler if 10 eating, unless all 12 are shiny
  77. if (wrinkCount == 10 && wrinkIndex != 10) {
  78. Game.wrinklers[wrinkIndex].hp = 0;
  79. }
  80. }, 60000);
  81. setTimeout(function() {
  82. Game.LoadMod("https://cookiemonsterteam.github.io/CookieMonster/dist/CookieMonster.js");
  83. }, 200); // Don't load Cookie Monster parallel with the game, CM loads but the game gets stuck
  84. setTimeout(function() {
  85. Game.LoadMod("https://rawgit.com/yannprada/cookie-garden-helper/master/cookie-garden-helper.js");
  86. }, 400); // Same goes for Cookie Garden Helper
  87. setTimeout(function() {
  88. // Announce transactions in game notifications
  89. const stockerTransactionNotifications = true
  90. // Make regular profit reports
  91. const stockerActivityReport = true
  92. // How often to make regular reports in ms (one hour by default)
  93. const stockerActivityReportFrequency = 1000 * 60 * 60
  94. // Make game notifications fade away on their own
  95. const stockerFastNotifications = false
  96. // Use console.log for more detailed info on trends
  97. const stockerConsoleAnnouncements = true
  98. // Logic loop frequency; do not touch it unless you are cheating.
  99. const stockerLoopFrequency = 1000 * 30
  100. // The cheat itself. Rolls the cycle every time logic loop triggers
  101. const stockerForceLoopUpdates = false
  102. const stockerGreeting = 'click clack you are now in debt'
  103. // ===================================================================================
  104. if (!stockList) {
  105. var stockList = {
  106. check: 'dump eet',
  107. goods: [],
  108. sessionStart: new Date(),
  109. sessionProfits: 0,
  110. sessionPurchases: 0,
  111. sessionSales: 0,
  112. stocksRising: 0
  113. }
  114. }
  115. var modeDecoder = ['stable','slowly rising','slowly falling','rapidly rising','rapidly falling','fluctuating'] // meanings of each market trend (good.mode)
  116. var goodIcons = [[2,33],[3,33],[4,33],[15,33],[16,33],[17,33],[5,33],[6,33],[7,33],[8,33],[13,33],[14,33],[19,33],[20,33],[32,33],[33,33],[34,33]];
  117. function stockerTimeBeautifier(duration) {
  118. var milliseconds = Math.floor((duration % 1000) / 100),
  119. //seconds = Math.floor((duration / 1000) % 60),
  120. minutes = Math.floor((duration / (1000 * 60)) % 60),
  121. hours = Math.floor((duration / (1000 * 60 * 60))); //% 24),
  122. //days = Math.floor((duration / (1000 * 60 * 60 * 24)));
  123. if (hours > 0) {
  124. if (hours == 1) {
  125. hours = hours + ' hour'
  126. }
  127. else hours = hours + ' hours'
  128. }
  129. else hours = -1;
  130. if (minutes >= 1) {
  131. minutes = (minutes == 1) ? minutes + ' minute' : minutes + ' minutes';
  132. }
  133. else minutes = -1;
  134. if ((hours != -1) && (minutes != -1)) { return hours + ' and ' + minutes; }
  135. else if ((hours == -1) && (minutes != -1)) { return minutes; }
  136. else if ((hours != -1) && (minutes == -1)) { return hours; }
  137. else if ((hours == -1) && (minutes == -1)) { return 'not that long actually'; }
  138. }
  139. setTimeout(function waitForGame() {
  140. if (typeof Game === 'object' && Game.ready) {
  141. Game.registerMod("gincookistocker",{
  142. init:function(){
  143. this.startStocking();
  144. },
  145. startStocking:function(){
  146. if (!Game.ObjectsById[5].minigame) {
  147. console.log('=====$$$== Stock Market minigame has not initialised yet! Will try again in 500ms.');
  148. setTimeout(() => {
  149. this.startStocking();
  150. },500);
  151. return
  152. }
  153. else {
  154. console.log('=====$$$== CookiStocker logic loop initialised at ' + new Date());
  155. console.log('=====$$$== With main options as follows:')
  156. console.log('=====$$$== Logic loop frequency: ' + stockerTimeBeautifier(stockerLoopFrequency))
  157. console.log('=====$$$== Report frequency: ' + stockerTimeBeautifier(stockerActivityReportFrequency))
  158. console.log('=====$$$== Cheating: ' + stockerForceLoopUpdates)
  159. Game.Notify(`CookiStocker is ready`,stockerGreeting,[1,33],false);
  160. console.log(stockList.check);
  161. }
  162. var market = Game.ObjectsById[5].minigame.goodsById; // read market
  163. console.log('Reading the market:');
  164. stockList.startingProfits = Game.ObjectsById[5].minigame.profit;
  165. for (let i = 0; i < market.length; i++){
  166. stockList.goods.push({
  167. name: market[i].name,
  168. stock: market[i].stock,
  169. restingPrice: 10*(i+1) + Game.ObjectsById[i].level - 1,
  170. currentPrice: market[i].val,
  171. mode: market[i].mode,
  172. lastMode: market[i].mode,
  173. priceBought: -1,
  174. });
  175. console.log('Stock: ' + market[i].name + ' Status: ' + modeDecoder[market[i].mode]);
  176. }
  177. if (stockerActivityReport) {
  178. var stockerReportInterval = setInterval(function() {
  179. var stockerUptime = new Date() - stockList.sessionStart;
  180. if ((stockList.sessionPurchases + stockList.sessionSales) == 0) {
  181. Game.Notify(
  182. 'CookiStocker report',
  183. 'This session has been running for ' + stockerTimeBeautifier(stockerUptime) +
  184. ', but no good investment opportunities were detected! Luck is not on our side, yet.'
  185. ,[26,7],stockerFastNotifications
  186. );
  187. } else {
  188. Game.Notify(
  189. 'CookiStocker report',
  190. 'This session has been running for ' + stockerTimeBeautifier(stockerUptime) +
  191. ', and has made ' + stockList.sessionProfits.toFixed(0) +
  192. '$ in ' + stockList.sessionPurchases + ' purchases and ' + stockList.sessionSales + ' sales.'
  193. ,[26,7],stockerFastNotifications
  194. );
  195. }
  196. },stockerActivityReportFrequency);
  197. }
  198. var stockerLoop = setInterval(function() {
  199. if (stockerForceLoopUpdates) Game.ObjectsById[5].minigame.tick();
  200. // setting stockerForceLoopUpdates to true will make the logic loop force the market to tick every time it triggers,
  201. // making this an obvious cheat, and i will personally resent you.
  202. // but
  203. // if you backup your save and set stockerLoopFrequency to like 10 milliseconds it looks very fun and effective.
  204. // yes, this is how i made the gif on the steam guide page.
  205. stockList.stocksRising = 0;
  206. market = Game.ObjectsById[5].minigame.goodsById; // update market
  207. for (let i = 0; i < market.length; i++){
  208. //let i = 3;
  209. // update stockList
  210. stockList.goods[i].stock = market[i].stock;
  211. stockList.goods[i].currentPrice = market[i].val;
  212. stockList.goods[i].mode = market[i].mode;
  213. let md = stockList.goods[i].mode;
  214. let lmd = stockList.goods[i].lastMode;
  215. if (
  216. (md != lmd) && (Game.ObjectsById[i+2].amount > 0) // new trend detected in a stock that is active
  217. )
  218. {
  219. if (stockerConsoleAnnouncements) {
  220. console.log(stockList.goods[i].name + ' has changed the mode from [' + modeDecoder[lmd] + '] to [' + modeDecoder[md] + ']');
  221. }
  222. if (lmd != 5 && md == 5) { // ignore unstable stocks
  223. if (stockerTransactionNotifications) Game.Notify(stockList.goods[i].name + ' went unstable','Ignoring the stock for a time',[1,33],stockerFastNotifications);
  224. }
  225. if ( // buy conditions
  226. (
  227. (lmd == 2) && ((md !=4) && (md!=5)) || // slow fall stopped
  228. (lmd == 4) && ((md !=2) && (md!=5)) || // fast fall stopped
  229. (lmd == 5) && ((md !=2) && (md!=4)) // chaotic stopped
  230. )
  231. &&
  232. (stockList.goods[i].currentPrice < stockList.goods[i].restingPrice) // only if the price is lower than resting price
  233. )
  234. {
  235. // buying
  236. stockList.goods[i].priceBought = stockList.goods[i].currentPrice;
  237. Game.ObjectsById[5].minigame.buyGood(i,10000);
  238. stockList.sessionPurchases++;
  239. if (stockerTransactionNotifications) Game.Notify('Buying ' + stockList.goods[i].name,'The price has stopped ' + modeDecoder[stockList.goods[i].lastMode] + ' at ' + Math.floor(stockList.goods[i].priceBought) + '$ per unit, and is ' + modeDecoder[stockList.goods[i].mode] + ' now.',goodIcons[i],stockerFastNotifications);
  240. if (stockerConsoleAnnouncements) console.log('=====$$$== Buying '+ stockList.goods[i].name);
  241. }
  242. if ( // sell conditions
  243. (stockList.goods[i].stock > 0) // only if the stock is present
  244. &&
  245. (
  246. (lmd == 1) && ((md !=3) && (md!=5)) || // slow rise stopped
  247. (lmd == 3) && ((md !=1) && (md!=5)) || // fast rise stopped
  248. (lmd == 5) && ((md !=1) && (md!=3)) // chaotic stopped
  249. )
  250. && (stockList.goods[i].currentPrice > stockList.goods[i].priceBought) // only if the price is higher than the price it was bought at
  251. )
  252. {
  253. // selling
  254. stockList.goods[i].priceBought = -1;
  255. Game.ObjectsById[5].minigame.sellGood(i,10000);
  256. stockList.sessionSales++;
  257. if (stockerTransactionNotifications) Game.Notify('Selling ' + stockList.goods[i].name,'At a profit of ' + Math.floor(stockList.goods[i].currentPrice - stockList.goods[i].priceBought) + '$ per unit (total ' + Math.floor(stockList.goods[i].currentPrice - stockList.goods[i].priceBought)*stockList.goods[i].stock + '$ profit), and is ' + modeDecoder[stockList.goods[i].mode] + ' now.',goodIcons[i],stockerFastNotifications);
  258. if (stockerConsoleAnnouncements) ('=====$$$== Selling '+ stockList.goods[i].name +' at a profit of ' + (stockList.goods[i].currentPrice - stockList.goods[i].priceBought).toFixed(2));
  259. }
  260. stockList.sessionProfits = Game.ObjectsById[5].minigame.profit - stockList.startingProfits;
  261. stockList.goods[i].lastMode = stockList.goods[i].mode // update last mode
  262. }
  263. }
  264. },stockerLoopFrequency);
  265. },
  266. });
  267. }
  268. else setTimeout(waitForGame,100)
  269. })
  270. }, 700); // CookiStocker is really fucking glitchy, I don't know why