AposFeedingBot

none

  1. // ==UserScript==
  2. // @name AposFeedingBot
  3. // @namespace AposFeedingBot
  4. // @include http://agar.io/*
  5. // @version 3.71
  6. // @grant none
  7. // @author http://www.twitch.tv/apostolique
  8. // @description none
  9. // ==/UserScript==
  10.  
  11. var aposFeedingBotVersion = 3.71;
  12.  
  13. //TODO: Team mode
  14. // Detect when people are merging
  15. // Split to catch smaller targets
  16. // Angle based cluster code
  17. // Better wall code
  18. // In team mode, make allies be obstacles.
  19.  
  20. Number.prototype.mod = function(n) {
  21. return ((this % n) + n) % n;
  22. };
  23.  
  24. Array.prototype.peek = function() {
  25. return this[this.length - 1];
  26. };
  27.  
  28. var sha = "efde0488cc2cc176db48dd23b28a20b90314352b";
  29. function getLatestCommit() {
  30. window.jQuery.ajax({
  31. url: "https://api.github.com/repos/apostolique/AposFeedingBot/git/refs/heads/master",
  32. cache: false,
  33. dataType: "jsonp"
  34. }).done(function(data) {
  35. console.dir(data.data);
  36. console.log("hmm: " + data.data.object.sha);
  37. sha = data.data.object.sha;
  38.  
  39. function update(prefix, name, url) {
  40. window.jQuery(document.body).prepend("<div id='" + prefix + "Dialog' style='position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 100; display: none;'>");
  41. window.jQuery('#' + prefix + 'Dialog').append("<div id='" + prefix + "Message' style='width: 350px; background-color: #FFFFFF; margin: 100px auto; border-radius: 15px; padding: 5px 15px 5px 15px;'>");
  42. window.jQuery('#' + prefix + 'Message').append("<h2>UPDATE TIME!!!</h2>");
  43. window.jQuery('#' + prefix + 'Message').append("<p>Grab the update for: <a id='" + prefix + "Link' href='" + url + "' target=\"_blank\">" + name + "</a></p>");
  44. window.jQuery('#' + prefix + 'Link').on('click', function() {
  45. window.jQuery("#" + prefix + "Dialog").hide();
  46. window.jQuery("#" + prefix + "Dialog").remove();
  47. });
  48. window.jQuery("#" + prefix + "Dialog").show();
  49. }
  50.  
  51. $.get('https://raw.githubusercontent.com/Apostolique/AposFeedingBot/master/AposFeedingBot.user.js?' + Math.floor((Math.random() * 1000000) + 1), function(data) {
  52. var latestVersion = data.replace(/(\r\n|\n|\r)/gm,"");
  53. latestVersion = latestVersion.substring(latestVersion.indexOf("// @version")+11,latestVersion.indexOf("// @grant"));
  54.  
  55. latestVersion = parseFloat(latestVersion + 0.0000);
  56. var myVersion = parseFloat(aposFeedingBotVersion + 0.0000);
  57. if(latestVersion > myVersion)
  58. {
  59. update("aposFeedingBot", "AposFeedingBot.user.js", "https://github.com/Apostolique/AposFeedingBot/blob/" + sha + "/AposFeedingBot.user.js/");
  60. }
  61. console.log('Current AposFeedingBot.user.js Version: ' + myVersion + " on Github: " + latestVersion);
  62. });
  63.  
  64. }).fail(function() {});
  65. }
  66. getLatestCommit();
  67.  
  68. console.log("Running Apos Feeding Bot!");
  69.  
  70. var f = window;
  71. var g = window.jQuery;
  72.  
  73. Parse.initialize("nj3ycKuqW4k4CnzN1ZYtMYowoa97qNw7NafLimrF", "nh6arPQQxbE5rFOyR0dCgecQiDAN54Zgjsf7eAKH");
  74.  
  75. console.log("Apos Feeding Bot!");
  76.  
  77. window.botList = window.botList || [];
  78.  
  79. /*function QuickBot() {
  80. this.name = "QuickBot V1";
  81. this.keyAction = function(key) {};
  82. this.displayText = function() {return [];};
  83. this.mainLoop = function() {
  84. return [screenToGameX(getMouseX()),
  85. screenToGameY(getMouseY())];
  86. };
  87. }
  88. window.botList.push(new QuickBot());*/
  89.  
  90.  
  91. function AposBot() {
  92. this.name = "AposFeedingBot " + aposFeedingBotVersion;
  93.  
  94. this.lastMasterUpdate = Date.now();
  95. this.MasterLocation = Parse.Object.extend("MasterLocation");
  96.  
  97. this.toggleFollow = false;
  98. this.master = false;
  99.  
  100. this.masterLocation = [100, 100];
  101. this.masterId = 0;
  102.  
  103. this.keyAction = function(key) {
  104. if (81 == key.keyCode) {
  105. console.log("Toggle Follow Mouse!");
  106. this.toggleFollow = !this.toggleFollow;
  107. }
  108. if (77 == key.keyCode) {
  109. console.log("Toggle Master!");
  110. this.master = !this.master;
  111. }
  112. };
  113.  
  114. this.displayText = function() {
  115. var theText = [];
  116. theText.push("Q - Follow Mouse: " + (this.toggleFollow ? "On" : "Off"));
  117. theText.push("M - Status: " + (this.master ? "Master" : "Slave"));
  118. return theText;
  119. };
  120.  
  121. this.splitDistance = 710;
  122.  
  123. //Given an angle value that was gotten from valueAndleBased(),
  124. //returns a new value that scales it appropriately.
  125. this.paraAngleValue = function(angleValue, range) {
  126. return (15 / (range[1])) * (angleValue * angleValue) - (range[1] / 6);
  127. };
  128.  
  129. this.valueAngleBased = function(angle, range) {
  130. var leftValue = (angle - range[0]).mod(360);
  131. var rightValue = (this.rangeToAngle(range) - angle).mod(360);
  132.  
  133. var bestValue = Math.min(leftValue, rightValue);
  134.  
  135. if (bestValue <= range[1]) {
  136. return this.paraAngleValue(bestValue, range);
  137. }
  138. return -1;
  139. };
  140.  
  141. this.computeDistance = function(x1, y1, x2, y2) {
  142. var xdis = x1 - x2; // <--- FAKE AmS OF COURSE!
  143. var ydis = y1 - y2;
  144. var distance = Math.sqrt(xdis * xdis + ydis * ydis);
  145.  
  146. return distance;
  147. };
  148.  
  149. this.computeDistanceFromCircleEdge = function(x1, y1, x2, y2, s2) {
  150. var tempD = this.computeDistance(x1, y1, x2, y2);
  151.  
  152. var offsetX = 0;
  153. var offsetY = 0;
  154.  
  155. var ratioX = tempD / (x1 - x2);
  156. var ratioY = tempD / (y1 - y2);
  157.  
  158. offsetX = x1 - (s2 / ratioX);
  159. offsetY = y1 - (s2 / ratioY);
  160.  
  161. drawPoint(offsetX, offsetY, 5, "");
  162.  
  163. return this.computeDistance(x2, y2, offsetX, offsetY);
  164. };
  165.  
  166. this.compareSize = function(player1, player2, ratio) {
  167. if (player1.size * player1.size * ratio < player2.size * player2.size) {
  168. return true;
  169. }
  170. return false;
  171. },
  172.  
  173. this.canSplit = function(player1, player2) {
  174. return this.compareSize(player1, player2, 2.8) && !this.compareSize(player1, player2, 20);
  175. };
  176.  
  177. this.isItMe = function(player, cell) {
  178. if (getMode() == ":teams") {
  179. var currentColor = player[0].color;
  180. var currentRed = currentColor.substring(1,3);
  181. var currentGreen = currentColor.substring(3,5);
  182. var currentBlue = currentColor.substring(5,7);
  183. var currentTeam = this.getTeam(currentRed, currentGreen, currentBlue);
  184.  
  185. var cellColor = cell.color;
  186.  
  187. var cellRed = cellColor.substring(1,3);
  188. var cellGreen = cellColor.substring(3,5);
  189. var cellBlue = cellColor.substring(5,7);
  190.  
  191. var cellTeam = this.getTeam(cellRed, cellGreen, cellBlue);
  192.  
  193. if (currentTeam == cellTeam && !cell.isVirus()) {
  194. return true;
  195. }
  196.  
  197. //console.log("COLOR: " + color);
  198.  
  199. } else {
  200. for (var i = 0; i < player.length; i++) {
  201. if (cell.id == player[i].id) {
  202. return true;
  203. }
  204. }
  205. }
  206. return false;
  207. };
  208.  
  209. this.getTeam = function(red, green, blue) {
  210. if (red == "ff") {
  211. return 0;
  212. } else if (green == "ff") {
  213. return 1;
  214. }
  215. return 2;
  216. };
  217.  
  218. this.isFood = function(blob, cell) {
  219. if (!cell.isVirus() && this.compareSize(cell, blob, 1.33) || (cell.size <= 13)) {
  220. return true;
  221. }
  222. return false;
  223. };
  224.  
  225. this.isThreat = function(blob, cell) {
  226. if (!cell.isVirus() && this.compareSize(blob, cell, 1.30)) {
  227. return true;
  228. }
  229. return false;
  230. };
  231.  
  232. this.isVirus = function(blob, cell) {
  233. if (cell.isVirus() && this.compareSize(cell, blob, 1.2)) {
  234. return true;
  235. } else if (cell.isVirus() && cell.color.substring(3,5).toLowerCase() != "ff") {
  236. return true;
  237. }
  238. return false;
  239. };
  240.  
  241. this.isSplitTarget = function(that, blob, cell) {
  242. if (that.canSplit(cell, blob)) {
  243. return true;
  244. }
  245. return false;
  246. };
  247.  
  248. this.getTimeToRemerge = function(mass){
  249. return ((mass*0.02) + 30);
  250. };
  251.  
  252. this.separateListBasedOnFunction = function(that, listToUse, blob) {
  253. var foodElementList = [];
  254. var threatList = [];
  255. var virusList = [];
  256. var splitTargetList = [];
  257. var foundMaster = [];
  258.  
  259. var player = getPlayer();
  260.  
  261. Object.keys(listToUse).forEach(function(element, index) {
  262. var isMe = that.isItMe(player, listToUse[element]);
  263.  
  264. if (!isMe) {
  265. if (!that.master && listToUse[element].id == that.masterId) {
  266. foundMaster.push(listToUse[element]);
  267. console.log("Found master! " + that.masterId + ", " + listToUse[element].id);
  268. } else if (that.isFood(blob, listToUse[element]) && listToUse[element].isNotMoving()) {
  269. //IT'S FOOD!
  270. foodElementList.push(listToUse[element]);
  271. } else if (that.isThreat(blob, listToUse[element])) {
  272. //IT'S DANGER!
  273. if ((!that.master && listToUse[element].id != that.masterId) || that.master) {
  274. threatList.push(listToUse[element]);
  275. } else {
  276. console.log("Found master! " + that.masterId);
  277. }
  278. } else if (that.isVirus(blob, listToUse[element])) {
  279. //IT'S VIRUS!
  280. virusList.push(listToUse[element]);
  281. }
  282. else if (that.isSplitTarget(that, blob, listToUse[element])) {
  283. drawCircle(listToUse[element].x, listToUse[element].y, listToUse[element].size + 50, 7);
  284. splitTargetList.push(listToUse[element]);
  285. foodElementList.push(listToUse[element]);
  286. }
  287. }/*else if(isMe && (getBlobCount(getPlayer()) > 0)){
  288. //Attempt to make the other cell follow the mother one
  289. foodElementList.push(listToUse[element]);
  290. }*/
  291. });
  292.  
  293. foodList = [];
  294. for (var i = 0; i < foodElementList.length; i++) {
  295. foodList.push([foodElementList[i].x, foodElementList[i].y, foodElementList[i].size]);
  296. }
  297.  
  298. return [foodList, threatList, virusList, splitTargetList, foundMaster];
  299. };
  300.  
  301. this.getAll = function(blob) {
  302. var dotList = [];
  303. var player = getPlayer();
  304. var interNodes = getMemoryCells();
  305.  
  306. dotList = this.separateListBasedOnFunction(this, interNodes, blob);
  307.  
  308. return dotList;
  309. };
  310.  
  311. this.clusterFood = function(foodList, blobSize) {
  312. var clusters = [];
  313. var addedCluster = false;
  314.  
  315. //1: x
  316. //2: y
  317. //3: size or value
  318. //4: Angle, not set here.
  319.  
  320. for (var i = 0; i < foodList.length; i++) {
  321. for (var j = 0; j < clusters.length; j++) {
  322. if (this.computeDistance(foodList[i][0], foodList[i][1], clusters[j][0], clusters[j][1]) < blobSize * 1.5) {
  323. clusters[j][0] = (foodList[i][0] + clusters[j][0]) / 2;
  324. clusters[j][1] = (foodList[i][1] + clusters[j][1]) / 2;
  325. clusters[j][2] += foodList[i][2];
  326. addedCluster = true;
  327. break;
  328. }
  329. }
  330. if (!addedCluster) {
  331. clusters.push([foodList[i][0], foodList[i][1], foodList[i][2], 0]);
  332. }
  333. addedCluster = false;
  334. }
  335. return clusters;
  336. };
  337.  
  338. this.getAngle = function(x1, y1, x2, y2) {
  339. //Handle vertical and horizontal lines.
  340.  
  341. if (x1 == x2) {
  342. if (y1 < y2) {
  343. return 271;
  344. //return 89;
  345. } else {
  346. return 89;
  347. }
  348. }
  349.  
  350. return (Math.round(Math.atan2(-(y1 - y2), -(x1 - x2)) / Math.PI * 180 + 180));
  351. };
  352.  
  353. this.slope = function(x1, y1, x2, y2) {
  354. var m = (y1 - y2) / (x1 - x2);
  355.  
  356. return m;
  357. };
  358.  
  359. this.slopeFromAngle = function(degree) {
  360. if (degree == 270) {
  361. degree = 271;
  362. } else if (degree == 90) {
  363. degree = 91;
  364. }
  365. return Math.tan((degree - 180) / 180 * Math.PI);
  366. };
  367.  
  368. //Given two points on a line, finds the slope of a perpendicular line crossing it.
  369. this.inverseSlope = function(x1, y1, x2, y2) {
  370. var m = this.slope(x1, y1, x2, y2);
  371. return (-1) / m;
  372. };
  373.  
  374. //Given a slope and an offset, returns two points on that line.
  375. this.pointsOnLine = function(slope, useX, useY, distance) {
  376. var b = useY - slope * useX;
  377. var r = Math.sqrt(1 + slope * slope);
  378.  
  379. var newX1 = (useX + (distance / r));
  380. var newY1 = (useY + ((distance * slope) / r));
  381. var newX2 = (useX + ((-distance) / r));
  382. var newY2 = (useY + (((-distance) * slope) / r));
  383.  
  384. return [
  385. [newX1, newY1],
  386. [newX2, newY2]
  387. ];
  388. };
  389.  
  390. this.followAngle = function(angle, useX, useY, distance) {
  391. var slope = this.slopeFromAngle(angle);
  392. var coords = this.pointsOnLine(slope, useX, useY, distance);
  393.  
  394. var side = (angle - 90).mod(360);
  395. if (side < 180) {
  396. return coords[1];
  397. } else {
  398. return coords[0];
  399. }
  400. };
  401.  
  402. //Using a line formed from point a to b, tells if point c is on S side of that line.
  403. this.isSideLine = function(a, b, c) {
  404. if ((b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) > 0) {
  405. return true;
  406. }
  407. return false;
  408. };
  409.  
  410. //angle range2 is within angle range2
  411. //an Angle is a point and a distance between an other point [5, 40]
  412. this.angleRangeIsWithin = function(range1, range2) {
  413. if (range2[0] == (range2[0] + range2[1]).mod(360)) {
  414. return true;
  415. }
  416. //console.log("r1: " + range1[0] + ", " + range1[1] + " ... r2: " + range2[0] + ", " + range2[1]);
  417.  
  418. var distanceFrom0 = (range1[0] - range2[0]).mod(360);
  419. var distanceFrom1 = (range1[1] - range2[0]).mod(360);
  420.  
  421. if (distanceFrom0 < range2[1] && distanceFrom1 < range2[1] && distanceFrom0 < distanceFrom1) {
  422. return true;
  423. }
  424. return false;
  425. };
  426.  
  427. this.angleRangeIsWithinInverted = function(range1, range2) {
  428. var distanceFrom0 = (range1[0] - range2[0]).mod(360);
  429. var distanceFrom1 = (range1[1] - range2[0]).mod(360);
  430.  
  431. if (distanceFrom0 < range2[1] && distanceFrom1 < range2[1] && distanceFrom0 > distanceFrom1) {
  432. return true;
  433. }
  434. return false;
  435. };
  436.  
  437. this.angleIsWithin = function(angle, range) {
  438. var diff = (this.rangeToAngle(range) - angle).mod(360);
  439. if (diff >= 0 && diff <= range[1]) {
  440. return true;
  441. }
  442. return false;
  443. };
  444.  
  445. this.rangeToAngle = function(range) {
  446. return (range[0] + range[1]).mod(360);
  447. };
  448.  
  449. this.anglePair = function(range) {
  450. return (range[0] + ", " + this.rangeToAngle(range) + " range: " + range[1]);
  451. };
  452.  
  453. this.computeAngleRanges = function(blob1, blob2) {
  454. var mainAngle = this.getAngle(blob1.x, blob1.y, blob2.x, blob2.y);
  455. var leftAngle = (mainAngle - 90).mod(360);
  456. var rightAngle = (mainAngle + 90).mod(360);
  457.  
  458. var blob1Left = this.followAngle(leftAngle, blob1.x, blob1.y, blob1.size);
  459. var blob1Right = this.followAngle(rightAngle, blob1.x, blob1.y, blob1.size);
  460.  
  461. var blob2Left = this.followAngle(rightAngle, blob2.x, blob2.y, blob2.size);
  462. var blob2Right = this.followAngle(leftAngle, blob2.x, blob2.y, blob2.size);
  463.  
  464. var blob1AngleLeft = this.getAngle(blob2.x, blob2.y, blob1Left[0], blob1Left[1]);
  465. var blob1AngleRight = this.getAngle(blob2.x, blob2.y, blob1Right[0], blob1Right[1]);
  466.  
  467. var blob2AngleLeft = this.getAngle(blob1.x, blob1.y, blob2Left[0], blob2Left[1]);
  468. var blob2AngleRight = this.getAngle(blob1.x, blob1.y, blob2Right[0], blob2Right[1]);
  469.  
  470. var blob1Range = (blob1AngleRight - blob1AngleLeft).mod(360);
  471. var blob2Range = (blob2AngleRight - blob2AngleLeft).mod(360);
  472.  
  473. var tempLine = this.followAngle(blob2AngleLeft, blob2Left[0], blob2Left[1], 400);
  474. //drawLine(blob2Left[0], blob2Left[1], tempLine[0], tempLine[1], 0);
  475.  
  476. if ((blob1Range / blob2Range) > 1) {
  477. drawPoint(blob1Left[0], blob1Left[1], 3, "");
  478. drawPoint(blob1Right[0], blob1Right[1], 3, "");
  479. drawPoint(blob1.x, blob1.y, 3, "" + blob1Range + ", " + blob2Range + " R: " + (Math.round((blob1Range / blob2Range) * 1000) / 1000));
  480. }
  481.  
  482. //drawPoint(blob2.x, blob2.y, 3, "" + blob1Range);
  483. };
  484.  
  485. this.debugAngle = function(angle, text) {
  486. var player = getPlayer();
  487. var line1 = this.followAngle(angle, player[0].x, player[0].y, 300);
  488. drawLine(player[0].x, player[0].y, line1[0], line1[1], 5);
  489. drawPoint(line1[0], line1[1], 5, "" + text);
  490. };
  491.  
  492. //TODO: Don't let this function do the radius math.
  493. this.getEdgeLinesFromPoint = function(blob1, blob2, radius) {
  494. var px = blob1.x;
  495. var py = blob1.y;
  496.  
  497. var cx = blob2.x;
  498. var cy = blob2.y;
  499.  
  500. //var radius = blob2.size;
  501.  
  502. /*if (blob2.isVirus()) {
  503. radius = blob1.size;
  504. } else if(canSplit(blob1, blob2)) {
  505. radius += splitDistance;
  506. } else {
  507. radius += blob1.size * 2;
  508. }*/
  509.  
  510. var shouldInvert = false;
  511.  
  512. var tempRadius = this.computeDistance(px, py, cx, cy);
  513. if (tempRadius <= radius) {
  514. radius = tempRadius - 5;
  515. shouldInvert = true;
  516. }
  517.  
  518. var dx = cx - px;
  519. var dy = cy - py;
  520. var dd = Math.sqrt(dx * dx + dy * dy);
  521. var a = Math.asin(radius / dd);
  522. var b = Math.atan2(dy, dx);
  523.  
  524. var t = b - a;
  525. var ta = {
  526. x: radius * Math.sin(t),
  527. y: radius * -Math.cos(t)
  528. };
  529.  
  530. t = b + a;
  531. var tb = {
  532. x: radius * -Math.sin(t),
  533. y: radius * Math.cos(t)
  534. };
  535.  
  536. var angleLeft = this.getAngle(cx + ta.x, cy + ta.y, px, py);
  537. var angleRight = this.getAngle(cx + tb.x, cy + tb.y, px, py);
  538. var angleDistance = (angleRight - angleLeft).mod(360);
  539.  
  540. /*if (shouldInvert) {
  541. var temp = angleLeft;
  542. angleLeft = (angleRight + 180).mod(360);
  543. angleRight = (temp + 180).mod(360);
  544. angleDistance = (angleRight - angleLeft).mod(360);
  545. }*/
  546.  
  547. return [angleLeft, angleDistance, [cx + tb.x, cy + tb.y],
  548. [cx + ta.x, cy + ta.y]
  549. ];
  550. };
  551.  
  552. this.invertAngle = function(range) {
  553. var angle1 = this.rangeToAngle(badAngles[i]);
  554. var angle2 = (badAngles[i][0] - angle1).mod(360);
  555. return [angle1, angle2];
  556. },
  557.  
  558. this.addWall = function(listToUse, blob) {
  559. //var mapSizeX = Math.abs(f.getMapStartX - f.getMapEndX);
  560. //var mapSizeY = Math.abs(f.getMapStartY - f.getMapEndY);
  561. //var distanceFromWallX = mapSizeX/3;
  562. //var distanceFromWallY = mapSizeY/3;
  563. var distanceFromWallY = 2000;
  564. var distanceFromWallX = 2000;
  565. if (blob.x < getMapStartX() + distanceFromWallX) {
  566. //LEFT
  567. //console.log("Left");
  568. listToUse.push([
  569. [90, true],
  570. [270, false], this.computeDistance(getMapStartX(), blob.y, blob.x, blob.y)
  571. ]);
  572. var lineLeft = this.followAngle(90, blob.x, blob.y, 190 + blob.size);
  573. var lineRight = this.followAngle(270, blob.x, blob.y, 190 + blob.size);
  574. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  575. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  576. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  577. }
  578. if (blob.y < getMapStartY() + distanceFromWallY) {
  579. //TOP
  580. //console.log("TOP");
  581. listToUse.push([
  582. [180, true],
  583. [0, false], this.computeDistance(blob.x, getMapStartY, blob.x, blob.y)
  584. ]);
  585. var lineLeft = this.followAngle(180, blob.x, blob.y, 190 + blob.size);
  586. var lineRight = this.followAngle(360, blob.x, blob.y, 190 + blob.size);
  587. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  588. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  589. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  590. }
  591. if (blob.x > getMapEndX() - distanceFromWallX) {
  592. //RIGHT
  593. //console.log("RIGHT");
  594. listToUse.push([
  595. [270, true],
  596. [90, false], this.computeDistance(getMapEndX(), blob.y, blob.x, blob.y)
  597. ]);
  598. var lineLeft = this.followAngle(270, blob.x, blob.y, 190 + blob.size);
  599. var lineRight = this.followAngle(90, blob.x, blob.y, 190 + blob.size);
  600. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  601. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  602. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  603. }
  604. if (blob.y > getMapEndY() - distanceFromWallY) {
  605. //BOTTOM
  606. //console.log("BOTTOM");
  607. listToUse.push([
  608. [0, true],
  609. [180, false], this.computeDistance(blob.x, getMapEndY(), blob.x, blob.y)
  610. ]);
  611. var lineLeft = this.followAngle(0, blob.x, blob.y, 190 + blob.size);
  612. var lineRight = this.followAngle(180, blob.x, blob.y, 190 + blob.size);
  613. drawLine(blob.x, blob.y, lineLeft[0], lineLeft[1], 5);
  614. drawLine(blob.x, blob.y, lineRight[0], lineRight[1], 5);
  615. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob.x, blob.y, 5);
  616. }
  617. return listToUse;
  618. };
  619.  
  620. //listToUse contains angles in the form of [angle, boolean].
  621. //boolean is true when the range is starting. False when it's ending.
  622. //range = [[angle1, true], [angle2, false]]
  623.  
  624. this.getAngleIndex = function(listToUse, angle) {
  625. if (listToUse.length == 0) {
  626. return 0;
  627. }
  628.  
  629. for (var i = 0; i < listToUse.length; i++) {
  630. if (angle <= listToUse[i][0]) {
  631. return i;
  632. }
  633. }
  634.  
  635. return listToUse.length;
  636. };
  637.  
  638. this.addAngle = function(listToUse, range) {
  639. //#1 Find first open element
  640. //#2 Try to add range1 to the list. If it is within other range, don't add it, set a boolean.
  641. //#3 Try to add range2 to the list. If it is withing other range, don't add it, set a boolean.
  642.  
  643. //TODO: Only add the new range at the end after the right stuff has been removed.
  644.  
  645. var newListToUse = listToUse.slice();
  646.  
  647. var startIndex = 1;
  648.  
  649. if (newListToUse.length > 0 && !newListToUse[0][1]) {
  650. startIndex = 0;
  651. }
  652.  
  653. var startMark = this.getAngleIndex(newListToUse, range[0][0]);
  654. var startBool = startMark.mod(2) != startIndex;
  655.  
  656. var endMark = this.getAngleIndex(newListToUse, range[1][0]);
  657. var endBool = endMark.mod(2) != startIndex;
  658.  
  659. var removeList = [];
  660.  
  661. if (startMark != endMark) {
  662. //Note: If there is still an error, this would be it.
  663. var biggerList = 0;
  664. if (endMark == newListToUse.length) {
  665. biggerList = 1;
  666. }
  667.  
  668. for (var i = startMark; i < startMark + (endMark - startMark).mod(newListToUse.length + biggerList); i++) {
  669. removeList.push((i).mod(newListToUse.length));
  670. }
  671. } else if (startMark < newListToUse.length && endMark < newListToUse.length) {
  672. var startDist = (newListToUse[startMark][0] - range[0][0]).mod(360);
  673. var endDist = (newListToUse[endMark][0] - range[1][0]).mod(360);
  674.  
  675. if (startDist < endDist) {
  676. for (var i = 0; i < newListToUse.length; i++) {
  677. removeList.push(i);
  678. }
  679. }
  680. }
  681.  
  682. removeList.sort(function(a, b){return b-a;});
  683.  
  684. for (var i = 0; i < removeList.length; i++) {
  685. newListToUse.splice(removeList[i], 1);
  686. }
  687.  
  688. if (startBool) {
  689. newListToUse.splice(this.getAngleIndex(newListToUse, range[0][0]), 0, range[0]);
  690. }
  691. if (endBool) {
  692. newListToUse.splice(this.getAngleIndex(newListToUse, range[1][0]), 0, range[1]);
  693. }
  694.  
  695. return newListToUse;
  696. };
  697.  
  698. this.getAngleRange = function(blob1, blob2, index, radius) {
  699. var angleStuff = this.getEdgeLinesFromPoint(blob1, blob2, radius);
  700.  
  701. var leftAngle = angleStuff[0];
  702. var rightAngle = this.rangeToAngle(angleStuff);
  703. var difference = angleStuff[1];
  704.  
  705. drawPoint(angleStuff[2][0], angleStuff[2][1], 3, "");
  706. drawPoint(angleStuff[3][0], angleStuff[3][1], 3, "");
  707.  
  708. //console.log("Adding badAngles: " + leftAngle + ", " + rightAngle + " diff: " + difference);
  709.  
  710. var lineLeft = this.followAngle(leftAngle, blob1.x, blob1.y, 150 + blob1.size - index * 10);
  711. var lineRight = this.followAngle(rightAngle, blob1.x, blob1.y, 150 + blob1.size - index * 10);
  712.  
  713. if (blob2.isVirus()) {
  714. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 6);
  715. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 6);
  716. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 6);
  717. } else if(getCells().hasOwnProperty(blob2.id)) {
  718. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 0);
  719. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 0);
  720. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 0);
  721. } else {
  722. drawLine(blob1.x, blob1.y, lineLeft[0], lineLeft[1], 3);
  723. drawLine(blob1.x, blob1.y, lineRight[0], lineRight[1], 3);
  724. drawArc(lineLeft[0], lineLeft[1], lineRight[0], lineRight[1], blob1.x, blob1.y, 3);
  725. }
  726.  
  727. return [leftAngle, difference];
  728. };
  729.  
  730. //Given a list of conditions, shift the angle to the closest available spot respecting the range given.
  731. this.shiftAngle = function(listToUse, angle, range) {
  732. //TODO: shiftAngle needs to respect the range! DONE?
  733. for (var i = 0; i < listToUse.length; i++) {
  734. if (this.angleIsWithin(angle, listToUse[i])) {
  735. //console.log("Shifting needed!");
  736.  
  737. var angle1 = listToUse[i][0];
  738. var angle2 = this.rangeToAngle(listToUse[i]);
  739.  
  740. var dist1 = (angle - angle1).mod(360);
  741. var dist2 = (angle2 - angle).mod(360);
  742.  
  743. if (dist1 < dist2) {
  744. if (this.angleIsWithin(angle1, range)) {
  745. return angle1;
  746. } else {
  747. return angle2;
  748. }
  749. } else {
  750. if (this.angleIsWithin(angle2, range)) {
  751. return angle2;
  752. } else {
  753. return angle1;
  754. }
  755. }
  756. }
  757. }
  758. //console.log("No Shifting Was needed!");
  759. return angle;
  760. };
  761.  
  762. /**
  763. * This is the main bot logic. This is called quite often.
  764. * @return A 2 dimensional array with coordinates for every cells. [[x, y], [x, y]]
  765. */
  766. this.mainLoop = function() {
  767. var player = getPlayer();
  768. var interNodes = getMemoryCells();
  769.  
  770. if ( /*!toggle*/ 1) {
  771. //The following code converts the mouse position into an
  772. //absolute game coordinate.
  773. var useMouseX = screenToGameX(getMouseX());
  774. var useMouseY = screenToGameY(getMouseY());
  775. tempPoint = [useMouseX, useMouseY, 1];
  776.  
  777. //The current destination that the cells were going towards.
  778. var tempMoveX = getPointX();
  779. var tempMoveY = getPointY();
  780.  
  781. //This variable will be returned at the end.
  782. //It will contain the destination choices for all the cells.
  783. //BTW!!! ERROR ERROR ABORT MISSION!!!!!!! READ BELOW -----------
  784. //
  785. //SINCE IT'S STUPID NOW TO ASK EACH CELL WHERE THEY WANT TO GO,
  786. //THE BOT SHOULD SIMPLY PICK ONE AND THAT'S IT, I MEAN WTF....
  787. var destinationChoices = []; //destination, size, danger
  788.  
  789. //Just to make sure the player is alive.
  790. if (player.length > 0) {
  791. if (!this.master && Date.now() - this.lastMasterUpdate > 5000) {
  792. var query = new Parse.Query(this.MasterLocation);
  793. var self = this;
  794. query.equalTo("server", getServer());
  795. query.first().then(function(object) {
  796. if (typeof object != 'undefined') {
  797. console.log("Previous Location: " + self.masterLocation);
  798. console.log("Going to: " + object.get("location"));
  799. self.masterLocation = object.get("location");
  800. self.masterLocation = object.get("location");
  801. self.masterId = object.get("cellId");
  802. console.log("Updated Location: " + self.masterLocation);
  803. } else {
  804. console.log("No master was found... Let's be the master.");
  805. self.master = true;
  806. }
  807. },
  808. function(error) {
  809. console.log("Error: " + error.code + " " + error.message);
  810. });
  811. this.lastMasterUpdate = Date.now();
  812. }
  813.  
  814. //Loop through all the player's cells.
  815. for (var k = 0; k < player.length; k++) {
  816. if (true) {
  817. drawPoint(player[k].x, player[k].y + player[k].size, 0, "" + (getLastUpdate() - player[k].birth) + " / " + (30000 + (player[k].birthMass * 57) - (getLastUpdate() - player[k].birth)) + " / " + player[k].birthMass);
  818. }
  819. }
  820.  
  821. //Loops only for one cell for now.
  822. for (var k = 0; /*k < player.length*/ k < 1; k++) {
  823.  
  824. //console.log("Working on blob: " + k);
  825.  
  826. drawCircle(player[k].x, player[k].y, player[k].size + this.splitDistance, 5);
  827. //drawPoint(player[0].x, player[0].y - player[0].size, 3, "" + Math.floor(player[0].x) + ", " + Math.floor(player[0].y));
  828.  
  829. //var allDots = processEverything(interNodes);
  830.  
  831. //loop through everything that is on the screen and
  832. //separate everything in it's own category.
  833. var allIsAll = this.getAll(player[k]);
  834.  
  835. //The food stored in element 0 of allIsAll
  836. var allPossibleFood = allIsAll[0];
  837. //The threats are stored in element 1 of allIsAll
  838. var allPossibleThreats = allIsAll[1];
  839. //The viruses are stored in element 2 of allIsAll
  840. var allPossibleViruses = allIsAll[2];
  841.  
  842. if (allIsAll[4].length > 0) {
  843. console.log("Found my real Master! " + allIsAll[4][0].id);
  844. this.masterLocation = [allIsAll[4][0].x, allIsAll[4][0].y]
  845. }
  846.  
  847.  
  848. //The bot works by removing angles in which it is too
  849. //dangerous to travel towards to.
  850. var badAngles = [];
  851. var obstacleList = [];
  852.  
  853. var isSafeSpot = true;
  854. var isMouseSafe = true;
  855.  
  856. var clusterAllFood = this.clusterFood(allPossibleFood, player[k].size);
  857.  
  858. //console.log("Looking for enemies!");
  859.  
  860. //Loop through all the cells that were identified as threats.
  861. for (var i = 0; i < allPossibleThreats.length; i++) {
  862.  
  863. var enemyDistance = this.computeDistanceFromCircleEdge(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y, allPossibleThreats[i].size);
  864.  
  865. allPossibleThreats[i].enemyDist = enemyDistance;
  866. }
  867.  
  868. /*allPossibleThreats.sort(function(a, b){
  869. return a.enemyDist-b.enemyDist;
  870. })*/
  871.  
  872. for (var i = 0; i < allPossibleThreats.length; i++) {
  873.  
  874. var enemyDistance = this.computeDistance(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y);
  875.  
  876. var splitDangerDistance = allPossibleThreats[i].size + this.splitDistance + 150;
  877.  
  878. var normalDangerDistance = allPossibleThreats[i].size + 150;
  879.  
  880. var shiftDistance = player[k].size;
  881.  
  882. //console.log("Found distance.");
  883.  
  884. var enemyCanSplit = (this.master ? this.canSplit(player[k], allPossibleThreats[i]) : false);
  885. for (var j = clusterAllFood.length - 1; j >= 0 ; j--) {
  886. var secureDistance = (enemyCanSplit ? splitDangerDistance : normalDangerDistance);
  887. if (this.computeDistance(allPossibleThreats[i].x, allPossibleThreats[i].y, clusterAllFood[j][0], clusterAllFood[j][1]) < secureDistance)
  888. clusterAllFood.splice(j, 1);
  889. }
  890.  
  891. //console.log("Removed some food.");
  892.  
  893. if (enemyCanSplit) {
  894. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, splitDangerDistance, 0);
  895. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, splitDangerDistance + shiftDistance, 6);
  896. } else {
  897. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, normalDangerDistance, 3);
  898. drawCircle(allPossibleThreats[i].x, allPossibleThreats[i].y, normalDangerDistance + shiftDistance, 6);
  899. }
  900.  
  901. if (allPossibleThreats[i].danger && getLastUpdate() - allPossibleThreats[i].dangerTimeOut > 1000) {
  902.  
  903. allPossibleThreats[i].danger = false;
  904. }
  905.  
  906. /*if ((enemyCanSplit && enemyDistance < splitDangerDistance) ||
  907. (!enemyCanSplit && enemyDistance < normalDangerDistance)) {
  908. allPossibleThreats[i].danger = true;
  909. allPossibleThreats[i].dangerTimeOut = f.getLastUpdate();
  910. }*/
  911.  
  912. //console.log("Figured out who was important.");
  913.  
  914. if ((enemyCanSplit && enemyDistance < splitDangerDistance) || (enemyCanSplit && allPossibleThreats[i].danger)) {
  915.  
  916. badAngles.push(this.getAngleRange(player[k], allPossibleThreats[i], i, splitDangerDistance).concat(allPossibleThreats[i].enemyDist));
  917.  
  918. } else if ((!enemyCanSplit && enemyDistance < normalDangerDistance) || (!enemyCanSplit && allPossibleThreats[i].danger)) {
  919.  
  920. badAngles.push(this.getAngleRange(player[k], allPossibleThreats[i], i, normalDangerDistance).concat(allPossibleThreats[i].enemyDist));
  921.  
  922. } else if (enemyCanSplit && enemyDistance < splitDangerDistance + shiftDistance) {
  923. var tempOb = this.getAngleRange(player[k], allPossibleThreats[i], i, splitDangerDistance + shiftDistance);
  924. var angle1 = tempOb[0];
  925. var angle2 = this.rangeToAngle(tempOb);
  926.  
  927. obstacleList.push([[angle1, true], [angle2, false]]);
  928. } else if (!enemyCanSplit && enemyDistance < normalDangerDistance + shiftDistance) {
  929. var tempOb = this.getAngleRange(player[k], allPossibleThreats[i], i, normalDangerDistance + shiftDistance);
  930. var angle1 = tempOb[0];
  931. var angle2 = this.rangeToAngle(tempOb);
  932.  
  933. obstacleList.push([[angle1, true], [angle2, false]]);
  934. }
  935. //console.log("Done with enemy: " + i);
  936. }
  937.  
  938. //console.log("Done looking for enemies!");
  939.  
  940. var goodAngles = [];
  941. var stupidList = [];
  942.  
  943. for (var i = 0; i < allPossibleViruses.length; i++) {
  944. if (player[k].size < allPossibleViruses[i].size) {
  945. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, allPossibleViruses[i].size + 10, 3);
  946. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, allPossibleViruses[i].size * 2, 6);
  947.  
  948. } else {
  949. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].size + 50, 3);
  950. drawCircle(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].size * 2, 6);
  951. }
  952. }
  953.  
  954. for (var i = 0; i < allPossibleViruses.length; i++) {
  955. var virusDistance = this.computeDistance(allPossibleViruses[i].x, allPossibleViruses[i].y, player[k].x, player[k].y);
  956. if (player[k].size < allPossibleViruses[i].size) {
  957. if (virusDistance < (allPossibleViruses[i].size * 2)) {
  958. var tempOb = this.getAngleRange(player[k], allPossibleViruses[i], i, allPossibleViruses[i].size + 10);
  959. var angle1 = tempOb[0];
  960. var angle2 = this.rangeToAngle(tempOb);
  961. obstacleList.push([[angle1, true], [angle2, false]]);
  962. }
  963. } else {
  964. if (virusDistance < (player[k].size * 2)) {
  965. var tempOb = this.getAngleRange(player[k], allPossibleViruses[i], i, player[k].size + 50);
  966. var angle1 = tempOb[0];
  967. var angle2 = this.rangeToAngle(tempOb);
  968. obstacleList.push([[angle1, true], [angle2, false]]);
  969. }
  970. }
  971. }
  972.  
  973. if (badAngles.length > 0) {
  974. //NOTE: This is only bandaid wall code. It's not the best way to do it.
  975. stupidList = this.addWall(stupidList, player[k]);
  976. }
  977.  
  978. for (var i = 0; i < badAngles.length; i++) {
  979. var angle1 = badAngles[i][0];
  980. var angle2 = this.rangeToAngle(badAngles[i]);
  981. stupidList.push([[angle1, true], [angle2, false], badAngles[i][2]]);
  982. }
  983.  
  984. //stupidList.push([[45, true], [135, false]]);
  985. //stupidList.push([[10, true], [200, false]]);
  986.  
  987. stupidList.sort(function(a, b){
  988. //console.log("Distance: " + a[2] + ", " + b[2]);
  989. return a[2]-b[2];
  990. });
  991.  
  992. //console.log("Added random noob stuff.");
  993.  
  994. var sortedInterList = [];
  995. var sortedObList = [];
  996.  
  997. for (var i = 0; i < stupidList.length; i++) {
  998. //console.log("Adding to sorted: " + stupidList[i][0][0] + ", " + stupidList[i][1][0]);
  999. var tempList = this.addAngle(sortedInterList, stupidList[i]);
  1000.  
  1001. if (tempList.length == 0) {
  1002. console.log("MAYDAY IT'S HAPPENING!");
  1003. break;
  1004. } else {
  1005. sortedInterList = tempList;
  1006. }
  1007. }
  1008.  
  1009. for (var i = 0; i < obstacleList.length; i++) {
  1010. sortedObList = this.addAngle(sortedObList, obstacleList[i]);
  1011.  
  1012. if (sortedObList.length == 0) {
  1013. break;
  1014. }
  1015. }
  1016.  
  1017. var offsetI = 0;
  1018. var obOffsetI = 1;
  1019.  
  1020. if (sortedInterList.length > 0 && sortedInterList[0][1]) {
  1021. offsetI = 1;
  1022. }
  1023. if (sortedObList.length > 0 && sortedObList[0][1]) {
  1024. obOffsetI = 0;
  1025. }
  1026.  
  1027. var goodAngles = [];
  1028. var obstacleAngles = [];
  1029.  
  1030. for (var i = 0; i < sortedInterList.length; i += 2) {
  1031. var angle1 = sortedInterList[(i + offsetI).mod(sortedInterList.length)][0];
  1032. var angle2 = sortedInterList[(i + 1 + offsetI).mod(sortedInterList.length)][0];
  1033. var diff = (angle2 - angle1).mod(360);
  1034. goodAngles.push([angle1, diff]);
  1035. }
  1036.  
  1037. for (var i = 0; i < sortedObList.length; i += 2) {
  1038. var angle1 = sortedObList[(i + obOffsetI).mod(sortedObList.length)][0];
  1039. var angle2 = sortedObList[(i + 1 + obOffsetI).mod(sortedObList.length)][0];
  1040. var diff = (angle2 - angle1).mod(360);
  1041. obstacleAngles.push([angle1, diff]);
  1042. }
  1043.  
  1044. for (var i = 0; i < goodAngles.length; i++) {
  1045. var line1 = this.followAngle(goodAngles[i][0], player[k].x, player[k].y, 100 + player[k].size);
  1046. var line2 = this.followAngle((goodAngles[i][0] + goodAngles[i][1]).mod(360), player[k].x, player[k].y, 100 + player[k].size);
  1047. drawLine(player[k].x, player[k].y, line1[0], line1[1], 1);
  1048. drawLine(player[k].x, player[k].y, line2[0], line2[1], 1);
  1049.  
  1050. drawArc(line1[0], line1[1], line2[0], line2[1], player[k].x, player[k].y, 1);
  1051.  
  1052. //drawPoint(player[0].x, player[0].y, 2, "");
  1053.  
  1054. drawPoint(line1[0], line1[1], 0, "" + i + ": 0");
  1055. drawPoint(line2[0], line2[1], 0, "" + i + ": 1");
  1056. }
  1057.  
  1058. for (var i = 0; i < obstacleAngles.length; i++) {
  1059. var line1 = this.followAngle(obstacleAngles[i][0], player[k].x, player[k].y, 50 + player[k].size);
  1060. var line2 = this.followAngle((obstacleAngles[i][0] + obstacleAngles[i][1]).mod(360), player[k].x, player[k].y, 50 + player[k].size);
  1061. drawLine(player[k].x, player[k].y, line1[0], line1[1], 6);
  1062. drawLine(player[k].x, player[k].y, line2[0], line2[1], 6);
  1063.  
  1064. drawArc(line1[0], line1[1], line2[0], line2[1], player[k].x, player[k].y, 6);
  1065.  
  1066. //drawPoint(player[0].x, player[0].y, 2, "");
  1067.  
  1068. drawPoint(line1[0], line1[1], 0, "" + i + ": 0");
  1069. drawPoint(line2[0], line2[1], 0, "" + i + ": 1");
  1070. }
  1071.  
  1072. if (!this.master && goodAngles.length == 0 && (player[k].size * player[k].size / 100) > 50) {
  1073. //This is the slave mode
  1074. console.log("Really Going to: " + this.masterLocation);
  1075. var distance = this.computeDistance(player[k].x, player[k].y, this.masterLocation[0], this.masterLocation[1]);
  1076.  
  1077. var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(this.masterLocation[0], this.masterLocation[1], player[k].x, player[k].y), [0, 360]);
  1078.  
  1079. var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);
  1080.  
  1081. destinationChoices = destination;
  1082. drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
  1083. } else if (this.toggleFollow && goodAngles.length == 0) {
  1084. //This is the follow the mouse mode
  1085. var distance = this.computeDistance(player[k].x, player[k].y, tempPoint[0], tempPoint[1]);
  1086.  
  1087. var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(tempPoint[0], tempPoint[1], player[k].x, player[k].y), [0, 360]);
  1088.  
  1089. var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);
  1090.  
  1091. destinationChoices = destination;
  1092. drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
  1093. //tempMoveX = destination[0];
  1094. //tempMoveY = destination[1];
  1095.  
  1096. } else if (goodAngles.length > 0) {
  1097. var bIndex = goodAngles[0];
  1098. var biggest = goodAngles[0][1];
  1099. for (var i = 1; i < goodAngles.length; i++) {
  1100. var size = goodAngles[i][1];
  1101. if (size > biggest) {
  1102. biggest = size;
  1103. bIndex = goodAngles[i];
  1104. }
  1105. }
  1106. var perfectAngle = (bIndex[0] + bIndex[1] / 2).mod(360);
  1107.  
  1108. perfectAngle = this.shiftAngle(obstacleAngles, perfectAngle, bIndex);
  1109.  
  1110. var line1 = this.followAngle(perfectAngle, player[k].x, player[k].y, verticalDistance());
  1111.  
  1112. destinationChoices = line1;
  1113. drawLine(player[k].x, player[k].y, line1[0], line1[1], 7);
  1114. //tempMoveX = line1[0];
  1115. //tempMoveY = line1[1];
  1116. } else if (badAngles.length > 0 && goodAngles == 0) {
  1117. //When there are enemies around but no good angles
  1118. //You're likely screwed. (This should never happen.)
  1119.  
  1120. console.log("Failed");
  1121. destinationChoices = [tempMoveX, tempMoveY];
  1122. /*var angleWeights = [] //Put weights on the angles according to enemy distance
  1123. for (var i = 0; i < allPossibleThreats.length; i++){
  1124. var dist = this.computeDistance(player[k].x, player[k].y, allPossibleThreats[i].x, allPossibleThreats[i].y);
  1125. var angle = this.getAngle(allPossibleThreats[i].x, allPossibleThreats[i].y, player[k].x, player[k].y);
  1126. angleWeights.push([angle,dist]);
  1127. }
  1128. var maxDist = 0;
  1129. var finalAngle = 0;
  1130. for (var i = 0; i < angleWeights.length; i++){
  1131. if (angleWeights[i][1] > maxDist){
  1132. maxDist = angleWeights[i][1];
  1133. finalAngle = (angleWeights[i][0] + 180).mod(360);
  1134. }
  1135. }
  1136. var line1 = this.followAngle(finalAngle,player[k].x,player[k].y,f.verticalDistance());
  1137. drawLine(player[k].x, player[k].y, line1[0], line1[1], 2);
  1138. destinationChoices.push(line1);*/
  1139. } else if (clusterAllFood.length > 0) {
  1140. for (var i = 0; i < clusterAllFood.length; i++) {
  1141. //console.log("mefore: " + clusterAllFood[i][2]);
  1142. //This is the cost function. Higher is better.
  1143.  
  1144. var clusterAngle = this.getAngle(clusterAllFood[i][0], clusterAllFood[i][1], player[k].x, player[k].y);
  1145.  
  1146. clusterAllFood[i][2] = clusterAllFood[i][2] * 6 - this.computeDistance(clusterAllFood[i][0], clusterAllFood[i][1], player[k].x, player[k].y);
  1147. //console.log("Current Value: " + clusterAllFood[i][2]);
  1148.  
  1149. //(goodAngles[bIndex][1] / 2 - (Math.abs(perfectAngle - clusterAngle)));
  1150.  
  1151. clusterAllFood[i][3] = clusterAngle;
  1152.  
  1153. drawPoint(clusterAllFood[i][0], clusterAllFood[i][1], 1, "");
  1154. //console.log("After: " + clusterAllFood[i][2]);
  1155. }
  1156.  
  1157. var bestFoodI = 0;
  1158. var bestFood = clusterAllFood[0][2];
  1159. for (var i = 1; i < clusterAllFood.length; i++) {
  1160. if (bestFood < clusterAllFood[i][2]) {
  1161. bestFood = clusterAllFood[i][2];
  1162. bestFoodI = i;
  1163. }
  1164. }
  1165.  
  1166. //console.log("Best Value: " + clusterAllFood[bestFoodI][2]);
  1167.  
  1168. var distance = this.computeDistance(player[k].x, player[k].y, clusterAllFood[bestFoodI][0], clusterAllFood[bestFoodI][1]);
  1169.  
  1170. var shiftedAngle = this.shiftAngle(obstacleAngles, this.getAngle(clusterAllFood[bestFoodI][0], clusterAllFood[bestFoodI][1], player[k].x, player[k].y), [0, 360]);
  1171.  
  1172. var destination = this.followAngle(shiftedAngle, player[k].x, player[k].y, distance);
  1173.  
  1174. destinationChoices = destination;
  1175. //tempMoveX = destination[0];
  1176. //tempMoveY = destination[1];
  1177. drawLine(player[k].x, player[k].y, destination[0], destination[1], 1);
  1178. } else {
  1179. //If there are no enemies around and no food to eat.
  1180. destinationChoices = [tempMoveX, tempMoveY];
  1181. }
  1182.  
  1183. drawPoint(tempPoint[0], tempPoint[1], tempPoint[2], "");
  1184. //drawPoint(tempPoint[0], tempPoint[1], tempPoint[2], "" + Math.floor(this.computeDistance(tempPoint[0], tempPoint[1], I, J)));
  1185. //drawLine(tempPoint[0], tempPoint[1], player[0].x, player[0].y, 6);
  1186. //console.log("Slope: " + slope(tempPoint[0], tempPoint[1], player[0].x, player[0].y) + " Angle: " + getAngle(tempPoint[0], tempPoint[1], player[0].x, player[0].y) + " Side: " + (getAngle(tempPoint[0], tempPoint[1], player[0].x, player[0].y) - 90).mod(360));
  1187. tempPoint[2] = 1;
  1188.  
  1189. //console.log("Done working on blob: " + i);
  1190. }
  1191.  
  1192. //TODO: Find where to go based on destinationChoices.
  1193. /*var dangerFound = false;
  1194. for (var i = 0; i < destinationChoices.length; i++) {
  1195. if (destinationChoices[i][2]) {
  1196. dangerFound = true;
  1197. break;
  1198. }
  1199. }
  1200. destinationChoices.sort(function(a, b){return b[1] - a[1]});
  1201. if (dangerFound) {
  1202. for (var i = 0; i < destinationChoices.length; i++) {
  1203. if (destinationChoices[i][2]) {
  1204. tempMoveX = destinationChoices[i][0][0];
  1205. tempMoveY = destinationChoices[i][0][1];
  1206. break;
  1207. }
  1208. }
  1209. } else {
  1210. tempMoveX = destinationChoices.peek()[0][0];
  1211. tempMoveY = destinationChoices.peek()[0][1];
  1212. //console.log("Done " + tempMoveX + ", " + tempMoveY);
  1213. }*/
  1214. }
  1215. //console.log("MOVING RIGHT NOW!");
  1216.  
  1217. //console.log("______Never lied ever in my life.");
  1218.  
  1219. if (this.master) {
  1220. this.masterLocation = destinationChoices;
  1221. this.masterId = player[0].id;
  1222. if (Date.now() - this.lastMasterUpdate > 5000) {
  1223. var self = this;
  1224. var query = new Parse.Query(this.MasterLocation);
  1225. query.equalTo("server", getServer());
  1226. query.first({
  1227. success: function(object) {
  1228. console.log("Done query");
  1229. if (typeof object != 'undefined') {
  1230. object.set("location", destinationChoices);
  1231. object.set("cellId", player[0].id);
  1232. object.set("server", getServer());
  1233. console.log("New location saved! " + object.get("location") + " ID: " + player[0].id + " Server: " + getServer());
  1234. object.save();
  1235. } else {
  1236. console.log("We have a problem!");
  1237. var ml = new self.MasterLocation();
  1238. ml.set("location", destinationChoices);
  1239. ml.set("cellId", player[0].id);
  1240. ml.set("server", getServer());
  1241. console.log("New location saved! " + ml.get("location") + " ID: " + player[0].id + " Server: " + getServer());
  1242. ml.save();
  1243. }
  1244. },
  1245. error: function(error) {
  1246. console.log("Error: " + error.code + " " + error.message);
  1247. }
  1248. });
  1249. this.lastMasterUpdate = Date.now();
  1250. }
  1251. }
  1252.  
  1253. return destinationChoices;
  1254. }
  1255. };
  1256. };
  1257. window.botList.push(new AposBot());
  1258.  
  1259. window.updateBotList(); //This function might not exist yet.