z242

CookiStocker 2.3: main.js

Aug 14th, 2025 (edited)
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 40.51 KB | Gaming | 0 0
  1. //          Options
  2.  
  3.         // Automatic trading when true (not yet implemented)
  4.         var stockerAutoTrading = false
  5.  
  6.         // Minimum number of brokers required for automatic trading
  7.         var stockerMinBrokers = 58              // Default of 58 results in 1% commission
  8.        
  9.         // Announce transactions in game notifications
  10.         var stockerTransactionNotifications = true
  11.  
  12.         // Make regular profit reports
  13.         var stockerActivityReport = true
  14.             // How often to make regular reports in ms (one hour by default)
  15.             var stockerActivityReportFrequency = 1000 * 60 * 60
  16.  
  17.         // Make game notifications fade away on their own
  18.         var stockerFastNotifications = false
  19.  
  20.         // Use console.log for more detailed info on prices and trends
  21.         var stockerConsoleAnnouncements = false
  22.  
  23.         // Display more detailed trading info near the top of the stock market display
  24.         var stockerAdditionalTradingStats = true
  25.  
  26.         // Logic loop frequency; do not touch it unless you are cheating
  27.         var stockerLoopFrequency = 1000 * 30
  28.        
  29.         // The cheat itself. Rolls the cycle every time logic loop triggers
  30.         var stockerForceLoopUpdates = false
  31.  
  32.         var hideBogdanoff = true
  33.         var stockerGreeting = 'click clack you are now in debt'
  34.  
  35.  
  36.  
  37. // ===================================================================================
  38.  
  39. if(typeof CCSE == undefined)
  40.     Game.LoadMod('https://klattmose.github.io/CookieClicker/SteamMods/CCSE/main.js')
  41.  
  42. if(CookiStocker === undefined) var CookiStocker = {};
  43.  
  44. CookiStocker.name = 'CookiStocker';
  45. CookiStocker.version = '2.3';
  46. CookiStocker.GameVersion = '2.053';
  47.  
  48. if (stockList === undefined) {
  49.     var stockList = {
  50.         Check: 'dump eet',
  51.         Goods: [],
  52.         Start: Date.now() + 500,
  53.         lastTime: Date.now() + 500,
  54.         startingProfits: 0,
  55.         Profits: 0,
  56.         netProfits: 0,
  57.         grossProfits: 0,
  58.         grossLosses: 0,
  59.         totalStocks: 0,
  60.         totalShares: 0,
  61.         totalValue: 0,
  62.         unrealizedProfits: 0,
  63.         profitableStocks: 0,
  64.         unprofitableStocks: 0,
  65.         profitableTrades: 0,
  66.         unprofitableTrades: 0,
  67.         Purchases: 0,
  68.         Sales: 0,
  69.         Uptime: 0,
  70.         hourlyProfits: 0,
  71.         dailyProfits: 0,
  72.     }
  73. }
  74.  
  75. if (!hideBogdanoff) console.log('\n\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⢀⣀⣀⡀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠈⠛⢿⣷\n⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⡟⠁⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠉⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⣸⣿\n⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⢠⣾⣿⣿\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠈⢿⣿⣿⣿\n⠃⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀⠈⣿⣿⣿\n⠀⢀⠀⢠⠀⠀⠀⠀⠀⢿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡈⠻⠟⠛⠛⢿⣿⣿⡿⠇⠀⠀⠀⠀⠀⠀⣿⣿⣿\n⣶⣿⡀⠀⠀⠀⠀⠀⠀⠀⢻⣿⠋⠀⠀⣠⣤⣄⣀⣠⣀⡀⠀⠀⢀⣤⣴⣶⣿⣿⣿⣿⣿⡆⠀⠀⠀⢻⣿⡆⠀⠀⠀⠀⠀⠀⠀⠘⠋⠀\n⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠈⠁⠀⠀⠎⢀⣩⡽⣿⣿⣿⡏⠀⠀⠘⣿⣿⠟⠙⠿⠿⠟⠋⠀⠀⠀⠀⢀⣄⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⣿⣿⠉⠀⣠⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠀⠈⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠁⢀⣤⠄⠀⠀⠀⠀⠀⠸⡷⠀\n⣿⣿⣷⡾⠟⠋⠁⠀⠀⠀⢼⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀\n⣿⠟⠁⠀⠀⠀⠀⠀⠀⢀⣴⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠾⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⠀\n⣿⠀⠀⠀⠀⠀⠀⣰⠀⢸⣿⠛⠉⠂⠀⠀⠀⠀⠀⠀⠀⠶⠤⣴⣶⠾⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠏⠀⠀⠐⡫⢀⣾⡇⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣶⠀⠀⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣀⣀⣠⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⣠⣴⠀⠹⡇⢿⣿⠃⠀⠀⠐⡀⠀⢠⣴⠶⠿⠿⠿⠿⠿⠟⢛⡿⠿⣿⣿⣿⣄⠀⡆⠀⠸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠠⢾⣿⣟⣠⢉⣥⣼⡏⠀⠀⠀⠀⠘⣶⠁⠀⠀⢤⣤⣠⣤⣤⣶⡿⠃⠀⠹⣿⣿⣷⣾⠁⠀⠀⠀⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠘⣆⠀⠀⠀⠉⠛⠛⠛⠉⠀⠀⠀⢀⣿⣿⡟⠁⠀⠀⠀⠀⣰⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀\n⠀⠀⠀⠐⢿⠟⠋⠙⠻⣿⣃⣀⣀⣤⣤⣶⣾⣿⠁⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⠟⠉⠀⠀⠀⠀⠀⣴⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀\n⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⡆⠸⣦⣤⣄⣀⣀⣠⣤⣤⣴⠎⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣶⣤⣤⣄⣀\n⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠹⣏⠛⠛⠛⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⠀⠀⠀⢀⠀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠙⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n\n     wot iz he doing in ze console?\n\n\n');
  76.  
  77. var modeDecoder = ['stable','slowly rising','slowly falling','rapidly rising','rapidly falling','chaotic'] // meanings of each market trend (good.mode)
  78. 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],[35,33]];
  79.  
  80. CookiStocker.launch = function() {
  81.     this.isLoaded = 1;
  82. }
  83.  
  84. if (!CookiStocker.isLoaded){
  85.     if (CCSE && CCSE.isLoaded) {
  86.         CookiStocker.launch();
  87.     }
  88.     else {
  89.         if(!CCSE) var CCSE = {};
  90.         if(!CCSE.postLoadHooks) CCSE.postLoadHooks = [];
  91.         CCSE.postLoadHooks.push(CookiStocker.launch);
  92.     }
  93. }
  94.  
  95. function stockerTimeBeautifier(duration) {
  96.     var milliseconds = Math.floor(duration % 1000),
  97.       seconds = Math.floor((duration / 1000) % 60),
  98.       minutes = Math.floor((duration / (1000 * 60)) % 60),
  99.       hours = Math.floor((duration / (1000 * 60 * 60)) % 24),
  100.       days = Math.floor(duration / (1000 * 60 * 60 * 24));
  101.     if (seconds && (minutes || hours || days) && !stockerForceLoopUpdates)
  102.         seconds = 0;                        // Don't display
  103.     var strSeconds = seconds + ' second' + (seconds != 1 ? 's' : '');
  104.     var strMinutes = minutes ? minutes + ' minute' + (minutes != 1 ? 's' : '') + (seconds ? (hours || days ? ', and ' : ' and ') : '') : '';
  105.     var strHours = hours ? hours + ' hour' + (hours != 1 ? 's' : '') + (minutes && seconds ? ', ' : ((minutes ? !seconds : seconds) ? ' and ' : '')) : '';
  106.     var strDays = days ? days + ' day' + (days != 1 ? 's' : '') + (hours && minutes || hours && seconds || minutes && seconds ? ', ' : (((hours ? !minutes : minutes) ? !seconds : seconds) ? ' and ' : '')) : '';
  107.     var strTime = strDays + strHours + strMinutes;
  108.     if (stockerForceLoopUpdates && seconds)
  109.         strTime += strSeconds;
  110.     if (minutes || hours || days) {
  111.         return (strTime);
  112.     } else
  113.         return (strSeconds);
  114. }
  115.  
  116. //Game.registerHook('reset', CookiStocker.reset);
  117. //Game.registerHook('save', CookiStocker.save);
  118. //Game.registerHook('load', CookiStocker.load);
  119.  
  120. Game.registerMod('CookiStocker',{
  121.     init:function(){
  122.         this.startStocking();
  123.     },
  124.     startStocking:function(){
  125.         if (!Game.Objects['Bank'].minigame) {
  126.             console.log('=====$$$=== Stock Market minigame has not initialised yet! Will try again in 500 ms.');
  127.             setTimeout(() => {
  128.                 this.startStocking();
  129.             },500);
  130.             return
  131.         }
  132.         else {
  133.             console.log('=====$$$=== CookiStocker logic loop initialised at ' + new Date());
  134.             console.log('=====$$$=== With main options as follows:')
  135.             console.log('=====$$$=== Logic loop frequency: ' + stockerTimeBeautifier(stockerLoopFrequency))
  136.             console.log('=====$$$=== Report frequency: ' + stockerTimeBeautifier(stockerActivityReportFrequency))
  137.             console.log('=====$$$=== Cheating: ' + stockerForceLoopUpdates)
  138.             Game.Notify('CookiStocker is ready',stockerGreeting,[1,33],false);
  139.             console.log(stockList.Check);
  140.         }
  141.        
  142.         let datStr
  143.             = '<div>'
  144.             + '<div style="display: inline-block; padding: 1px 8px;position:relative;margin:-10px;left:20px;">'
  145.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Net profits: <span id="Profits">$0</span>.'
  146.             + '<div style="display: inline-block; padding: 1px 8px;">'
  147.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Profits per hour: <span id="profitsHour">$0</span>.'
  148.             + '<div style="display: inline-block; padding: 1px 8px;">'
  149.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Profits per day: <span id="profitsDay">$0</span>.'
  150.             + '<div style="display: inline-block; padding: 1px 8px;">'
  151.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Gross profits: <span id="grossProfits">$0</span>.'
  152.             + '<div style="display: inline-block; padding: 1px 8px;">'
  153.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Gross losses: <span id="grossLosses">$0</span>.'
  154.             + '<div style="display: inline-block; padding: 1px 8px;">'
  155.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + (stockerForceLoopUpdates ? 'Runtime: <span id="runTime">0:00:00</span>' : 'Runtime: <span id="runTime">0:00</span>')
  156.             + '</div>'
  157.             + '</div>';
  158.  
  159.         let datStr2 = (stockerAdditionalTradingStats ? '<div>'
  160.             + '<div style="display: inline-block; padding: 1px 8px;position:relative;margin:-10px;left:20px;">'
  161.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Net cookies: <span id="netCookies">0</span>.'
  162.             + '<div style="display: inline-block; padding: 1px 8px;">'
  163.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Cookies per hour: <span id="cookiesHour">0</span>.'
  164.             + '<div style="display: inline-block; padding: 1px 8px;">'
  165.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Cookies per day: <span id="cookiesDay">0</span>.'
  166.             + '<div style="display: inline-block; padding: 1px 8px;">'
  167.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Purchases: <span id="Purchases">0</span>.'
  168.             + '<div style="display: inline-block; padding: 1px 8px;">'
  169.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Sales: <span id="Sales">0</span>.'
  170.             + '</div>'
  171.             + '</div>' : '');
  172.  
  173.         let datStr3 = (stockerAdditionalTradingStats ? '<div>'
  174.             + '<div style="display: inline-block; padding: 1px 8px;position:relative;margin:-10px;left:20px;">'
  175.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'CPS multiple: <span id="cpsMultiple">0</span>.'
  176.             + '<div style="display: inline-block; padding: 1px 8px;">'
  177.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Stocks held: <span id="stocksHeld">' + stockList.totalStocks + '</span>.'
  178.             + '<div style="display: inline-block; padding: 1px 8px;">'
  179.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Total shares: <span id="totalShares">' + Beautify(stockList.totalShares, 0) + '</span>.'
  180.             + '<div style="display: inline-block; padding: 1px 8px;">'
  181.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Total value: <span id="totalValue">' + Beautify(stockList.totalValue, 2) + '</span>.'
  182.             + '<div style="display: inline-block; padding: 1px 8px;">'
  183.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Unrealized profits: <span id="unrealizedProfits">' + Beautify(stockList.unrealizedProfits, 0) + '</span>.'
  184.             + '</div>'
  185.             + '</div>' : '');
  186.  
  187.         let datStr4 = (stockerAdditionalTradingStats ? '<div>'
  188.             + '<div style="display: inline-block; padding: 1px 8px;position:relative;margin:-10px;left:20px;">'
  189.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Profitable stocks: <span id="profitableStocks">0</span>.'
  190.             + '<div style="display: inline-block; padding: 1px 8px;">'
  191.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Unprofitable stocks: <span id="unprofitableStocks">0</span>.'
  192.             + '<div style="display: inline-block; padding: 1px 8px;">'
  193.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Profitable trades: <span id="profitableTrades">0</span>.'
  194.             + '<div style="display: inline-block; padding: 1px 8px;">'
  195.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Unprofitable trades: <span id="unprofitableTrades">0</span>.'
  196.             + '<div style="display: inline-block; padding: 1px 8px;">'
  197.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Average profit per trade: <span id="averageProfit">$0</span>.'
  198.             + '<div style="display: inline-block; padding: 1px 8px;">'
  199.             + '<div style="font-size:10px;color:rgba(255,255,255,0.8);">' + 'Average loss per trade: <span id="averageLoss">$0</span>.'
  200.             + '</div>'
  201.             + '</div>' : '');
  202.  
  203.         l('bankHeader').firstChild.insertAdjacentHTML('beforeend', datStr);
  204.         if (stockerAdditionalTradingStats) {
  205.             l('bankHeader').firstChild.insertAdjacentHTML('beforeend', datStr2);
  206.             l('bankHeader').firstChild.insertAdjacentHTML('beforeend', datStr3);
  207.             l('bankHeader').firstChild.insertAdjacentHTML('beforeend', datStr4);
  208.         }
  209.         CookiStocker.ReplaceGameMenu();
  210.  
  211. /*      let M = {}
  212.         M.parent=Game.Objects['Bank'];
  213.         M.parent.minigame=M;
  214.         M = Game.Objects['Bank'].minigame;
  215. */      let market = Game.Objects['Bank'].minigame.goodsById;   // read market
  216.         console.log('Reading the market:');
  217.         stockList.startingProfits = Game.Objects['Bank'].minigame.profit;
  218.         for (let i = 0; i < market.length; i++){
  219.             stockList.Goods.push({
  220.                 name: market[i].name,
  221.                 stock: market[i].stock,
  222.                 currentPrice: market[i].val,
  223.                 mode: market[i].mode,
  224.                 lastMode: market[i].mode,
  225.                 lastDur: market[i].dur,
  226.                 unchangedDur: 0,
  227.                 dropCount: 0,
  228.                 riseCount: 0,
  229.                 profit: 0,
  230.                 someSold: false,
  231.                 someBought: false,
  232.             });
  233.             console.log('Stock: ' + market[i].name.replace('%1', Game.bakeryName) + ' Status: ' + modeDecoder[market[i].mode] + ' at $' + market[i].val + (market[i].stock ? ' (own)' : ''));
  234.         }
  235.  
  236.         CookiStocker.TradingStats();
  237.         if (stockerForceLoopUpdates)
  238.             Game.Objects['Bank'].minigame.secondsPerTick = stockerLoopFrequency / 1000;
  239.         var stockerLoop = setInterval(function() {
  240.             let doUpdate = false;
  241.            
  242.             // setting stockerForceLoopUpdates to true will make the logic loop force the market to tick every time it triggers,
  243.             // making this an obvious cheat, and i will personally resent you.  
  244.             //
  245.             // but
  246.             // if you backup your save and set stockerLoopFrequency to like 10 milliseconds it looks very fun and effective.
  247.             // yes, this is how i made the gif on the steam guide page.  [Comment by Gingerguy.]
  248.             if (!stockerForceLoopUpdates)
  249.                 stockerLoopFrequency = Game.Objects['Bank'].minigame.secondsPerTick * 500;      // Keep up to date
  250.             const smallDelta = 3;
  251.             const largeDelta = 4;
  252.             const alwaysBuyBelow = 2;
  253.             const neverSellBelow = 11;
  254.  
  255.             setTimeout(function waitForGame() {
  256.                 if (typeof Game !== 'object' || !Game.ready) {
  257.                     setTimeout(waitForGame, 500);
  258.                 }
  259.             })
  260.                
  261.             let M = CookiStocker;
  262.             M.Achievements = [];
  263. //          M.Achievements.push(CCSE.NewAchievement('Plasmic assets', 'Have your stock market profits surpass <b>$100 million</b>.<p>This will get you charged up!</q><q>Your warehouse companies double their space.</q>',[12,33]));
  264. //          M.Achievements.push(CCSE.NewAchievement('Bose-Einstein Condensed Assets', 'Have your stock market profits surpass <b>$500 million</b>.<q>You have so many assets, we need to condense them!</q><q>Your warehouse companies double their space.</q>', [18,33]));
  265.             Game.last.pool = 'shadow';
  266. //          Game.Achievements['Plasmic Assets'].won = 0;
  267. //          Game.Achievements['Bose-Einstein Condensed Assets'].won = 0;
  268.             for(var i = 0; i < M.Achievements.length; i++) M.Achievements[i].order = 1002000 + i / 100;
  269.            
  270.             market = Game.Objects['Bank'].minigame.goodsById;   // update market
  271.             for (let i = 0; i < market.length; i++) {
  272.                
  273.                 let lastPrice = stockList.Goods[i].currentPrice;
  274.                 let currentPrice = market[i].val;
  275.  
  276.                 // update stockList
  277.                 stockList.Goods[i].stock = market[i].stock;
  278.                 stockList.Goods[i].currentPrice = market[i].val;
  279.                 stockList.Goods[i].mode = market[i].mode;
  280.  
  281.                 let md = stockList.Goods[i].mode;
  282.                 let lmd = stockList.Goods[i].lastMode;
  283.                 let lastStock = market[i].stock;
  284.                 let deltaPrice = largeDelta;
  285.                 let stockName = stockList.Goods[i].name.replace('%1', Game.bakeryName);
  286.                
  287.                 // Our ceilingPrice is the maximum of the bank ceiling and the (deprecated but still useful) stock ceiling
  288.                 let ceilingPrice = Math.max(10*(i+1) + Game.Objects['Bank'].level + 49, 97 + Game.Objects['Bank'].level * 3);
  289.  
  290.                 if (Game.ObjectsById[i+2].amount == 0) {        // stock must be active
  291.                     console.log(`${stockName} stock is inactive`);
  292.                     continue;
  293.                 }
  294.                 if (lmd == md && (stockList.Goods[i].stock && (md == 2 || md == 4) ||   // Make selling into a downturn easier
  295.                 !stockList.Goods[i].stock && (md == 1 || md == 3)))         // Make buying into an upturn easier
  296.                     deltaPrice = smallDelta;
  297.                 if (md != lmd && (md == 3 && lmd != 1 || md == 4 && lmd != 2 || md == 1 && lmd != 3 || md == 2 && lmd != 4)) {
  298.                     stockList.Goods[i].dropCount = 0;
  299.                     stockList.Goods[i].riseCount = 0;
  300.                 } else if (currentPrice > lastPrice) {
  301.                     stockList.Goods[i].dropCount = 0;
  302.                     stockList.Goods[i].riseCount++;
  303.                 } else if (currentPrice < lastPrice) {
  304.                     stockList.Goods[i].riseCount = 0;
  305.                     stockList.Goods[i].dropCount++;
  306.                 }
  307.                 if (stockList.Goods[i].lastDur != market[i].dur || ++stockList.Goods[i].unchangedDur > 1) {
  308.                     stockList.Goods[i].unchangedDur = 0;
  309.                     doUpdate = true;
  310.                 }
  311.                 if (stockerConsoleAnnouncements && doUpdate) {          // Tick tick
  312.                     if (md == lmd)
  313.                         console.log(`${stockName} mode is unchanged at ${lmd} [${modeDecoder[lmd]}] at $${Beautify(currentPrice, 2)}`);
  314.                     else
  315.                         console.log(`MODE CHANGE ${stockName} old mode was ${lmd} [${modeDecoder[lmd]}] and new mode is ${md} [${modeDecoder[md]}] at $${Beautify(currentPrice, 2)}`);
  316.                 }
  317.                 stockList.Goods[i].lastDur = market[i].dur;
  318.                 if (    // buy conditions
  319.                     (
  320.                         currentPrice < alwaysBuyBelow || md != 4 && ((currentPrice > lastPrice &&
  321.                         stockList.Goods[i].riseCount >= deltaPrice || (md == 1 || md == 3) && md != lmd ||
  322.                         md == 0 && !stockList.Goods[i].someSold && stockList.Goods[i].dropCount < deltaPrice &&
  323.                         currentPrice >= 10) && (currentPrice < ceilingPrice || md == 1 || md == 3))
  324.                     )
  325.                     && (((Game.Objects['Bank'].minigame.getGoodMaxStock(market[i]) * Game.cookiesPsRawHighest) < (Game.cookies * 0.05)) && Game.Objects['Bank'].minigame.brokers >= stockerMinBrokers)
  326.                     && Game.Objects['Bank'].minigame.buyGood(i,10000)   // actual buy attempt
  327.                 )
  328.                 {
  329.                     // buying
  330.                     console.log(`Buy: ${Game.Objects['Bank'].minigame.getGoodMaxStock(market[i]) * Game.cookiesPsRawHighest}, Max: ${Game.cookies * .03}`);
  331.                     let mode = (lmd != md) ? 'is no longer in ' + modeDecoder[lmd] + ' mode' : 'is ';
  332.                     let units = market[i].stock - lastStock;
  333.  
  334.                     stockList.Goods[i].someBought = true;
  335.                     stockList.Goods[i].stock = market[i].stock;
  336.                     if (market[i].prevBuyMode1 != undefined)
  337.                     {
  338.                         market[i].prevBuyMode1 = lmd;
  339.                         market[i].prevBuyMode2 = md;
  340.                     }
  341.                     market[i].buyTime = Date.now();
  342.                     if (typeof StockAssistant != 'undefined')
  343.                     {
  344.                         StockAssistant.stockData.goods[i].boughtVal = market[i].prev;
  345.                         StockAssistant.buyGood(i);
  346.                     }
  347.                     stockList.Purchases++;
  348.                     if (stockerTransactionNotifications)
  349.                         if (currentPrice >= 2) Game.Notify(`Buying ${stockName} ${new Date().toLocaleTimeString([], {hourCycle: 'h23', hour: '2-digit', minute: '2-digit'})}`,`Buying ${units} unit${(units > 1 ? 's' : '')}. The stock ${mode} at $${Beautify(market[i].prev, 2)} per unit (your buying price) and is in ${modeDecoder[md]} mode now.`,goodIcons[i],stockerFastNotifications);
  350.                         else Game.Notify(`Buying ${stockName} ${new Date().toLocaleTimeString([], {hourCycle: 'h23', hour: '2-digit', minute: '2-digit'})}`, `Buying ${units} unit${(units > 1 ? 's' : '')}. The price has dropped below $2 per unit, and your buying price is $${Beautify(market[i].prev, 2)}.`,goodIcons[i],stockerFastNotifications);
  351.                     if (stockerConsoleAnnouncements) console.log('=====$$$=== Buying '+ stockName + ' at $' + Beautify(market[i].prev, 2));
  352.                 } else if ( // sell conditions
  353.                     stockList.Goods[i].stock > 0 && (currentPrice < lastPrice &&
  354.                     stockList.Goods[i].dropCount >= deltaPrice ||
  355.                     (md == 2 || md == 4) && md != lmd) && currentPrice >= neverSellBelow    // not near the bottom
  356.                 )
  357.                 {
  358.                     let profit = 0;
  359.                     let strProfit = 'profit '
  360.                     let mode = (lmd != md) ? 'is no longer in ' + modeDecoder[lmd] + ' mode and ' : '';
  361.  
  362.                     if (!Game.Objects['Bank'].minigame.sellGood(i,stockList.Goods[i].stock)) {
  363.                         stockList.Goods[i].lastMode = stockList.Goods[i].mode;
  364.                         continue;
  365.                     }
  366.                     stockList.Goods[i].someSold = true;
  367.                     market[i].prevSale = market[i].val;
  368.                     market[i].prevSellMode1 = lmd;
  369.                     market[i].prevSellMode2 = md;
  370.                     market[i].sellTime = Date.now();
  371.                     if (typeof StockAssistant != 'undefined')
  372.                         StockAssistant.sellGood(i);
  373.                     stockList.Sales++;
  374.                     profit = (market[i].val - market[i].prev) * stockList.Goods[i].stock;
  375.                     stockList.Goods[i].profit += profit;
  376.                     if (profit > 0) {
  377.                         stockList.grossProfits += profit;
  378.                         stockList.profitableTrades++;
  379. /*                      if (Game.Objects['Bank'].minigame.profit >= 100000000 && !Game.Achievements['Plasmic assets'].won) {
  380.                              Game.Win('Plasmic assets');
  381.                              Game.Achievements['Plasmic Assets'].won = 1    // Shouldn't be necessary
  382.                              for (let j = 0; j < market.length; j++) {
  383.                                 market[j].building.highest = Game.Objects['Bank'].minigame.getGoodMaxStock(market[j]) * 2;
  384.                             }
  385.                         } else if (Game.Objects['Bank'].minigame.profit >= 500000000 && !Game.Achievements['Bose-Einstein Condensed Assets'].won) {
  386.                              Game.Win('Bose-Einstein Condensed Assets');
  387.                              Game.Achievements['Bose-Einstein Condensed Assets'].won = 1    // Shouldn't be necessary
  388.                              for (let j = 0; j < market.length; j++) {
  389.                                 market[j].building.highest = Game.Objects['Bank'].minigame.getGoodMaxStock(market[j]) * 2;
  390.                              }
  391.                         }
  392. */                  } else {
  393.                         stockList.grossLosses += -profit;
  394.                         stockList.unprofitableTrades++;
  395.                     }
  396.                     stockList.netProfits += profit;
  397.                     stockerModeProfits[lmd][md][0] += profit;
  398.                     stockerModeProfits[lmd][md][1] += profit;
  399.                     stockerModeProfits[lmd][md][2]++;
  400.                     if (profit < 0)
  401.                     {
  402.                         strProfit = 'loss ';
  403.                         profit = -profit;
  404.                     }
  405.                     if (stockerTransactionNotifications) Game.Notify(`Selling ${stockName} ${new Date().toLocaleTimeString([], {hourCycle: 'h23', hour: '2-digit', minute: '2-digit'})}`,`Selling ${stockList.Goods[i].stock} unit${(stockList.Goods[i].stock > 1 ? 's' : '')} at a price of $${Beautify(market[i].val, 2)} per unit for a ${strProfit} of $${Beautify(profit, 2)} and total revenue of $${Beautify(market[i].val*stockList.Goods[i].stock, 2)}, which is added to the total market profits. The stock ${mode} is in ${modeDecoder[md]} mode now. Bought at a price of $${Beautify(market[i].prev, 2)} per unit.`,goodIcons[i],stockerFastNotifications);
  406.                     if (stockerConsoleAnnouncements) console.log(`=====$$$=== Selling ${stockName} at $${Beautify(market[i].val, 2)} for a ${strProfit}of $${Beautify(profit, 2)} and total revenue of $${Beautify(market[i].val*stockList.Goods[i].stock, 2)}. Last bought at $${Beautify(market[i].prev, 2)}.`);
  407.                 }
  408.                
  409.                 stockList.Profits = Game.Objects['Bank'].minigame.profit - stockList.startingProfits;
  410.                 stockList.Goods[i].lastMode = stockList.Goods[i].mode;
  411.             }
  412.             stockList.profitableStocks = stockList.unprofitableStocks = 0;
  413.             for (let i = 0; i < market.length; i++) {           // Must recalculate the whole list on every pass
  414.                 if (stockList.Goods[i].profit > 0)
  415.                     stockList.profitableStocks++;
  416.                 else if (stockList.Goods[i].profit < 0)
  417.                     stockList.unprofitableStocks++;
  418.             }
  419.             CookiStocker.TradingStats();
  420.  
  421.         },stockerLoopFrequency);
  422.  
  423.         let stockerModeProfits = [
  424.             [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
  425.             [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
  426.             [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
  427.             [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
  428.             [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
  429.             [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
  430.         ];
  431.  
  432.         if (stockerActivityReport || stockerConsoleAnnouncements) {
  433.             var stockerReportInterval = setInterval(function() {
  434.                 let j, k;
  435.  
  436.                 if (stockerActivityReport)
  437.                     if ((stockList.Purchases + stockList.Sales) == 0) {
  438.                         Game.Notify(
  439.                             `CookiStocker report ${new Date().toLocaleTimeString([], {hourCycle: 'h23', hour: '2-digit', minute: '2-digit'})}`,
  440.                             `This session has been running for ${stockerTimeBeautifier(stockList.Uptime)}, but no good investment opportunities were detected! Luck is not on our side, yet.`
  441.                             ,[1, 33],stockerFastNotifications
  442.                         );
  443.                     } else {
  444.                         Game.Notify(
  445.                             `CookiStocker report ${new Date().toLocaleTimeString([], {hourCycle: 'h23', hour: '2-digit', minute: '2-digit'})}`,
  446.                             `This session has been running for ${stockerTimeBeautifier(stockList.Uptime)} and has made $${Beautify(stockList.netProfits, 0)} in net profits and $${Beautify(stockList.Profits, 0)} in revenue (displayed profits) in ${Beautify(stockList.Purchases, 0)} purchases and ${Beautify(stockList.Sales, 0)} sales.`,[1, 33],stockerFastNotifications
  447.                         );
  448.                     }
  449.                 if (stockerConsoleAnnouncements) {
  450.                     let totalProfits = 0;
  451.                     let subtotalProfits = 0;
  452.                     let deltaTotalProfits = 0;
  453.                     let deltaSubtotalProfits = 0;
  454.                     let totalTrades = 0;
  455.                     let subtotalTrades = 0;
  456.                     let profit = 0;
  457.                     let lastProfit = 0;
  458.                     let trades = 0;
  459.                     let strProfit = '';
  460.                     let strDeltaModeProfits = '';
  461.                     let strTrades = '';
  462.  
  463.                     console.log(`Running for ${stockerTimeBeautifier(stockList.Uptime)} and made $${Beautify(stockList.netProfits, 0)}\n  in net profits and $${Beautify(stockList.Profits, 0)} in revenue (displayed profits)\n  in ${Beautify(stockList.Purchases, 0)} purchases and ${Beautify(stockList.Sales, 0)} sales.\nTotal number of stocks held: ${stockList.totalStocks}.  Total shares: ${Beautify(stockList.totalShares, 0)}.\nTotal value: $${Beautify(stockList.totalValue)}.  Unrealized profits: $${Beautify(stockList.unrealizedProfits, 2)}.\nTotal gross profits:  $${Beautify(stockList.grossProfits, 0)}.  Profitable stocks:  ${stockList.profitableStocks}.\nProfitable trades:  ${stockList.profitableTrades}.  Average profit per trade:  $${stockList.grossProfits ? Beautify(stockList.grossProfits / stockList.profitableTrades, 2) : 0}.\nTotal gross losses:  $${Beautify(stockList.grossLosses, 0)}.  Unprofitable stocks:  ${stockList.unprofitableStocks}.\nUnprofitable trades:  ${stockList.unprofitableTrades}.  Average loss per trade:  $${stockList.grossLosses ? Beautify(stockList.grossLosses / stockList.unprofitableTrades, 2) : 0}.`);
  464.                    
  465.                     // Stats for individual modes
  466.                     for (j = 0; j < 6; j++)
  467.                         for (k = 0; k < 6; k++)
  468.                             totalProfits += stockerModeProfits[j][k][0];
  469.                     for (j = 0; j < 6; j++)
  470.                         for (k = 0; k < 6; k++) {
  471.                             profit = stockerModeProfits[j][k][0];
  472.                             lastProfit = stockerModeProfits[j][k][1];
  473.                             trades = stockerModeProfits[j][k][2];
  474.                             strProfit = profit ? ((100 * profit/totalProfits).toFixed(2) + '%').padStart(8) : '';
  475.                             strDeltaModeProfits = (lastProfit ? '$' + Beautify(lastProfit, 2) : '').padStart(14);
  476.                             strTrades = trades ? (' ' + trades + ' trade' + (trades > 1 ? 's' : ' ')).padStart(13) : '';
  477.                            
  478.                             console.log(`Profits[${j}][${k}] = $${Beautify(profit, 2).padEnd(14)} ${strProfit}${strDeltaModeProfits}${strTrades}`);
  479.                             subtotalProfits += profit;
  480.                             deltaSubtotalProfits += lastProfit;
  481.                             deltaTotalProfits += lastProfit;
  482.                             subtotalTrades += trades;
  483.                             totalTrades += trades;
  484.                         }
  485.                        
  486.                     // Stats for subtotals
  487.                     for (j = 0; j < 6; j++) {
  488.                         subtotalProfits = 0;
  489.                         deltaSubtotalProfits = 0;
  490.                         subtotalTrades = 0;
  491.                         for (k = 0; k < 6; k++) {
  492.                             subtotalProfits += stockerModeProfits[j][k][0];
  493.                             deltaSubtotalProfits += stockerModeProfits[j][k][1];
  494.                             subtotalTrades += stockerModeProfits[j][k][2];
  495.                             stockerModeProfits[j][k][1] = 0;
  496.                         }
  497.                         strProfit = subtotalProfits ? ((100 * subtotalProfits/totalProfits).toFixed(2) + '%').padStart(8) : '';
  498.                         strDeltaModeProfits = (deltaSubtotalProfits ? '$' + Beautify(deltaSubtotalProfits, 2) : '').padStart(14);
  499.                         strTrades = subtotalTrades ? (' ' + subtotalTrades + ' trade' + (subtotalTrades > 1 ? 's' : ' ')).padStart(13) : '';
  500.                        
  501.                         console.log(`Subtotal[${j}]`.padEnd(14) + `= $${Beautify(subtotalProfits, 2).padEnd(14)} ${strProfit}${strDeltaModeProfits}${strTrades}`);
  502.                         subtotalProfits = 0;
  503.                         deltaSubtotalProfits = 0;
  504.                         subtotalTrades = 0;
  505.                     }
  506.                    
  507.                     // Stats for totals
  508.                     stockList.hourlyProfits = totalProfits * (stockerLoopFrequency / 60_000) * 3600_000 / stockList.Uptime;
  509.                     stockList.dailyProfits = totalProfits * (stockerLoopFrequency / 60_000) * 86_400_000 / stockList.Uptime;
  510.  
  511.                     if (!stockerForceLoopUpdates) {
  512.                         stockList.hourlyProfits *= 2;
  513.                         stockList.dailyProfits *= 2;
  514.                     }
  515.                     console.log(`Total profits = $${Beautify(totalProfits, 2).padEnd(22)}${(deltaTotalProfits ? '$' + Beautify(deltaTotalProfits, 2) : '').padStart(15)}${totalTrades ? (' ' + totalTrades + ' trade' + (totalTrades > 1 ? 's' : ' ')).padStart(13) : ''}`);
  516.                     console.log(`Profit per hour = $${Beautify(stockList.hourlyProfits, 2)}; profit per day = $${Beautify(stockList.dailyProfits, 2)}`);
  517.                     console.log(`That's ${Beautify(stockList.hourlyProfits * Game.cookiesPsRawHighest, 2)} cookies and ${Beautify(stockList.dailyProfits * Game.cookiesPsRawHighest, 2)} cookies, respectively. It's also ${Beautify((stockList.hourlyProfits / 3600), 0)} times your highest raw cookie production rate.`);
  518.                     if (stockerForceLoopUpdates) {
  519.                         console.log('In unadjusted, true numbers:');
  520.                         stockList.hourlyProfits *= 60_000 / stockerLoopFrequency;
  521.                         stockList.dailyProfits *= 60_000 / stockerLoopFrequency;
  522.                         console.log(`Profit per hour = $${Beautify(stockList.hourlyProfits, 2)}; profit per diem = $${Beautify(stockList.dailyProfits, 2)}`);
  523.                         console.log(`That's ${Beautify(stockList.hourlyProfits * Game.cookiesPsRawHighest, 2)} cookies and ${Beautify(stockList.dailyProfits * Game.cookiesPsRawHighest, 2)} cookies, respectively. It's also ${Beautify((stockList.hourlyProfits / 3600), 0)} times your highest raw cookie production rate.`);
  524.                     }
  525.                     console.log('------------------------------------------------------------------');
  526.                 }
  527.                 CookiStocker.TradingStats();
  528.  
  529.             },stockerActivityReportFrequency);
  530.         }
  531.     },
  532. })
  533.  
  534. CookiStocker.DataStats = function(id, value) {
  535.     let it = l(id);
  536.        it.innerHTML = (value < 0 ? "-" : "") + (id.includes('ookies') ? '' : '$') + Beautify(Math.abs(value), 0);              
  537.        if (value > 0) {
  538.            it.classList.add("green");
  539.            it.classList.remove("red");
  540.        } else if (value < 0) {
  541.            it.classList.add("red");
  542.            it.classList.remove("green");
  543.        }
  544. }
  545.  
  546. CookiStocker.TradingStats = function()
  547. {
  548.     let j;
  549.     let now = Date.now();
  550.     let market = Game.Objects['Bank'].minigame.goodsById;
  551.  
  552.     if (now > stockList.lastTime + stockerActivityReportFrequency + 500) {      // Were we sleeping?
  553.         stockList.Start += now - stockList.lastTime - stockerActivityReportFrequency;
  554.     }
  555.  
  556.     stockList.totalStocks = 0;
  557.     stockList.totalShares = 0;
  558.     stockList.totalValue = 0;
  559.     stockList.unrealizedProfits = 0;
  560.     for (j = 0; j < market.length; j++) {
  561.         if (stockList.Goods[j].stock) {
  562.             stockList.totalStocks++;
  563.             stockList.totalShares += stockList.Goods[j].stock;
  564.             stockList.totalValue += stockList.Goods[j].stock * stockList.Goods[j].currentPrice;
  565.             stockList.unrealizedProfits += (market[j].val - market[j].prev) * stockList.Goods[j].stock;
  566.         }
  567.     }
  568.     CookiStocker.DataStats("Profits", stockList.netProfits);
  569.     CookiStocker.DataStats("profitsHour", stockList.hourlyProfits);
  570.     CookiStocker.DataStats("profitsDay", stockList.dailyProfits);
  571.     CookiStocker.DataStats("grossProfits", stockList.grossProfits);
  572.     CookiStocker.DataStats("grossLosses", -stockList.grossLosses);
  573.     stockList.lastTime = now;
  574.     stockList.Uptime = Math.floor((now - stockList.Start) / 1000) * 1000;
  575.     stockList.Uptime -= stockList.Uptime % stockerLoopFrequency;
  576.     let uptimeHours = Math.floor(stockList.Uptime / 3600000) + ':';
  577.     let it = l("runTime");
  578.     if (stockerForceLoopUpdates) {
  579.         it.innerHTML = uptimeHours + new Date(stockList.Uptime).toLocaleTimeString([], {minute: '2-digit', second: '2-digit'});
  580.     } else {
  581.         let uptimeMinutes = (Math.floor(stockList.Uptime / 60000)) % 60;
  582.         it.innerHTML = uptimeHours + (uptimeMinutes < 10 ? '0' : '') + uptimeMinutes;
  583.     }
  584.     if (stockerAdditionalTradingStats) {
  585.         CookiStocker.DataStats("netCookies", stockList.netProfits * Game.cookiesPsRawHighest);
  586.         CookiStocker.DataStats("cookiesHour", stockList.hourlyProfits * Game.cookiesPsRawHighest);
  587.         CookiStocker.DataStats("cookiesDay", stockList.dailyProfits * Game.cookiesPsRawHighest);
  588.         l("Purchases").innerHTML = stockList.Purchases;
  589.         l("Sales").innerHTML = stockList.Sales;
  590.         l("cpsMultiple").innerHTML = Beautify(stockList.hourlyProfits / 3600, 3);
  591.         l("stocksHeld").innerHTML = stockList.totalStocks;
  592.         l("totalShares").innerHTML = Beautify(stockList.totalShares);
  593.         CookiStocker.DataStats("totalValue", stockList.totalValue);
  594.         CookiStocker.DataStats("unrealizedProfits", stockList.unrealizedProfits);
  595.         l("profitableStocks").innerHTML = stockList.profitableStocks;
  596.         l("unprofitableStocks").innerHTML = stockList.unprofitableStocks
  597.         l("profitableTrades").innerHTML = stockList.profitableTrades;
  598.         l("unprofitableTrades").innerHTML = stockList.unprofitableTrades;
  599.         CookiStocker.DataStats("averageProfit", stockList.profitableTrades ? stockList.grossProfits / stockList.profitableTrades : 0);
  600.         CookiStocker.DataStats("averageLoss", stockList.unprofitableTrades ? -stockList.grossLosses / stockList.unprofitableTrades : 0);
  601.     }
  602.     if (it.innerHTML == '')        
  603.         it.innerHTML = "0:00";
  604. }
  605.  
  606. CookiStocker.ReplaceGameMenu = function()
  607. {
  608.     Game.customOptionsMenu.push(function()
  609.     {
  610. //      CCSE.AppendCollapsibleOptionsMenu(CookiStocker.name, CookiStocker.getMenuString());
  611.     });
  612.    
  613.     Game.customStatsMenu.push(function()
  614.     {
  615.         CCSE.AppendStatsVersionNumber(CookiStocker.name, CookiStocker.version);
  616.         if (CookiStocker.isLoaded && typeof Game === 'object' && Game.ready) {
  617.             console.log("Profit: $" + Game.Objects['Bank'].minigame.profit);
  618.             let profit = Game.Objects['Bank'].minigame.profit;
  619.             console.log('profit: ' + profit);
  620.  
  621.             if (profit)
  622.                 CCSE.AppendStatsGeneral('<div class="listing"><b>Stock Market has earned you :</b> <div class="stock price"> $' + Beautify(profit) + ' (' + Game.tinyCookie() + Beautify(profit * Game.cookiesPsRawHighest, 3) + '</div></div>');
  623.         }
  624.     });
  625. }
  626.  
  627. CookiStocker.getMenuString = function() {
  628.     let str = '';
  629. }
  630.  
  631. CookiStocker.save = function() {
  632.     var str = '';
  633.  
  634.     let market = Game.Objects['Bank'].minigame.goodsById;
  635.     str += parseInt(stockList.Check);
  636.     for (let i = 0; i < market.length; i++) {
  637.         str += '_' + parseInt(stockList.Goods[i].name);
  638.         str += '_' + parseInt(stockList.Goods[i].stock);
  639.         str += '_' + parseInt(stockList.Goods[i].val);
  640.         str += '_' + parseInt(stockList.Goods[i].currentPrice);
  641.         str += '_' + parseInt(stockList.Goods[i].mode);
  642.         str += '_' + parseInt(stockList.Goods[i].lastMode);
  643.         str += '_' + parseInt(stockList.Goods[i].lastDur);
  644.         str += '_' + parseInt(stockList.Goods[i].unchangedDur);
  645.         str += '_' + parseInt(stockList.Goods[i].dropCount);
  646.         str += '_' + parseInt(stockList.Goods[i].riseCount);
  647.         str += '_' + parseInt(stockList.Goods[i].profit);
  648.         str += '_' + parseInt(stockList.Goods[i].someSold);
  649.         str += '_' + parseInt(stockList.Goods[i].someBought);
  650.     }
  651.     str += '_' + parseInt(stockList.Start);
  652.     str += '_' + parseInt(stockList.lastTime);
  653.     str += '_' + parseInt(stockList.startingProfits);
  654.     str += '_' + parseInt(stockList.Profits);
  655.     str += '_' + parseInt(stockList.netProfits);
  656.     str += '_' + parseInt(stockList.grossProfits);
  657.     str += '_' + parseInt(stockList.grossLosses);
  658.     str += '_' + parseInt(stockList.totalStocks);
  659.     str += '_' + parseInt(stockList.totalShares);
  660.     str += '_' + parseInt(stockList.totalValue);
  661.     str += '_' + parseInt(stockList.unrealizedProfits);
  662.     str += '_' + parseInt(stockList.profitableStocks);
  663.     str += '_' + parseInt(stockList.unprofitableStocks);
  664.     str += '_' + parseInt(stockList.profitableTrades);
  665.     str += '_' + parseInt(stockList.unprofitableTrades);
  666.     str += '_' + parseInt(stockList.Purchases);
  667.     str += '_' + parseInt(stockList.Sales);
  668.     str += '_' + parseInt(stockList.Uptime);
  669.     str += '_' + parseInt(stockList.hourlyProfits);
  670.     str += '_' + parseInt(stockList.dailyProfits);
  671.     return str;
  672. }
  673.  
  674. CookiStocker.load = function(str) {
  675.     let i = 0;
  676.     let spl = str.split('_');
  677.  
  678.     if(!str) return false;
  679.     let market = Game.Objects['Bank'].minigame.goodsById;
  680.     stockList.Check = parseInt(spl[i++] || 0);
  681.     for (let j = 0; j < market.length; j++) {
  682.         stockList.Goods[j].name = parseInt(spl[i++] || 0);
  683.         stockList.Goods[j].stock = parseInt(spl[i++] || 0);
  684.         stockList.Goods[j].val = parseInt(spl[i++] || 0);
  685.         stockList.Goods[j].currentPrice = parseInt(spl[i++] || 0);
  686.         stockList.Goods[j].mode = parseInt(spl[i++] || 0);
  687.         stockList.Goods[j].lastMode = parseInt(spl[i++] || 0);
  688.         stockList.Goods[j].lastDur = parseInt(spl[i++] || 0);
  689.         stockList.Goods[j].unchangedDur = parseInt(spl[i++] || 0);
  690.         stockList.Goods[j].dropCount = parseInt(spl[i++] || 0);
  691.         stockList.Goods[j].riseCount = parseInt(spl[i++] || 0);
  692.         stockList.Goods[j].profit = parseInt(spl[i++] || 0);
  693.         stockList.Goods[j].someSold = parseInt(spl[i++] || 0);
  694.         stockList.Goods[j].someBought = parseInt(spl[i++] || 0);
  695.     }
  696.     stockList.Start = parseInt(spl[i++] || 0);
  697.     stockList.lastTime = parseInt(spl[i++] || 0);
  698.     stockList.startingProfits = parseInt(spl[i++] || 0);
  699.     stockList.Profits = parseInt(spl[i++] || 0);
  700.     stockList.netProfits = parseInt(spl[i++] || 0);
  701.     stockList.grossProfits = parseInt(spl[i++] || 0);
  702.     stockList.grossLosses = parseInt(spl[i++] || 0);
  703.     stockList.totalStocks = parseInt(spl[i++] || 0);
  704.     stockList.totalShares = parseInt(spl[i++] || 0);
  705.     stockList.totalValue = parseInt(spl[i++] || 0);
  706.     stockList.unrealizedProfits = parseInt(spl[i++] || 0);
  707.     stockList.profitableStocks = parseInt(spl[i++] || 0);
  708.     stockList.unprofitableStocks = parseInt(spl[i++] || 0);
  709.     stockList.profitableTrades = parseInt(spl[i++] || 0);
  710.     stockList.unprofitableTrades = parseInt(spl[i++] || 0);
  711.     stockList.Purchases = parseInt(spl[i++] || 0);
  712.     stockList.Sales = parseInt(spl[i++] || 0);
  713.     stockList.Uptime = parseInt(spl[i++] || 0);
  714.     stockList.hourlyProfits = parseInt(spl[i++] || 0);
  715.     stockList.dailyProfits = parseInt(spl[i++] || 0);
  716. }
  717.  
  718. CookiStocker.reset = function(hard) {
  719.     let M = CookiStocker;
  720.  
  721.     stockList.Goods = [];
  722.     for (let i = 0; i < market.length; i++) {
  723.         stockList.Goods.push({
  724.             name: market[i].name,
  725.             stock: market[i].stock,
  726.             currentPrice: market[i].val,
  727.             mode: market[i].mode,
  728.             lastMode: market[i].mode,
  729.             lastDur: market[i].dur,
  730.             unchangedDur: 0,
  731.             dropCount: 0,
  732.             riseCount: 0,
  733.             profit: 0,
  734.             someSold: false,
  735.             someBought: false,
  736.         });
  737.     }
  738.     stockList.Start = Date.now() + 500;
  739.     stockList.lastTime = Date.now() + 500;
  740.     stockList.startingProfits = 0;
  741.     stockList.Profits = 0;
  742.     stockList.netProfits = 0;
  743.     stockList.grossProfits = 0;
  744.     stockList.grossLosses = 0;
  745.     stockList.totalStocks = 0;
  746.     stockList.totalShares = 0;
  747.     stockList.totalValue = 0;
  748.     stockList.unrealizedProfits = 0;
  749.     stockList.profitableStocks = 0;
  750.     stockList.unprofitableStocks = 0;
  751.     stockList.profitableTrades = 0;
  752.     stockList.unprofitableTrades = 0;
  753.     stockList.Purchases = 0;
  754.     stockList.Sales = 0;
  755.     stockList.Uptime = 0;
  756.     stockList.hourlyProfits = 0;
  757.     stockList.dailyProfits = 0;
  758.  
  759.     if (hard) {
  760.         for (var i = 0; i < M.Achievements.length; i++) M.Achievements[i].won = 0;
  761.     }
  762. }
Tags: CookiStocker
Advertisement
Add Comment
Please, Sign In to add comment