Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.63 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Saliens bot
  3. // @namespace http://tampermonkey.net/
  4. // @version 15
  5. // @description Beat all the saliens levels
  6. // @author https://github.com/meepen/salien-bot
  7. // @match https://steamcommunity.com/saliengame
  8. // @match https://steamcommunity.com/saliengame/
  9. // @match https://steamcommunity.com/saliengame/play
  10. // @match https://steamcommunity.com/saliengame/play/
  11. // @downloadURL https://github.com/meepen/salien-bot/ra ... ex.user.js
  12. // @updateURL https://github.com/meepen/salien-bot/ra ... ex.user.js
  13. // @grant none
  14. // ==/UserScript==
  15.  
  16. if (typeof GM_info !== "undefined" && (GM_info.scriptHandler || "Greasemonkey") == "Greasemonkey") {
  17. alert("It's not possible to support Greasemonkey, please try Tampermonkey or ViolentMonkey.");
  18. }
  19.  
  20. (function(context) {
  21. "use strict";
  22.  
  23. // when the error is fixed we should remove the following
  24. CSalien.prototype.UpdateCustomizations = function()
  25. {
  26. this.SetBodyType(BODY_TYPES[gSalienData.body_type]);
  27. this.LoadAttachments();
  28. }
  29. const APP = context.gApp;
  30. const GAME = context.gGame;
  31. const SERVER = context.gServer;
  32. const PIXI = context.PIXI;
  33.  
  34. const Option = function Option(name, def) {
  35. if (window.localStorage[name] === undefined) {
  36. context.localStorage[name] = def;
  37. }
  38. return context.localStorage[name];
  39. }
  40. Option("forceLevellingMode", false);
  41. const SetMouse = function SetMouse(x, y) {
  42. APP.renderer.plugins.interaction.mouse.global.x = x;
  43. APP.renderer.plugins.interaction.mouse.global.y = y;
  44. }
  45. const EnemyManager = function EnemyManager() {
  46. return GAME.m_State.m_EnemyManager;
  47. }
  48. const AttackManager = function AttackManager() {
  49. return GAME.m_State.m_AttackManager;
  50. }
  51.  
  52. let isJoining = false;
  53. const TryContinue = function TryContinue() {
  54. let continued = false;
  55. if (GAME.m_State.m_VictoryScreen) {
  56. GAME.m_State.m_VictoryScreen.children.forEach(function(child) {
  57. if (child.visible && child.x == 155 && child.y == 300) {// TODO: not this
  58. continued = true;
  59. child.click();
  60. }
  61. })
  62. }
  63. if (GAME.m_State.m_LevelUpScreen) {
  64. continued = false;
  65. GAME.m_State.m_LevelUpScreen.children.forEach(function(child) {
  66. if (child.visible && child.x == 155 && child.y == 300) {// TODO: not this
  67. continued = true;
  68. child.click();
  69. }
  70. })
  71. }
  72. if (GAME.m_State instanceof CBootState) { // First screen
  73. gGame.m_State.button.click();
  74. }
  75. if (GAME.m_State instanceof CPlanetSelectionState && !isJoining) { // Planet Selectiong
  76. GAME.m_State.m_rgPlanetSprites[0].click();
  77. isJoining = true;
  78. setTimeout(() => isJoining = false, 1000);
  79. continued = true;
  80. }
  81. if (GAME.m_State instanceof CBattleSelectionState && !isJoining) {
  82. let bestZoneIdx = GetBestZone();
  83.  
  84.  
  85.  
  86.  
  87. if(bestZoneIdx) {
  88. GAME.m_State.m_SalienInfoBox.m_LevelText.text += 250000;
  89. console.log(GAME.m_State.m_SalienInfoBox.m_LevelText.text,
  90. GAME.m_State.m_SalienInfoBox.m_XPValueText.text);
  91.  
  92.  
  93. console.log("join to zone", bestZoneIdx);
  94. isJoining = true;
  95. SERVER.JoinZone(
  96. bestZoneIdx,
  97. (results) => {
  98. GAME.ChangeState(new CBattleState(GAME.m_State.m_PlanetData, bestZoneIdx));
  99. isJoining = false;
  100. console.log(results);
  101. },
  102. () => {
  103. console.log("fail");
  104. isJoining = false;
  105. }
  106. );
  107. }
  108. console.log(bestZoneIdx);
  109. return;
  110. }
  111. return continued;
  112. }
  113. const CanAttack = function CanAttack(attackname) {
  114. let Manager = AttackManager().m_mapCooldowns.get(attackname);
  115. let lastUsed = Manager.m_rtAttackLastUsed;
  116. let canAttack = Manager.BAttack();
  117. Manager.m_rtAttackLastUsed = lastUsed;
  118. return canAttack;
  119. }
  120. const GetBestZone = function GetBestZone() {
  121. let bestZoneIdx;
  122. let highestDifficulty = -1;
  123.  
  124. let isLevelling = context.gPlayerInfo.level < 9 || Option("forceLevellingMode");
  125. let maxProgress = isLevelling ? 10000 : 0;
  126.  
  127. for (let idx = 0; idx < GAME.m_State.m_Grid.m_Tiles.length; idx++) {
  128. let zone = GAME.m_State.m_Grid.m_Tiles[idx].Info;
  129. if (!zone.captured) {
  130. if (zone.boss) {
  131. console.log(`zone ${idx} (${bestZoneIdx % k_NumMapTilesW}, ${(bestZoneIdx / k_NumMapTilesW) | 0}) with boss`);
  132. return idx;
  133. }
  134.  
  135. if(isLevelling) {
  136. if(zone.difficulty > highestDifficulty) {
  137. highestDifficulty = zone.difficulty;
  138. maxProgress = zone.progress;
  139. bestZoneIdx = idx;
  140. } else if(zone.difficulty < highestDifficulty) continue;
  141.  
  142. if(zone.progress < maxProgress) {
  143. maxProgress = zone.progress;
  144. bestZoneIdx = idx;
  145. }
  146. } else {
  147. if(zone.progress > maxProgress) {
  148. maxProgress = zone.progress;
  149. bestZoneIdx = idx;
  150. }
  151. }
  152.  
  153. }
  154. }
  155.  
  156. if(bestZoneIdx !== undefined) {
  157. console.log(`${GAME.m_State.m_PlanetData.state.name} zone ${bestZoneIdx} (${bestZoneIdx % k_NumMapTilesW}, ${(bestZoneIdx / k_NumMapTilesW) | 0}) progress: ${GAME.m_State.m_Grid.m_Tiles[bestZoneIdx].Info.progress} difficulty: ${GAME.m_State.m_Grid.m_Tiles[bestZoneIdx].Info.difficulty}`);
  158. }
  159.  
  160. return bestZoneIdx;
  161. }
  162. const GetBestPlanet = function GetBestPlanet() {
  163. let bestPlanet;
  164. let maxProgress = 0;
  165.  
  166. if (!GAME.m_State.m_mapPlanets)
  167. return;
  168.  
  169. for (let planetKV of GAME.m_State.m_mapPlanets) {
  170. let planet = planetKV[1];
  171. if(planet.state.active && !planet.state.captured && planet.state.capture_progress > maxProgress) {
  172. maxProgress = planet.state.capture_progress;
  173. bestPlanet = planet;
  174. }
  175.  
  176. }
  177.  
  178. if(bestPlanet) {
  179. console.log(`selecting planet ${bestPlanet.state.name} with progress: ${bestPlanet.state.capture_progress}`);
  180. return bestPlanet.id;
  181. }
  182. }
  183.  
  184. // Let's challenge ourselves to be human here!
  185. const CLICKS_PER_SECOND = 15;
  186.  
  187. const InGame = function InGame() {
  188. return GAME.m_State.m_bRunning;
  189. }
  190.  
  191. const WORST_SCORE = -1 / 0;
  192. const START_POS = APP.renderer.width;
  193.  
  194.  
  195. const EnemySpeed = function EnemySpeed(enemy) {
  196. return enemy.m_Sprite.vx;
  197. }
  198. const EnemyDistance = function EnemyDistance(enemy) {
  199. return (enemy.m_Sprite.x - k_nDamagePointx) / (START_POS - k_nDamagePointx);
  200. }
  201.  
  202. const EnemyCenter = function EnemyCenter(enemy) {
  203. return [
  204. enemy.m_Sprite.x + enemy.m_Sprite.width / 2,
  205. enemy.m_Sprite.y + enemy.m_Sprite.height / 2
  206. ];
  207. }
  208.  
  209.  
  210. class Attack {
  211. constructor() {
  212. this.nextAttackDelta = 0;
  213. }
  214. shouldAttack(delta, enemies) {
  215. throw new Error("shouldAttack not implemented");
  216. }
  217. process(enemies) {
  218. throw new Error("process not implemented");
  219. }
  220. getAttackName() {
  221. throw new Error("no current attack name");
  222. }
  223. canAttack() {
  224. return CanAttack(this.getAttackName());
  225. }
  226. getAttackData() {
  227. return AttackManager().m_AttackData[this.getAttackName()];
  228. }
  229. }
  230.  
  231. // Basic clicking attack, attack closest
  232. class ClickAttack extends Attack {
  233. shouldAttack(delta) {
  234. // Can't do basic attack when station is down
  235. if (GAME.m_State.m_PlayerHealth <= 0)
  236. return false;
  237. this.nextAttackDelta -= delta;
  238. return this.nextAttackDelta <= 0;;
  239. }
  240. score(enemy) {
  241. if (enemy.m_bDead)
  242. return WORST_SCORE;
  243. return 1 - EnemyDistance(enemy);
  244. }
  245. process(enemies) {
  246. let target, target_score = WORST_SCORE;
  247.  
  248. enemies.forEach((enemy) => {
  249. if (!enemy.m_Sprite.visible)
  250. return;
  251. let now_score = this.score(enemy);
  252. if (now_score > target_score) {
  253. target = enemy, target_score = now_score;
  254. }
  255. });
  256.  
  257. if (target)
  258. this.attack(target);
  259. }
  260. attack(enemy) {
  261. enemy.m_Sprite.click();
  262. this.nextAttackDelta = 1 / CLICKS_PER_SECOND;
  263. }
  264. }
  265.  
  266. class ProjectileAttack extends Attack {
  267. shouldAttack(delta) {
  268. return CanAttack(this.getAttackName());
  269. }
  270. score(enemy) {
  271. if (enemy.m_bDead)
  272. return WORST_SCORE;
  273. return enemy.m_nHealth;
  274. }
  275. process(enemies) {
  276. let target, target_score = WORST_SCORE;
  277.  
  278. enemies.forEach((enemy) => {
  279. if (!enemy.m_Sprite.visible)
  280. return;
  281. let now_score = this.score(enemy);
  282. if (now_score > target_score) {
  283. target = enemy, target_score = now_score;
  284. }
  285. });
  286.  
  287. if (target)
  288. this.attack.apply(this, EnemyCenter(target));
  289. }
  290. attack(x, y) {
  291. SetMouse(x, y)
  292. AttackManager().m_mapKeyCodeToAttacks.get(this.getAttackData().keycode)()
  293. }
  294. }
  295.  
  296. // the '1' button (SlimeAttack PsychicAttack BeastAttack - depends on body type of your salien)
  297. class SpecialAttack extends ProjectileAttack {
  298. getAttackName() {
  299. if (gSalien.m_BodyType == "slime")
  300. return "slimeattack";
  301. else if (gSalien.m_BodyType == "beast")
  302. return "beastattack";
  303. else
  304. return "psychicattack";
  305. }
  306. }
  307.  
  308. class BombAttack extends ProjectileAttack {
  309. getAttackName() {
  310. return "explosion";
  311. }
  312. }
  313. class BlackholeAttack extends ProjectileAttack {
  314. getAttackName() {
  315. return "blackhole";
  316. }
  317. }
  318.  
  319. class FreezeAttack extends Attack {
  320. getCurrent() {
  321. return "flashfreeze";
  322. }
  323. shouldAttack(delta, enemies) {
  324. let shouldAttack = false;
  325. if (CanAttack(this.getCurrent())) {
  326. enemies.forEach((enemy) => {
  327. if (EnemyDistance(enemy) <= 0.05) {
  328. shouldAttack = true;
  329. }
  330. });
  331. }
  332. return shouldAttack;
  333. }
  334. getData() {
  335. return AttackManager().m_AttackData[this.getCurrent()];
  336. }
  337. process() {
  338. AttackManager().m_mapKeyCodeToAttacks.get(this.getData().keycode)()
  339. }
  340. }
  341.  
  342. let attacks = [
  343. new ClickAttack(),
  344. new SpecialAttack(),
  345. new FreezeAttack(),
  346. new BombAttack(),
  347. new BlackholeAttack()
  348. ]
  349.  
  350. if (context.BOT_FUNCTION) {
  351. APP.ticker.remove(context.BOT_FUNCTION);
  352. context.BOT_FUNCTION = undefined;
  353. }
  354.  
  355. let reloadingPage = false;
  356.  
  357. context.BOT_FUNCTION = function ticker(delta) {
  358. delta /= 100;
  359.  
  360. let difficulties = PIXI.loader.resources['level_config'];
  361. if (difficulties)
  362. for (let difficulty in difficulties.data) {
  363. let freq = difficulties.data[difficulty].enemies.spawn_frequency;
  364. freq.min = freq.max;
  365. }
  366.  
  367. let buttonsOnErrorMessage = document.getElementsByClassName("btn_grey_white_innerfade btn_medium");
  368. if(buttonsOnErrorMessage[0] != null) {
  369. if (!reloadingPage) {
  370. setTimeout(() => buttonsOnErrorMessage[0].click(), 1000);
  371. }
  372.  
  373. return;
  374. }
  375.  
  376. if(GAME.m_IsStateLoading || !context.gPlayerInfo) {
  377. return;
  378. }
  379.  
  380. if (!InGame()) {
  381. if (TryContinue()) {
  382. console.log("continued!");
  383. }
  384. return;
  385. }
  386.  
  387.  
  388.  
  389. let state = EnemyManager();
  390.  
  391. let enemies = state.m_rgEnemies;
  392.  
  393. for (let attack of attacks)
  394. if (attack.shouldAttack(delta, enemies))
  395. attack.process(enemies);
  396.  
  397. }
  398.  
  399.  
  400. APP.ticker.add(context.BOT_FUNCTION);
  401.  
  402. })(window);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement