DripStat DropOut

Calculates stats in DripStat, and provides a control panel for automation.

当前为 2014-06-17 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name DripStat DropOut
  3. // @namespace anonycat
  4. // @version 0.5.260
  5. // @description Calculates stats in DripStat, and provides a control panel for automation.
  6. // @match https://dripstat.com/game/
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. //Should powerups and upgrades be automatically purchased as they become affordable?
  11. //(As of level 5, also includes facilities for grabbing spring beans that appear)
  12. crypto.autoPurchase=0;
  13. //Should the BPS rate be increased to simulate automatic cup clicks?
  14. crypto.autoClick=0;
  15. //Should memory automatically be dripped?
  16. //0 = no auto-drip, 1 = auto-drip when buffer is full, 2 = auto-drip as needed to create enough space to pay for upgrades
  17. crypto.autoDrip=0;
  18.  
  19. //Throttle auto purchases to one every 5 seconds, to avoid flooding the server
  20. var lastBuy = 5;
  21.  
  22. function init()
  23. {
  24. //If autoclicking is enabled, each second will pick a random multiplier and count off that many cup clicks.
  25. //A multiplier of 0 means no clicking, only natural BPS intake.
  26. //Multipliers greater than 20 are rejected by the server, so we won't ever generate such a thing here.
  27. //Lowest possible multiplier to select
  28. crypto.cupmultl = 0;
  29. //Average multiplier
  30. crypto.cupmultm = 5;
  31. //There is no variable for the highest multiplier; it's automatically figured as 2*Middle - Low (but capped at 20).
  32. //Keep track of the original names and descriptions
  33. localStats.powerUps.slice(0).forEach(function(powerUp){
  34. powerUp.upgrades.forEach(function(upgrade){
  35. upgrade.originalName = upgrade.name;
  36. upgrade.originalDesc = upgrade.desc;
  37. });
  38. powerUp.originalName = powerUp.name;
  39. powerUp.originalDesc = powerUp.desc;
  40. });
  41. //string (int) seconds to formatted time
  42. String.prototype.toHHMMSS = function () {
  43. var seconds = parseInt(this, 10); // don't forget the second param
  44. if(seconds <= 0)
  45. return "no time";
  46. var days = Math.floor(seconds / 86400);
  47. seconds -= days*86400;
  48. var hours = Math.floor(seconds / 3600);
  49. seconds -= hours*3600;
  50. var minutes = Math.floor(seconds / 60);
  51. seconds -= minutes*60;
  52. if (hours < 10 && days) {hours = "0"+hours;}
  53. if (minutes < 10 && hours) {minutes = "0"+minutes;}
  54. if (seconds < 10) {seconds = "0"+seconds;}
  55. var output = "";
  56. if(days)
  57. output = days+"d "+hours+":"+minutes+":"+seconds;
  58. else if(hours)
  59. output = hours+":"+minutes+":"+seconds;
  60. else
  61. output = minutes+":"+seconds;
  62. return output;
  63. }
  64. //Create the control panel with divs
  65. $('#bpsChartContainer').parent().append("<table style='width:100%; height:70px; border-collapse: collapse;'><tr>"
  66. +"<td rowspan=2 style='width:30%; border: 2px solid black;'><div id='next-purchase-container'></div></td>"
  67. +"<td colspan=2 style='width:12%; height:35px; border: 2px solid black; border-bottom: none;' class='apy apn' onclick='crypto.autoPurchase = 1 - crypto.autoPurchase'>Auto Buy</td>"
  68. +"<td colspan=3 style='width:21%; border: 2px solid black; border-bottom: none' class='drip0 drip1 drip2' onclick='crypto.autoDrip = (1 + crypto.autoDrip) % 3'>Auto Drip</td>"
  69. +"<td colspan=2 style='width:12%; border: 2px solid black; border-bottom: none;' class='acy acn' onclick='crypto.autoClick = 1 - crypto.autoClick'>Auto Click</td>"
  70. +"<td style='width:15%; border: 2px solid black; border-right:1px solid black'> Auto Click <div id='multl'></div></td>"
  71. +"<td style='width:5%; border-top: 2px solid black; border-bottom: 2px solid black; background-color: #AFA;' onclick='crypto.cupmultl = Math.min(crypto.cupmultl + 1, crypto.cupmultm)'> + </td>"
  72. +"<td style='width:5%; border: 2px solid black; border-left: 1px solid black; background-color: #FAA;' onclick='crypto.cupmultl = Math.max(crypto.cupmultl - 1, 1)'> - </td></tr>"
  73. +"<tr><td style='width:6%; height:35px; border: 2px solid black; border-top: 1px solid black;' class='apn' onclick='crypto.autoPurchase = 0'> Off </td>"
  74. +"<td style='width:6%; border: 2px solid black; border-top: 1px solid black;' class='apy' onclick='crypto.autoPurchase = 1'> On </td>"
  75. +"<td style='width:7%; border: 2px solid black; border-top: 1px solid black;' class='drip0' onclick='crypto.autoDrip = 0'> Never </td>"
  76. +"<td style='width:7%; border: 2px solid black; border-top: 1px solid black;' class='drip1' onclick='crypto.autoDrip = 1'> At <br /> Limit </td>"
  77. +"<td style='width:7%; border: 2px solid black; border-top: 1px solid black;' class='drip2' onclick='crypto.autoDrip = 2'> For <br /> Costs </td>"
  78. +"<td style='width:6%; border: 2px solid black; border-top: 1px solid black;' class='acn' onclick='crypto.autoClick = 0'> Off </td>"
  79. +"<td style='width:6%; border: 2px solid black; border-top: 1px solid black;' class='acy' onclick='crypto.autoClick = 1'> On </td>"
  80. +"<td style='width:15%; border: 2px solid black; border-right:1px solid black'> Auto Click <div id='multm'></div></td>"
  81. +"<td style='width:5%; border-top: 2px solid black; border-bottom: 2px solid black; background-color: #AFA;' onclick='crypto.cupmultm = Math.min(crypto.cupmultm + 1, 20)'> + </td>"
  82. +"<td style='width:5%; border: 2px solid black; border-left: 1px solid black; background-color: #FAA;' onclick='crypto.cupmultm = Math.max(crypto.cupmultm - 1, crypto.cupmultl)'> - </td></tr></table>");
  83. $("#next-purchase-container").html("<div id='next-purchase-label'></div><div id='next-purchase-payback'></div><div id='next-purchase-time'></div><div id='max-space-label'></div>");
  84. }
  85. function loop()
  86. {
  87. var upgradeCounter = 1;
  88. var powerupCounter = 1;
  89. var mult = 0;
  90. var multm = 0;
  91. var bpc = CoffeeCup.calcBytesPerClick();
  92. if (crypto.autoClick)
  93. {
  94. multm = crypto.cupmultm;
  95. mult = Math.min(20,Math.floor(Math.random()*(2 * multm - crypto.cupmultl)+crypto.cupmultl));
  96. if(mult)
  97. localStats.byteCount += bpc * mult;
  98. if(localStats.byteCount >= localStats.memoryCapacity)
  99. localStats.byteCount = localStats.memoryCapacity;
  100. }
  101. if (crypto.autoDrip && localStats.byteCount == localStats.memoryCapacity)
  102. dripper.dripGlobal();
  103. var data = Array();
  104. var min = 999999999999;
  105. var bytesNeeded=0;
  106. var next = min;
  107. var minObj = {};
  108. localStats.powerUps.slice(0).forEach(function(powerUp) {
  109. powerUp.position = "pu"+powerupCounter;
  110. var hasUpgrade = false;
  111. powerUp.upgrades.forEach(function(upgrade) {
  112. hasUpgrade = true;
  113. upgrade.position = "upg"+upgradeCounter;
  114. //Let's see which upgrade provides the biggest bang for the buck
  115. //(computed as "time taken before this upgrade will recoup its own cost").
  116. //If the price is so high that the current buffer can't possibly hold enough
  117. //(even if we cashed out for more space right now),
  118. //the "real" price includes what it takes to earn that extra buffer space.
  119. //If there's an object we can afford right now,
  120. //which will pay itself back in 2 hours,
  121. //and another object that would nominally pay itself back in 1h50m,
  122. //except that we can't afford it for 20 more minutes,
  123. //we should account for that in the time before recouping.
  124. //Add the time spent waiting to accrue sufficient funds.
  125. //Oh, and if we need 100MB for something, but can only hold 80MB
  126. //(with 70MB of it filled already), we can't just drip 20MB and keep the rest.
  127. //We have to drip everything at once, shooting all the way to 150MB.
  128. //Thus we can't make any progress on affording the item until a drip,
  129. //and then it costs a full additional 100MB after starting from scratch.
  130.  
  131. if(upgrade.price > localStats.byteCount + localStats.memoryCapacity)
  132. bytesNeeded = 2 * upgrade.price - (localStats.memoryCapacity + localStats.byteCount);
  133. else if(upgrade.price > localStats.memoryCapacity)
  134. bytesNeeded = upgrade.price;
  135. else if(upgrade.price > localStats.byteCount)
  136. bytesNeeded = upgrade.price - localStats.byteCount;
  137. else
  138. bytesNeeded = 0;
  139. //Cursor upgrades boost clicking too, so if autoclicks are on, take the rate
  140. //and overall BPS into account when determining its value.
  141. if(powerupCounter == 1)
  142. upgrade.value = upgrade.price/((powerUp.totalBps + multm * bpc) / 10) + bytesNeeded / (multm * bpc + localStats.bps);
  143. else
  144. upgrade.value = upgrade.price/(powerUp.totalBps / 10) + bytesNeeded / (multm * bpc + localStats.bps);
  145. min = Math.min(min, upgrade.value);
  146. if(upgrade.value == min)
  147. minObj = upgrade;
  148. upgrade.desc = "Pays for itself in "+String(upgrade.value).toHHMMSS() + "<br>" + upgrade.originalDesc;
  149. });
  150. if(hasUpgrade)
  151. upgradeCounter++;
  152. powerupCounter++;
  153. //Same procedure on the main power-ups themselves.
  154. if(powerUp.currentPrice > localStats.byteCount + localStats.memoryCapacity)
  155. bytesNeeded = 2 * powerUp.currentPrice - (localStats.memoryCapacity + localStats.byteCount);
  156. else if(powerUp.currentPrice > localStats.memoryCapacity)
  157. bytesNeeded = powerUp.currentPrice;
  158. else if(powerUp.currentPrice > localStats.byteCount)
  159. bytesNeeded = powerUp.currentPrice - localStats.byteCount;
  160. else
  161. bytesNeeded = 0;
  162. powerUp.value = powerUp.currentPrice/powerUp.currentBps + bytesNeeded / (multm * bpc + localStats.bps);
  163. data.push(powerUp.value);
  164. if(!(powerUp.name == "Spring Framework" && springPowerup.isLocked))
  165. {
  166. min = Math.min(min, powerUp.value);
  167. if(powerUp.value == min)
  168. minObj = powerUp;
  169. }
  170. });
  171. $('.storeItem, .upgcontainer').css('background-color', '');
  172. var selector = minObj.position;
  173. $("#"+selector).css('background-color', '#B2EDED');
  174. $('.storePrice').each(function(index){
  175. $(this).find('p').remove();
  176. var content = "<p style=\"display:inline; font-size:0.7em;\"> ("+String(data[index]).toHHMMSS()+")</p>";
  177. $(this).append(content);
  178. });
  179. var label = minObj.name;
  180. if(minObj.powerup) //Is our best deal an upgrade or a powerup? They use different syntax.
  181. {
  182. label += " (Upgrade)";
  183. var price = minObj.price;
  184. }
  185. else
  186. var price = minObj.currentPrice;
  187. var limitTime = Number((localStats.memoryCapacity - localStats.byteCount)/(multm * bpc + localStats.bps)).toFixed(0);
  188. var limitstr = "";
  189. if(price > localStats.byteCount + localStats.memoryCapacity)
  190. {
  191. var time = Number((2 * price - (localStats.memoryCapacity + localStats.byteCount))/(multm * bpc + localStats.bps)).toFixed(0);
  192. if(localStats.memoryCapacity==localStats.byteCount)
  193. limitstr = " (Drip NOW!)";
  194. }
  195. else if(price > localStats.memoryCapacity)
  196. {
  197. var time = Number(price/(multm * bpc + localStats.bps)).toFixed(0);
  198. limitstr = " (Drip NOW!)";
  199. if(crypto.autoDrip >= 2)
  200. dripper.dripGlobal();
  201. }
  202. else
  203. var time = Number((price - localStats.byteCount)/(multm * bpc + localStats.bps)).toFixed(0);
  204. //Now to fill the control panel.
  205. $("#next-purchase-label").html("Next Purchase: <strong>"+label+"</strong>");
  206. $("#next-purchase-payback").html("Pays for itself in "+String(minObj.value).toHHMMSS());
  207. if(time <= 0)
  208. $("#next-purchase-time").html("Affordable now");
  209. else
  210. $("#next-purchase-time").html("Affordable in "+String(time).toHHMMSS()+limitstr);
  211. if(limitTime <= 0)
  212. $("#max-space-label").html("Capacity is maxed out!");
  213. else
  214. $("#max-space-label").html("Capacity maxes out in "+String(limitTime).toHHMMSS());
  215. $("#multl").html("Min. Rate: "+String(crypto.cupmultl));
  216. $("#multm").html("Avg. Rate: "+String(crypto.cupmultm));
  217. if(crypto.autoPurchase)
  218. {
  219. $(".apn").css('background-color', '');
  220. $(".apy").css('background-color', '#AFA');
  221. }
  222. else
  223. {
  224. $(".apy").css('background-color', '');
  225. $(".apn").css('background-color', '#FAA');
  226. }
  227. if(crypto.autoClick)
  228. {
  229. $(".acn").css('background-color', '');
  230. $(".acy").css('background-color', '#AFA');
  231. }
  232. else
  233. {
  234. $(".acy").css('background-color', '');
  235. $(".acn").css('background-color', '#FAA');
  236. }
  237. if(crypto.autoDrip==2)
  238. {
  239. $(".drip0").css('background-color', '');
  240. $(".drip1").css('background-color', '');
  241. $(".drip2").css('background-color', '#AFA');
  242. }
  243. else if(crypto.autoDrip)
  244. {
  245. $(".drip2").css('background-color', '');
  246. $(".drip0").css('background-color', '');
  247. $(".drip1").css('background-color', '#AAF');
  248. }
  249. else
  250. {
  251. $(".drip2").css('background-color', '');
  252. $(".drip1").css('background-color', '');
  253. $(".drip0").css('background-color', '#FAA');
  254. }
  255. if(crypto.autoPurchase && price<=localStats.byteCount && lastBuy >= 5)
  256. {
  257. minObj.buy(localStats);
  258. lastBuy = 0;
  259. }
  260. else if (lastBuy < 5)
  261. lastBuy += 1;
  262. if(crypto.autoPurchase && springPowerup.isLocked && mine.beanCount > 0 && AnonymousUserManager.canGrabBean())
  263. {
  264. if($('.vex').length)
  265. vex.closeAll();
  266. Mine.onGrab();
  267. }
  268. }
  269. init();
  270. setInterval(function(){loop();}, 1000);