Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2018
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.58 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. alert("Your mom gay!");
  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. if(bestZoneIdx) {
  84. console.log(GAME.m_State.m_SalienInfoBox.m_LevelText.text, GAME.m_State.m_SalienInfoBox.m_XPValueText.text);
  85. console.log("join to zone", bestZoneIdx);
  86. isJoining = true;
  87. SERVER.JoinZone(
  88. bestZoneIdx,
  89. (results) => {
  90. GAME.ChangeState(new CBattleState(GAME.m_State.m_PlanetData, bestZoneIdx));
  91. isJoining = false;
  92. console.log(results);
  93. },
  94. () => {
  95. console.log("fail");
  96. isJoining = false;
  97. }
  98. );
  99. }
  100. console.log(bestZoneIdx);
  101. return;
  102. }
  103. return continued;
  104. }
  105. const CanAttack = function CanAttack(attackname) {
  106. let Manager = AttackManager().m_mapCooldowns.get(attackname);
  107. let lastUsed = Manager.m_rtAttackLastUsed;
  108. let canAttack = Manager.BAttack();
  109. Manager.m_rtAttackLastUsed = lastUsed;
  110. return canAttack;
  111. }
  112. const GetBestZone = function GetBestZone() {
  113. let bestZoneIdx;
  114. let highestDifficulty = -1;
  115.  
  116. let isLevelling = context.gPlayerInfo.level < 9 || Option("forceLevellingMode");
  117. let maxProgress = isLevelling ? 10000 : 0;
  118.  
  119. for (let idx = 0; idx < GAME.m_State.m_Grid.m_Tiles.length; idx++) {
  120. let zone = GAME.m_State.m_Grid.m_Tiles[idx].Info;
  121. if (!zone.captured) {
  122. if (zone.boss) {
  123. console.log(`zone ${idx} (${bestZoneIdx % k_NumMapTilesW}, ${(bestZoneIdx / k_NumMapTilesW) | 0}) with boss`);
  124. return idx;
  125. }
  126.  
  127. if(isLevelling) {
  128. if(zone.difficulty > highestDifficulty) {
  129. highestDifficulty = zone.difficulty;
  130. maxProgress = zone.progress;
  131. bestZoneIdx = idx;
  132. } else if(zone.difficulty < highestDifficulty) continue;
  133.  
  134. if(zone.progress < maxProgress) {
  135. maxProgress = zone.progress;
  136. bestZoneIdx = idx;
  137. }
  138. } else {
  139. if(zone.progress > maxProgress) {
  140. maxProgress = zone.progress;
  141. bestZoneIdx = idx;
  142. }
  143. }
  144.  
  145. }
  146. }
  147.  
  148. if(bestZoneIdx !== undefined) {
  149. 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}`);
  150. }
  151.  
  152. return bestZoneIdx;
  153. }
  154. const GetBestPlanet = function GetBestPlanet() {
  155. let bestPlanet;
  156. let maxProgress = 0;
  157.  
  158. if (!GAME.m_State.m_mapPlanets)
  159. return;
  160.  
  161. for (let planetKV of GAME.m_State.m_mapPlanets) {
  162. let planet = planetKV[1];
  163. if(planet.state.active && !planet.state.captured && planet.state.capture_progress > maxProgress) {
  164. maxProgress = planet.state.capture_progress;
  165. bestPlanet = planet;
  166. }
  167.  
  168. }
  169.  
  170. if(bestPlanet) {
  171. console.log(`selecting planet ${bestPlanet.state.name} with progress: ${bestPlanet.state.capture_progress}`);
  172. return bestPlanet.id;
  173. }
  174. }
  175.  
  176. // Let's challenge ourselves to be human here!
  177. const CLICKS_PER_SECOND = 15;
  178.  
  179. const InGame = function InGame() {
  180. return GAME.m_State.m_bRunning;
  181. }
  182.  
  183. const WORST_SCORE = -1 / 0;
  184. const START_POS = APP.renderer.width;
  185.  
  186.  
  187. const EnemySpeed = function EnemySpeed(enemy) {
  188. return enemy.m_Sprite.vx;
  189. }
  190. const EnemyDistance = function EnemyDistance(enemy) {
  191. return (enemy.m_Sprite.x - k_nDamagePointx) / (START_POS - k_nDamagePointx);
  192. }
  193.  
  194. const EnemyCenter = function EnemyCenter(enemy) {
  195. return [
  196. enemy.m_Sprite.x + enemy.m_Sprite.width / 2,
  197. enemy.m_Sprite.y + enemy.m_Sprite.height / 2
  198. ];
  199. }
  200.  
  201.  
  202. class Attack {
  203. constructor() {
  204. this.nextAttackDelta = 0;
  205. }
  206. shouldAttack(delta, enemies) {
  207. throw new Error("shouldAttack not implemented");
  208. }
  209. process(enemies) {
  210. throw new Error("process not implemented");
  211. }
  212. getAttackName() {
  213. throw new Error("no current attack name");
  214. }
  215. canAttack() {
  216. return CanAttack(this.getAttackName());
  217. }
  218. getAttackData() {
  219. return AttackManager().m_AttackData[this.getAttackName()];
  220. }
  221. }
  222.  
  223. // Basic clicking attack, attack closest
  224. class ClickAttack extends Attack {
  225. shouldAttack(delta) {
  226. // Can't do basic attack when station is down
  227. if (GAME.m_State.m_PlayerHealth <= 0)
  228. return false;
  229. this.nextAttackDelta -= delta;
  230. return this.nextAttackDelta <= 0;;
  231. }
  232. score(enemy) {
  233. if (enemy.m_bDead)
  234. return WORST_SCORE;
  235. return 1 - EnemyDistance(enemy);
  236. }
  237. process(enemies) {
  238. let target, target_score = WORST_SCORE;
  239.  
  240. enemies.forEach((enemy) => {
  241. if (!enemy.m_Sprite.visible)
  242. return;
  243. let now_score = this.score(enemy);
  244. if (now_score > target_score) {
  245. target = enemy, target_score = now_score;
  246. }
  247. });
  248.  
  249. if (target)
  250. this.attack(target);
  251. }
  252. attack(enemy) {
  253. enemy.m_Sprite.click();
  254. this.nextAttackDelta = 1 / CLICKS_PER_SECOND;
  255. }
  256. }
  257.  
  258. class ProjectileAttack extends Attack {
  259. shouldAttack(delta) {
  260. return CanAttack(this.getAttackName());
  261. }
  262. score(enemy) {
  263. if (enemy.m_bDead)
  264. return WORST_SCORE;
  265. return enemy.m_nHealth;
  266. }
  267. process(enemies) {
  268. let target, target_score = WORST_SCORE;
  269.  
  270. enemies.forEach((enemy) => {
  271. if (!enemy.m_Sprite.visible)
  272. return;
  273. let now_score = this.score(enemy);
  274. if (now_score > target_score) {
  275. target = enemy, target_score = now_score;
  276. }
  277. });
  278.  
  279. if (target)
  280. this.attack.apply(this, EnemyCenter(target));
  281. }
  282. attack(x, y) {
  283. SetMouse(x, y)
  284. AttackManager().m_mapKeyCodeToAttacks.get(this.getAttackData().keycode)()
  285. }
  286. }
  287.  
  288. // the '1' button (SlimeAttack PsychicAttack BeastAttack - depends on body type of your salien)
  289. class SpecialAttack extends ProjectileAttack {
  290. getAttackName() {
  291. if (gSalien.m_BodyType == "slime")
  292. return "slimeattack";
  293. else if (gSalien.m_BodyType == "beast")
  294. return "beastattack";
  295. else
  296. return "psychicattack";
  297. }
  298. }
  299.  
  300. class BombAttack extends ProjectileAttack {
  301. getAttackName() {
  302. return "explosion";
  303. }
  304. }
  305. class BlackholeAttack extends ProjectileAttack {
  306. getAttackName() {
  307. return "blackhole";
  308. }
  309. }
  310.  
  311. class FreezeAttack extends Attack {
  312. getCurrent() {
  313. return "flashfreeze";
  314. }
  315. shouldAttack(delta, enemies) {
  316. let shouldAttack = false;
  317. if (CanAttack(this.getCurrent())) {
  318. enemies.forEach((enemy) => {
  319. if (EnemyDistance(enemy) <= 0.05) {
  320. shouldAttack = true;
  321. }
  322. });
  323. }
  324. return shouldAttack;
  325. }
  326. getData() {
  327. return AttackManager().m_AttackData[this.getCurrent()];
  328. }
  329. process() {
  330. AttackManager().m_mapKeyCodeToAttacks.get(this.getData().keycode)()
  331. }
  332. }
  333.  
  334. let attacks = [
  335. new ClickAttack(),
  336. new SpecialAttack(),
  337. new FreezeAttack(),
  338. new BombAttack(),
  339. new BlackholeAttack()
  340. ]
  341.  
  342. if (context.BOT_FUNCTION) {
  343. APP.ticker.remove(context.BOT_FUNCTION);
  344. context.BOT_FUNCTION = undefined;
  345. }
  346.  
  347. let reloadingPage = false;
  348.  
  349. context.BOT_FUNCTION = function ticker(delta) {
  350. delta /= 100;
  351.  
  352. let difficulties = PIXI.loader.resources['level_config'];
  353. if (difficulties)
  354. for (let difficulty in difficulties.data) {
  355. let freq = difficulties.data[difficulty].enemies.spawn_frequency;
  356. freq.min = freq.max;
  357. }
  358.  
  359. let buttonsOnErrorMessage = document.getElementsByClassName("btn_grey_white_innerfade btn_medium");
  360. if(buttonsOnErrorMessage[0] != null) {
  361. if (!reloadingPage) {
  362. setTimeout(() => buttonsOnErrorMessage[0].click(), 1000);
  363. }
  364.  
  365. return;
  366. }
  367.  
  368. if(GAME.m_IsStateLoading || !context.gPlayerInfo) {
  369. return;
  370. }
  371.  
  372. if (!InGame()) {
  373. if (TryContinue()) {
  374. console.log("continued!");
  375. }
  376. return;
  377. }
  378.  
  379.  
  380.  
  381. let state = EnemyManager();
  382.  
  383. let enemies = state.m_rgEnemies;
  384.  
  385. for (let attack of attacks)
  386. if (attack.shouldAttack(delta, enemies))
  387. attack.process(enemies);
  388.  
  389. }
  390.  
  391.  
  392. APP.ticker.add(context.BOT_FUNCTION);
  393.  
  394. })(window);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement