Advertisement
Guest User

mouseasXwchill

a guest
Jun 13th, 2015
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.55 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Monster Minigame AutoScript
  3. // @author /u/mouseasw for creating and maintaining the script, /u/WinneonSword for the Greasemonkey support, and every contributor on the GitHub repo for constant enhancements.
  4. // @version 1.8
  5. // @namespace https://github.com/mouseas/steamSummerMinigame
  6. // @description A script that runs the Steam Monster Minigame for you.
  7. // @match http://steamcommunity.com/minigame/towerattack*
  8. // @updateURL https://raw.githubusercontent.com/mouseas/steamSummerMinigame/master/autoPlay.js
  9. // @downloadURL https://raw.githubusercontent.com/mouseas/steamSummerMinigame/master/autoPlay.js
  10. // ==/UserScript==
  11.  
  12. // IMPORTANT: Update the @version property above to a higher number such as 1.1 and 1.2 when you update the script! Otherwise, Tamper / Greasemonkey users will not update automatically.
  13.  
  14. // OPTIONS
  15. var enableAutoClicker = true; // set to false to disable autoclicker
  16. var clickRate = 50; // change to number of desired clicks per second
  17. var setClickVariable = false; // change to true to improve performance
  18.  
  19. var isAlreadyRunning = false;
  20.  
  21. var ABILITIES = {
  22. "MORALE_BOOSTER": 5,
  23. "GOOD_LUCK": 6,
  24. "MEDIC": 7,
  25. "METAL_DETECTOR": 8,
  26. "COOLDOWN": 9,
  27. "NUKE": 10,
  28. "CLUSTER_BOMB": 11,
  29. "NAPALM": 12
  30. };
  31.  
  32. var ITEMS = {
  33. "REVIVE": 13,
  34. "GOLD_RAIN": 17,
  35. "GOD_MODE": 21,
  36. "REFLECT_DAMAGE":24,
  37. "CRIT": 18,
  38. "CRIPPLE_MONSTER": 15,
  39. "CRIPPLE_SPAWNER": 14,
  40. "MAXIMIZE_ELEMENT": 16
  41. }
  42.  
  43. var ENEMY_TYPE = {
  44. "SPAWNER":0,
  45. "CREEP":1,
  46. "BOSS":2,
  47. "MINIBOSS":3,
  48. "TREASURE":4
  49. }
  50.  
  51. if (thingTimer){
  52. window.clearInterval(thingTimer);
  53. }
  54.  
  55. function firstRun() {
  56. // disable particle effects - this drastically reduces the game's memory leak
  57. if (g_Minigame !== undefined) {
  58. g_Minigame.CurrentScene().DoClickEffect = function() {};
  59. g_Minigame.CurrentScene().DoCritEffect = function( nDamage, x, y, additionalText ) {};
  60. g_Minigame.CurrentScene().SpawnEmitter = function(emitter) {
  61. emitter.emit = false;
  62. return emitter;
  63. }
  64. }
  65.  
  66. // disable enemy flinching animation when they get hit
  67. if (CEnemy !== undefined) {
  68. CEnemy.prototype.TakeDamage = function() {};
  69. CEnemySpawner.prototype.TakeDamage = function() {};
  70. CEnemyBoss.prototype.TakeDamage = function() {};
  71. }
  72. }
  73.  
  74. function doTheThing() {
  75. if (!isAlreadyRunning){
  76. isAlreadyRunning = true;
  77.  
  78. goToLaneWithBestTarget();
  79. useGoodLuckCharmIfRelevant();
  80. useMedicsIfRelevant();
  81. useMoraleBoosterIfRelevant();
  82. useClusterBombIfRelevant();
  83. useNapalmIfRelevant();
  84. useTacticalNukeIfRelevant();
  85. useCrippleSpawnerIfRelevant();
  86. useGoldRainIfRelevant();
  87. attemptRespawn();
  88.  
  89. isAlreadyRunning = false;
  90. }
  91. }
  92.  
  93. function goToLaneWithBestTarget() {
  94. // We can overlook spawners if all spawners are 40% hp or higher and a creep is under 10% hp
  95. var spawnerOKThreshold = 0.4;
  96. var creepSnagThreshold = 0.1;
  97.  
  98. var targetFound = false;
  99. var lowHP = 0;
  100. var lowLane = 0;
  101. var lowTarget = 0;
  102. var lowPercentageHP = 0;
  103.  
  104. // determine which lane and enemy is the optimal target
  105. var enemyTypePriority = [
  106. ENEMY_TYPE.TREASURE,
  107. ENEMY_TYPE.BOSS,
  108. ENEMY_TYPE.MINIBOSS,
  109. ENEMY_TYPE.SPAWNER,
  110. ENEMY_TYPE.CREEP
  111. ];
  112.  
  113. var skippingSpawner = false;
  114. var skippedSpawnerLane = 0;
  115. var skippedSpawnerTarget = 0;
  116. var targetIsTreasureOrBoss = false;
  117.  
  118. for (var k = 0; !targetFound && k < enemyTypePriority.length; k++) {
  119.  
  120. if (enemyTypePriority[k] == ENEMY_TYPE.TREASURE || enemyTypePriority[k] == ENEMY_TYPE.BOSS){
  121. targetIsTreasureOrBoss = true;
  122. } else {
  123. targetIsTreasureOrBoss = false;
  124. }
  125.  
  126. var enemies = [];
  127.  
  128. // gather all the enemies of the specified type.
  129. for (var i = 0; i < 3; i++) {
  130. for (var j = 0; j < 4; j++) {
  131. var enemy = g_Minigame.CurrentScene().GetEnemy(i, j);
  132. if (enemy && enemy.m_data.type == enemyTypePriority[k]) {
  133. enemies[enemies.length] = enemy;
  134. }
  135. }
  136. }
  137.  
  138. // target the enemy of the specified type with the lowest hp
  139. for (var i = 0; i < enemies.length; i++) {
  140. if (enemies[i] && !enemies[i].m_bIsDestroyed) {
  141. if (lowHP < 1 || enemies[i].m_flDisplayedHP < lowHP) {
  142. targetFound = true;
  143. lowHP = enemies[i].m_flDisplayedHP;
  144. lowLane = enemies[i].m_nLane;
  145. lowTarget = enemies[i].m_nID;
  146. }
  147. var percentageHP = enemies[i].m_flDisplayedHP / enemies[i].m_data.max_hp;
  148. if (lowPercentageHP == 0 || percentageHP < lowPercentageHP) {
  149. lowPercentageHP = percentageHP;
  150. }
  151. }
  152. }
  153.  
  154. // If we just finished looking at spawners,
  155. // AND none of them were below our threshold,
  156. // remember them and look for low creeps (so don't quit now)
  157. if (enemyTypePriority[k] == ENEMY_TYPE.SPAWNER && lowPercentageHP > spawnerOKThreshold) {
  158. skippedSpawnerLane = lowLane;
  159. skippedSpawnerTarget = lowTarget;
  160. skippingSpawner = true;
  161. targetFound = false;
  162. }
  163.  
  164. // If we skipped a spawner and just finished looking at creeps,
  165. // AND the lowest was above our snag threshold,
  166. // just go back to the spawner!
  167. if (skippingSpawner && enemyTypePriority[k] == ENEMY_TYPE.CREEP && lowPercentageHP > creepSnagThreshold ) {
  168. lowLane = skippedSpawnerLane;
  169. lowTarget = skippedSpawnerTarget;
  170. }
  171. }
  172.  
  173.  
  174. // go to the chosen lane
  175. if (targetFound) {
  176. if (g_Minigame.CurrentScene().m_nExpectedLane != lowLane) {
  177. //console.log('switching langes');
  178. g_Minigame.CurrentScene().TryChangeLane(lowLane);
  179. }
  180.  
  181. // target the chosen enemy
  182. if (g_Minigame.CurrentScene().m_nTarget != lowTarget) {
  183. //console.log('switching targets');
  184. g_Minigame.CurrentScene().TryChangeTarget(lowTarget);
  185. }
  186.  
  187.  
  188. // Prevent attack abilities and items if up against a boss or treasure minion
  189. if (targetIsTreasureOrBoss) {
  190. // Morale
  191. disableAbility(ABILITIES.MORALE_BOOSTER);
  192. // Luck
  193. disableAbility(ABILITIES.GOOD_LUCK);
  194. // Nuke
  195. disableAbility(ABILITIES.NUKE);
  196. // Clusterbomb
  197. disableAbility(ABILITIES.CLUSTER_BOMB);
  198. // Napalm
  199. disableAbility(ABILITIES.NAPALM);
  200. // Crit
  201. disableAbilityItem(ITEMS.CRIT);
  202. // Cripple Spawner
  203. disableAbilityItem(ITEMS.CRIPPLE_SPAWNER);
  204. // Cripple Monster
  205. disableAbilityItem(ITEMS.CRIPPLE_MONSTER);
  206. // Max Elemental Damage
  207. disableAbilityItem(ITEMS.MAXIMIZE_ELEMENT);
  208. // Reflect Damage
  209. disableAbilityItem(ITEMS.REFLECT_DAMAGE);
  210. } else {
  211. // Morale
  212. enableAbility(ABILITIES.MORALE_BOOSTER);
  213. // Luck
  214. enableAbility(ABILITIES.GOOD_LUCK);
  215. // Nuke
  216. enableAbility(ABILITIES.NUKE);
  217. // Clusterbomb
  218. enableAbility(ABILITIES.CLUSTER_BOMB);
  219. // Napalm
  220. enableAbility(ABILITIES.NAPALM);
  221. // Crit
  222. enableAbilityItem(ITEMS.CRIT);
  223. // Cripple Spawner
  224. enableAbilityItem(ITEMS.CRIPPLE_SPAWNER);
  225. // Cripple Monster
  226. enableAbilityItem(ITEMS.CRIPPLE_MONSTER);
  227. // Max Elemental Damage
  228. enableAbilityItem(ITEMS.MAXIMIZE_ELEMENT);
  229. // Reflect Damage
  230. enableAbilityItem(ITEMS.REFLECT_DAMAGE);
  231. }
  232. }
  233. }
  234.  
  235. function useMedicsIfRelevant() {
  236. var myMaxHealth = g_Minigame.CurrentScene().m_rgPlayerTechTree.max_hp;
  237.  
  238. // check if health is below 50%
  239. var hpPercent = g_Minigame.CurrentScene().m_rgPlayerData.hp / myMaxHealth;
  240. if (hpPercent > 0.5 || g_Minigame.CurrentScene().m_rgPlayerData.hp < 1) {
  241. return; // no need to heal - HP is above 50% or already dead
  242. }
  243.  
  244. // check if Medics is purchased and cooled down
  245. if (hasPurchasedAbility(ABILITIES.MEDIC) && !isAbilityCoolingDown(ABILITIES.MEDIC)) {
  246.  
  247. // Medics is purchased, cooled down, and needed. Trigger it.
  248. console.log('Medics is purchased, cooled down, and needed. Trigger it.');
  249. triggerAbility(ABILITIES.MEDIC);
  250. } else if (hasItem(ITEMS.GOD_MODE) && !isAbilityCoolingDown(ITEMS.GOD_MODE)) {
  251.  
  252. console.log('We have god mode, cooled down, and needed. Trigger it.');
  253. triggerItem(ITEMS.GOD_MODE);
  254. }
  255. };
  256.  
  257. // Use Good Luck Charm if doable
  258. function useGoodLuckCharmIfRelevant() {
  259. // check if Good Luck Charms is purchased and cooled down
  260. if (hasPurchasedAbility(ABILITIES.GOOD_LUCK)) {
  261. if (isAbilityCoolingDown(ABILITIES.GOOD_LUCK)) {
  262. return;
  263. }
  264.  
  265. if (! isAbilityEnabled(ABILITIES.GOOD_LUCK)) {
  266. return;
  267. }
  268.  
  269. // Good Luck Charms is purchased, cooled down, and needed. Trigger it.
  270. console.log('Good Luck Charms is purchased, cooled down, and needed. Trigger it.');
  271. triggerAbility(ABILITIES.GOOD_LUCK);
  272. }
  273. }
  274.  
  275. function useClusterBombIfRelevant() {
  276. //Check if Cluster Bomb is purchased and cooled down
  277. if (hasPurchasedAbility(ABILITIES.CLUSTER_BOMB)) {
  278. if (isAbilityCoolingDown(ABILITIES.CLUSTER_BOMB)) {
  279. return;
  280. }
  281.  
  282. //Check lane has monsters to explode
  283. var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
  284. var enemyCount = 0;
  285. var enemySpawnerExists = false;
  286. //Count each slot in lane
  287. for (var i = 0; i < 4; i++) {
  288. var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
  289. if (enemy) {
  290. enemyCount++;
  291. if (enemy.m_data.type == 0) {
  292. enemySpawnerExists = true;
  293. }
  294. }
  295. }
  296. //Bombs away if spawner and 2+ other monsters
  297. if (enemySpawnerExists && enemyCount >= 3) {
  298. triggerAbility(ABILITIES.CLUSTER_BOMB);
  299. }
  300. }
  301. }
  302.  
  303. function useNapalmIfRelevant() {
  304. //Check if Napalm is purchased and cooled down
  305. if (hasPurchasedAbility(ABILITIES.NAPALM)) {
  306. if (isAbilityCoolingDown(ABILITIES.NAPALM)) {
  307. return;
  308. }
  309.  
  310. //Check lane has monsters to burn
  311. var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
  312. var enemyCount = 0;
  313. var enemySpawnerExists = false;
  314. //Count each slot in lane
  315. for (var i = 0; i < 4; i++) {
  316. var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
  317. if (enemy) {
  318. enemyCount++;
  319. if (enemy.m_data.type == 0) {
  320. enemySpawnerExists = true;
  321. }
  322. }
  323. }
  324. //Burn them all if spawner and 2+ other monsters
  325. if (enemySpawnerExists && enemyCount >= 3) {
  326. triggerAbility(ABILITIES.NAPALM);
  327. }
  328. }
  329. }
  330.  
  331. function useMoraleBoosterIfRelevant() {
  332. // Check if Morale Booster is purchased
  333. if(hasPurchasedAbility(5)) {
  334. if (isAbilityCoolingDown(5)) {
  335. return;
  336. }
  337.  
  338. //Check lane has monsters so the hype isn't wasted
  339. var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
  340. var enemyCount = 0;
  341. var enemySpawnerExists = false;
  342. //Count each slot in lane
  343. for (var i = 0; i < 4; i++) {
  344. var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
  345. if (enemy) {
  346. enemyCount++;
  347. if (enemy.m_data.type == 0) {
  348. enemySpawnerExists = true;
  349. }
  350. }
  351. }
  352. //Hype everybody up!
  353. if (enemySpawnerExists && enemyCount >= 3) {
  354. triggerAbility(5);
  355. }
  356. }
  357. }
  358.  
  359. function useTacticalNukeIfRelevant() {
  360. // Check if Tactical Nuke is purchased
  361. if(hasPurchasedAbility(ABILITIES.NUKE)) {
  362. if (isAbilityCoolingDown(ABILITIES.NUKE)) {
  363. return;
  364. }
  365.  
  366. //Check that the lane has a spawner and record it's health percentage
  367. var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
  368. var enemySpawnerExists = false;
  369. var enemySpawnerHealthPercent = 0.0;
  370. //Count each slot in lane
  371. for (var i = 0; i < 4; i++) {
  372. var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
  373. if (enemy) {
  374. if (enemy.m_data.type == 0) {
  375. enemySpawnerExists = true;
  376. enemySpawnerHealthPercent = enemy.m_flDisplayedHP / enemy.m_data.max_hp;
  377. }
  378. }
  379. }
  380.  
  381. // If there is a spawner and it's health is between 60% and 30%, nuke it!
  382. if (enemySpawnerExists && enemySpawnerHealthPercent < 0.6 && enemySpawnerHealthPercent > 0.3) {
  383. console.log("Tactical Nuke is purchased, cooled down, and needed. Nuke 'em.");
  384. triggerAbility(ABILITIES.NUKE);
  385. }
  386. }
  387. }
  388.  
  389. function useCrippleSpawnerIfRelevant() {
  390. // Check if Cripple Spawner is available
  391. if(hasItem(ITEMS.CRIPPLE_SPAWNER)) {
  392. if (isAbilityCoolingDown(ITEMS.CRIPPLE_SPAWNER)) {
  393. return;
  394. }
  395.  
  396. //Check that the lane has a spawner and record it's health percentage
  397. var currentLane = g_Minigame.CurrentScene().m_nExpectedLane;
  398. var enemySpawnerExists = false;
  399. var enemySpawnerHealthPercent = 0.0;
  400. //Count each slot in lane
  401. for (var i = 0; i < 4; i++) {
  402. var enemy = g_Minigame.CurrentScene().GetEnemy(currentLane, i);
  403. if (enemy) {
  404. if (enemy.m_data.type == 0) {
  405. enemySpawnerExists = true;
  406. enemySpawnerHealthPercent = enemy.m_flDisplayedHP / enemy.m_data.max_hp;
  407. }
  408. }
  409. }
  410.  
  411. // If there is a spawner and it's health is above 95%, cripple it!
  412. if (enemySpawnerExists && enemySpawnerHealthPercent > 0.95) {
  413. console.log("Cripple Spawner available, and needed. Cripple 'em.");
  414. triggerItem(ITEMS.CRIPPLE_SPAWNER);
  415. }
  416. }
  417. }
  418.  
  419. function useGoldRainIfRelevant() {
  420. // Check if gold rain is purchased
  421. if (hasItem(ITEMS.GOLD_RAIN)) {
  422. if (isAbilityCoolingDown(ITEMS.GOLD_RAIN)) {
  423. return;
  424. }
  425.  
  426. var enemy = g_Minigame.m_CurrentScene.GetEnemy(g_Minigame.m_CurrentScene.m_rgPlayerData.current_lane, g_Minigame.m_CurrentScene.m_rgPlayerData.target);
  427. // check if current target is a boss, otherwise its not worth using the gold rain
  428. if (enemy && enemy.m_data.type == ENEMY_TYPE.BOSS) {
  429. var enemyBossHealthPercent = enemy.m_flDisplayedHP / enemy.m_data.max_hp;
  430.  
  431. if (enemyBossHealthPercent >= 0.6) { // We want sufficient time for the gold rain to be applicable
  432. // Gold Rain is purchased, cooled down, and needed. Trigger it.
  433. console.log('Gold rain is purchased and cooled down, Triggering it on boss');
  434. triggerItem(ITEMS.GOLD_RAIN);
  435. }
  436. }
  437. }
  438. }
  439.  
  440. //If player is dead, call respawn method
  441. function attemptRespawn() {
  442. if ((g_Minigame.CurrentScene().m_bIsDead) &&
  443. ((g_Minigame.CurrentScene().m_rgPlayerData.time_died) + 5) < (g_Minigame.CurrentScene().m_nTime)) {
  444. RespawnPlayer();
  445. }
  446. }
  447.  
  448. function isAbilityActive(abilityId) {
  449. return g_Minigame.CurrentScene().bIsAbilityActive(abilityId);
  450. }
  451.  
  452. function hasItem(itemId) {
  453. for ( var i = 0; i < g_Minigame.CurrentScene().m_rgPlayerTechTree.ability_items.length; ++i ) {
  454. var abilityItem = g_Minigame.CurrentScene().m_rgPlayerTechTree.ability_items[i];
  455. if (abilityItem.ability == itemId) {
  456. return true;
  457. }
  458. }
  459. return false;
  460. }
  461.  
  462. function isAbilityCoolingDown(abilityId) {
  463. return g_Minigame.CurrentScene().GetCooldownForAbility(abilityId) > 0;
  464. }
  465.  
  466. function hasPurchasedAbility(abilityId) {
  467. // each bit in unlocked_abilities_bitfield corresponds to an ability.
  468. // the above condition checks if the ability's bit is set or cleared. I.e. it checks if
  469. // the player has purchased the specified ability.
  470. return (1 << abilityId) & g_Minigame.CurrentScene().m_rgPlayerTechTree.unlocked_abilities_bitfield;
  471. }
  472.  
  473. function triggerItem(itemId) {
  474. var elem = document.getElementById('abilityitem_' + itemId);
  475. if (elem && elem.childElements() && elem.childElements().length >= 1) {
  476. g_Minigame.CurrentScene().TryAbility(document.getElementById('abilityitem_' + itemId).childElements()[0]);
  477. }
  478. }
  479.  
  480. function triggerAbility(abilityId) {
  481. var elem = document.getElementById('ability_' + abilityId);
  482. if (elem && elem.childElements() && elem.childElements().length >= 1) {
  483. g_Minigame.CurrentScene().TryAbility(document.getElementById('ability_' + abilityId).childElements()[0]);
  484. }
  485. }
  486.  
  487. function toggleAbilityVisibility(abilityId, show) {
  488. var vis = show === true ? "visible" : "hidden";
  489.  
  490. var elem = document.getElementById('ability_' + abilityId);
  491. if (elem && elem.childElements() && elem.childElements().length >= 1) {
  492. elem.childElements()[0].style.visibility = vis;
  493. }
  494. }
  495.  
  496. function disableAbility(abilityId) {
  497. toggleAbilityVisibility(abilityId, false);
  498. }
  499.  
  500. function enableAbility(abilityId) {
  501. toggleAbilityVisibility(abilityId, true);
  502. }
  503.  
  504. function isAbilityEnabled(abilityId) {
  505. var elem = document.getElementById('ability_' + abilityId);
  506. if (elem && elem.childElements() && elem.childElements().length >= 1) {
  507. return elem.childElements()[0].style.visibility == "visible";
  508. }
  509. return false;
  510. }
  511.  
  512. function toggleAbilityItemVisibility(abilityId, show) {
  513. var vis = show === true ? "visible" : "hidden";
  514.  
  515. var elem = document.getElementById('abilityitem_' + abilityId);
  516. if (elem && elem.childElements() && elem.childElements().length >= 1) {
  517. elem.childElements()[0].style.visibility = show;
  518. }
  519. }
  520.  
  521. function disableAbilityItem(abilityId) {
  522. toggleAbilityItemVisibility(abilityId, false);
  523. }
  524.  
  525. function enableAbilityItem(abilityId) {
  526. toggleAbilityItemVisibility(abilityId, true);
  527. }
  528.  
  529. function isAbilityItemEnabled(abilityId) {
  530. var elem = document.getElementById('abilityitem_' + abilityId);
  531. if (elem && elem.childElements() && elem.childElements().length >= 1) {
  532. return elem.childElements()[0].style.visibility == "visible";
  533. }
  534. return false;
  535. }
  536.  
  537. var thingTimer = window.setInterval(doTheThing, 1000);
  538. function clickTheThing() {
  539. g_Minigame.m_CurrentScene.DoClick(
  540. {
  541. data: {
  542. getLocalPosition: function() {
  543. var enemy = g_Minigame.m_CurrentScene.GetEnemy(
  544. g_Minigame.m_CurrentScene.m_rgPlayerData.current_lane,
  545. g_Minigame.m_CurrentScene.m_rgPlayerData.target),
  546. laneOffset = enemy.m_nLane * 440;
  547.  
  548. return {
  549. x: enemy.m_Sprite.position.x - laneOffset,
  550. y: enemy.m_Sprite.position.y - 52
  551. }
  552. }
  553. }
  554. }
  555. );
  556. }
  557.  
  558. if(enableAutoClicker) {
  559. var resetTickTimer = setInterval(function(){g_msTickRate = 1000},1000); //Force update to be sent every 1000ms
  560. if(setClickVariable) {
  561. var clickTimer = setInterval( function(){
  562. g_Minigame.m_CurrentScene.m_nClicks = clickRate;
  563. }, 1000);
  564. } else {
  565. var clickTimer = window.setInterval(clickTheThing, 1000/clickRate);
  566. }
  567. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement