Nolans Mod

Agario Mod ITS BACK

  1. // ==UserScript==
  2. // @name Nolans Mod
  3. // @version 0.7
  4. // @description Agario Mod ITS BACK
  5. // @author Nolan
  6. // @match http://agar.io
  7. // @match https://agar.io
  8. // @match http://agarserv.com
  9. // @match https://agarserv.com
  10. // @changes 0.1 - Stats now detects viruses being eaten
  11. // 0.2 - Upgraded zoom functions
  12. // 0.3 - Some zoom bug fixes
  13. // 0.4 - protocol breakage fix
  14. // 0.5 - fixed my fuckup
  15. // 0.6 - Click-to-lock added
  16. // 0.7 - Fixed It So I Can Not Be Sued
  17.  
  18.  
  19.  
  20. // @require https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js
  21. // @grant GM_setValue
  22. // @grant GM_getValue
  23. // @grant GM_xmlhttpRequest
  24.  
  25. // @namespace
  26. // ==/UserScript==
  27. var _version_ = GM_info.script.version;
  28.  
  29. var debugMonkeyReleaseMessage = "<h3>Protocol Changes and Burnout</h3><p>" +
  30. "Hey guys. I've patched the no-movement issue. Sorry for the inconvenience and for the delay in making a fix. <br><br>" +
  31. "I've been a bit burnt out on Agar.io so I've been taking it easy." +
  32. "You guys are the real MVPs.<br>" +
  33. "<img src='http://i.imgur.com/p4zv6vx.jpg'><br><br>-A1ien";
  34.  
  35. //if (window.top != window.self) //-- Don't run on frames or iframes
  36. // return;
  37. //https://cdn.rawgit.com/pockata/blackbird-js/1e4c9812f8e6266bf71a25e91cb12a553e7756f4/blackbird.js
  38. //https://raw.githubusercontent.com/pockata/blackbird-js/cc2dc268b89e6345fa99ca6109ddaa6c22143ad0/blackbird.css
  39. $.getScript("https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.4.1/canvas.min.js");
  40. $.getScript("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js");
  41.  
  42. unsafeWindow.connect2 = unsafeWindow.connect;
  43. jQuery("#canvas").remove();
  44. jQuery("#connecting").after('<canvas id="canvas" width="800" height="600"></canvas>');
  45.  
  46. (function(d, f) {
  47.  
  48.  
  49. // Options that will always be reset on reload
  50. var zoomFactor = 10;
  51. var isGrazing = false;
  52. var serverIP = "";
  53. var showVisualCues = true;
  54.  
  55. // Game State & Info
  56. var highScore = 0;
  57. var timeSpawned = null;
  58. var grazzerTargetResetRequest = false;
  59. var nearestVirusID;
  60. var suspendMouseUpdates = false;
  61. var grazingTargetFixation = false;
  62. var selectedBlobID = null;
  63.  
  64. // Constants
  65. var Huge = 2.66,
  66. Large = 1.25,
  67. Small = 0.7,
  68. Tiny = 0.375;
  69. var Huge_Color = "#FF3C3C",
  70. Large_Color = "#FFBF3D",
  71. Same_Color = "#FFFF00",
  72. Small_Color = "#00AA00",
  73. Tiny_Color = "#CC66FF",
  74. myColor ="#3371FF",
  75. virusColor ="#666666";
  76. var lastMouseCoords = { x: 0, y: 0 };
  77. var ghostBlobs = [];
  78.  
  79.  
  80. var miniMapCtx=jQuery('<canvas id="mini-map" width="175" height="175" style="border:2px solid #999;text-align:center;position:fixed;bottom:5px;right:5px;"></canvas>')
  81. .appendTo(jQuery('body'))
  82. .get(0)
  83. .getContext("2d");
  84.  
  85. // cobbler is the object that holds all user options. Options that should never be persisted can be defined here.
  86. // If an option setting should be remembered it can
  87. var cobbler = {
  88. set grazingMode(val) {isGrazing = val;},
  89. get grazingMode() {return isGrazing;},
  90. minimapScaleCurrentValue : 1,
  91. "displayMiniMap" : true,
  92.  
  93. };
  94. // utility function to simplify creation of options whose state should be persisted to disk
  95. function simpleSavedSettings(optionsObject){
  96. _.forEach(optionsObject, function(defaultValue, settingName){
  97. var backingVar = '_' + settingName;
  98. cobbler[backingVar] = GM_getValue(settingName, defaultValue),
  99. Object.defineProperty(cobbler, settingName, {
  100. get: function() { return this[backingVar];},
  101. set: function(val) { this[backingVar] = val; GM_setValue(settingName, val); }
  102. });
  103. });
  104. }
  105. // defines all options that should be persisted along with their default values.
  106. function makeCobbler(){
  107. var optionsAndDefaults = {
  108. "isLiteBrite" : true,
  109. "sfxVol" : 0.5,
  110. "bgmVol" : 0.5,
  111. "drawTail" : false,
  112. "splitGuide" : true,
  113. "rainbowPellets" : true,
  114. "debugLevel" : 1,
  115. "imgurSkins" : true,
  116. "amExtendedSkins" : true,
  117. "amConnectSkins" : true,
  118. "namesUnderBlobs" : false,
  119. "grazerMultiBlob2" : false,
  120. "grazerHybridSwitch": false,
  121. "grazerHybridSwitchMass" : 300,
  122. "gridLines" : true,
  123. "autoRespawn" : false,
  124. "visualizeGrazing" : true,
  125. "msDelayBetweenShots" : 100,
  126. "miniMapScale" : false,
  127. "miniMapScaleValue" : 64,
  128. "enableBlobLock" : false,
  129. 'nextOnBlobLock' : false,
  130. 'rightClickFires' : false,
  131. 'showZcStats' : true,
  132. };
  133. simpleSavedSettings(optionsAndDefaults);
  134. }
  135. makeCobbler();
  136.  
  137. window.cobbler = cobbler;
  138.  
  139. // ====================== Property & Var Name Restoration =======================================================
  140. var zeach = {
  141. get connect() {return Aa;}, // Connect
  142. get ctx() {return g;}, // g_context
  143. get webSocket() {return r;}, // g_socket
  144. get myIDs() {return K;}, // g_playerCellIds
  145. get myPoints() {return m;}, // g_playerCells
  146. get allNodes() {return D;}, // g_cellsById
  147. get allItems() {return v;}, // g_cells
  148. get mouseX2() {return fa;}, // g_moveX
  149. get mouseY2() {return ga;}, // g_moveY
  150. get mapLeft() {return oa;}, // g_minX
  151. get mapTop() {return pa;}, // g_minY
  152. get mapRight() {return qa;}, // g_maxX
  153. get mapBottom() {return ra;}, // g_maxY
  154. get isShowSkins() {return fb;}, // g_showSkins
  155. // "g_showNames": "va",
  156. get isNightMode() {return sa;}, // ??
  157. get isShowMass() {return gb;}, // ??
  158. get gameMode() {return O;}, // g_mode
  159. get fireFunction() {return G;}, // SendCmd
  160. get isColors() {return Ka;}, // g_noColors
  161. get defaultSkins() {return jb;}, // g_skinNamesA
  162. get imgCache() {return T;}, // ???
  163. get textFunc() {return ua;}, // CachedCanvas
  164. get textBlobs() {return Bb;}, // g_skinNamesB
  165. get hasNickname() {return va;}, // g_showNames
  166. get scale() {return k;}, //
  167. // Classes
  168. get CachedCanvas() {return ua;}, // CachedCanvas
  169. get Cell() {return aa;}, //
  170. // These never existed before but are useful
  171. get mapWidth() {return ~~(Math.abs(zeach.mapLeft) + zeach.mapRight);},
  172. get mapHeight() {return ~~(Math.abs(zeach.mapTop) + zeach.mapBottom);},
  173. };
  174.  
  175.  
  176. function restoreCanvasElementObj(objPrototype){
  177. var canvasElementPropMap = {
  178. 'setValue' : 'C', //
  179. 'render' : 'L', //
  180. 'setScale' : 'ea', //
  181. 'setSize' : 'M', //
  182. };
  183. _.forEach(canvasElementPropMap, function(newPropName,oldPropName){
  184. Object.defineProperty(objPrototype, oldPropName, {
  185. get: function() { return this[newPropName];},
  186. set: function(val) { this[newPropName] = val; }
  187. });
  188. });
  189. }
  190.  
  191. // Cell
  192. function restorePointObj(objPrototype){
  193. var pointPropMap = {
  194. 'isVirus' : 'h', //
  195. 'nx' : 'J', //
  196. 'ny' : 'K', //
  197. 'setName' : 'B', //
  198. 'nSize' : 'q', //
  199. 'ox' : 's', //
  200. 'oy' : 't', //
  201. 'oSize' : 'r', //
  202. 'destroy' : 'X', //
  203. 'maxNameSize' : 'l', //
  204. 'massText' : 'O', //
  205. 'nameCache' : 'o', //
  206. 'isAgitated' : 'n'
  207. };
  208. _.forEach(pointPropMap, function(newPropName,oldPropName){
  209. Object.defineProperty(objPrototype, oldPropName, {
  210. get: function() { return this[newPropName];},
  211. set: function(val) { this[newPropName] = val; }
  212. });
  213. });
  214. }
  215.  
  216. // ====================== Utility code ==================================================================
  217. function isFood(blob){
  218. return (blob.nSize < 15);
  219. }
  220. function getSelectedBlob(){
  221. if(!_.contains(zeach.myIDs, selectedBlobID)){
  222. selectedBlobID = zeach.myPoints[0].id;
  223. //console.log("Had to select new blob. Its id is " + selectedBlobID);
  224. }
  225. return zeach.allNodes[selectedBlobID];
  226. }
  227.  
  228. function isPlayerAlive(){
  229. return !!zeach.myPoints.length;
  230. }
  231.  
  232. function sendMouseUpdate(ws, mouseX2, mouseY2, blob) {
  233. lastMouseCoords = {x: mouseX2, y: mouseY2};
  234.  
  235. if (ws && ws.readyState == ws.OPEN) {
  236. var blobId = blob ? blob.id : 0;
  237. var z0 = new ArrayBuffer(13);
  238. var z1 = new DataView(z0);
  239. z1.setUint8(0, 16);
  240. z1.setInt32(1, mouseX2, true);
  241. z1.setInt32(5, mouseY2, true);
  242. z1.setUint32(9, blobId, true);
  243. ws.send(z0);
  244. }
  245. }
  246.  
  247. function getMass(x){
  248. return x*x/100;
  249. }
  250.  
  251. function lineDistance( point1, point2 ){
  252. var xs = point2.nx - point1.nx;
  253. var ys = point2.ny - point1.ny;
  254.  
  255. return Math.sqrt( xs * xs + ys * ys );
  256. }
  257.  
  258. function getVirusShotsNeededForSplit(cellSize){
  259. return ~~((149-cellSize)/7);
  260. }
  261.  
  262. function calcTTR(element){
  263.  
  264. var totalMass = _.sum(_.pluck(zeach.myPoints, "nSize").map(getMass));
  265. return ~~((((totalMass*0.02)*1000)+30000) / 1000) - ~~((Date.now() - element.splitTime) / 1000);
  266. }
  267.  
  268. function getBlobShotsAvailable(blob) {
  269. return ~~(Math.max(0, (getMass(blob.nSize)-(35-18))/18));
  270. }
  271.  
  272. function distanceFromCellZero(blob) {
  273. return isPlayerAlive() ? lineDistance(blob, getSelectedBlob()) :
  274. Math.sqrt((zeach.mapRight - zeach.mapLeft) * (zeach.mapRight - zeach.mapLeft) + (zeach.mapBottom - zeach.mapTop) * (zeach.mapBottom - zeach.mapTop));
  275. }
  276.  
  277. function getViewport(interpolated) {
  278. var x = _.sum(_.pluck(zeach.myPoints, interpolated ? "x" : "nx")) / zeach.myPoints.length;
  279. var y = _.sum(_.pluck(zeach.myPoints, interpolated ? "y" : "ny")) / zeach.myPoints.length;
  280. var totalRadius = _.sum(_.pluck(zeach.myPoints, interpolated ? "size" : "nSize"));
  281. var zoomFactor = Math.pow(Math.min(64.0 / totalRadius, 1), 0.4);
  282. var deltaX = 1024 / zoomFactor;
  283. var deltaY = 600 / zoomFactor;
  284. return { x: x, y: y, dx: deltaX, dy: deltaY };
  285. }
  286.  
  287. function getMouseCoordsAsPseudoBlob(){
  288. return {
  289. "x": zeach.mouseX2,
  290. "y": zeach.mouseY2,
  291. "nx": zeach.mouseX2,
  292. "ny": zeach.mouseY2,
  293. };
  294. }
  295.  
  296. // ====================== Grazing code ==================================================================
  297.  
  298. function checkCollision(myBlob, targetBlob, potential){
  299. // Calculate distance to target
  300. var dtt = lineDistance(myBlob, targetBlob);
  301. // Slope and normal slope
  302. var sl = (targetBlob.ny-myBlob.ny)/(targetBlob.nx-myBlob.nx);
  303. var ns = -1/sl;
  304. // y-int of ptt
  305. var yint1 = myBlob.ny - myBlob.nx*sl;
  306. if(!(lineDistance(myBlob, potential) < dtt)){
  307. // get second y-int
  308. var yint2 = potential.ny - potential.nx * ns;
  309. var interx = (yint2-yint1)/(sl-ns);
  310. var intery = sl*interx + yint1;
  311. var pseudoblob = {};
  312. pseudoblob.nx = interx;
  313. pseudoblob.ny = intery;
  314. if (((targetBlob.nx < myBlob.nx && targetBlob.nx < interx && interx < myBlob.nx) ||
  315. (targetBlob.nx > myBlob.nx && targetBlob.nx > interx && interx > myBlob.nx)) &&
  316. ((targetBlob.ny < myBlob.ny && targetBlob.ny < intery && intery < myBlob.ny) ||
  317. (targetBlob.ny > myBlob.ny && targetBlob.ny > intery && intery > myBlob.ny))){
  318. if(lineDistance(potential, pseudoblob) < potential.size+100){
  319. return true;
  320. }
  321. }
  322. }
  323. return false;
  324. }
  325.  
  326. function isSafeTarget(myBlob, targetBlob, threats){
  327. var isSafe = true;
  328. // check target against each enemy to make sure no collision is possible
  329. threats.forEach(function (threat){
  330. if(isSafe) {
  331. if(threat.isVirus) {
  332. //todo once we are big enough, our center might still be far enough
  333. // away that it doesn't cross virus but we still pop
  334. if(checkCollision(myBlob, targetBlob, threat) ) {
  335. isSafe = false;
  336. }
  337. }
  338. else {
  339. if ( checkCollision(myBlob, targetBlob, threat) || lineDistance(threat, targetBlob) <= threat.size + 200) {
  340. isSafe = false;
  341. }
  342. }
  343. }
  344. });
  345. return isSafe;
  346. }
  347.  
  348. // All blobs that aren't mine
  349. function getOtherBlobs(){
  350. return _.omit(zeach.allNodes, zeach.myIDs);
  351. }
  352.  
  353. // Gets any item which is a threat including bigger players and viruses
  354. function getThreats(blobArray, myMass) {
  355. // start by omitting all my IDs
  356. // then look for viruses smaller than us and blobs substantially bigger than us
  357. return _.filter(getOtherBlobs(), function(possibleThreat){
  358. var possibleThreatMass = getMass(possibleThreat.size);
  359.  
  360. if(possibleThreat.isVirus) {
  361. // Viruses are only a threat if we are bigger than them
  362. return myMass >= possibleThreatMass;
  363. }
  364. // other blobs are only a threat if they cross the 'Large' threshhold
  365. return possibleThreatMass > myMass * Large;
  366. });
  367. }
  368.  
  369. var throttledResetGrazingTargetId = null;
  370.  
  371. function doGrazing() {
  372. var i;
  373. if(!isPlayerAlive()) {
  374. //isGrazing = false;
  375. return;
  376. }
  377.  
  378. if(null === throttledResetGrazingTargetId){
  379. throttledResetGrazingTargetId = _.throttle(function (){
  380. grazzerTargetResetRequest = 'all';
  381. //console.log(~~(Date.now()/1000));
  382. }, 200);
  383. }
  384.  
  385.  
  386. if (grazzerTargetResetRequest == 'all') {
  387. grazzerTargetResetRequest = false;
  388.  
  389. for(i = 0; i < zeach.myPoints.length; i++) {
  390. zeach.myPoints[i].grazingTargetID = false;
  391. }
  392. } else if (grazzerTargetResetRequest == 'current') {
  393. var pseudoBlob = getMouseCoordsAsPseudoBlob();
  394.  
  395. pseudoBlob.size = getSelectedBlob().size;
  396. //pseudoBlob.scoreboard = scoreboard;
  397. var newTarget = findFoodToEat_old(pseudoBlob,zeach.allItems);
  398. if(-1 == newTarget){
  399. isGrazing = false;
  400. return;
  401. }
  402. getSelectedBlob().grazingTargetID = newTarget.id;
  403. }
  404.  
  405. // with target fixation on, target remains until it's eaten by someone or
  406. // otherwise disappears. With it off target is constantly recalculated
  407. // at the expense of CPU
  408. if(!grazingTargetFixation) {
  409. throttledResetGrazingTargetId();
  410. }
  411.  
  412. var target;
  413.  
  414.  
  415. var targets = findFoodToEat(!cobbler.grazerMultiBlob2);
  416. for(i = 0; i < zeach.myPoints.length; i++) {
  417. var point = zeach.myPoints[i];
  418.  
  419. if (!cobbler.grazerMultiBlob2 && point.id != getSelectedBlob().id) {
  420. continue;
  421. }
  422.  
  423. point.grazingMode = isGrazing;
  424. if(cobbler.grazerHybridSwitch) {
  425. var mass = getMass(point.nSize);
  426. // switch over to new grazer once we pass the threshhold
  427. if(1 === point.grazingMode && mass > cobbler.grazerHybridSwitchMass){
  428. point.grazingMode = 2; // We gained enough much mass. Use new grazer.
  429. }else if(2 === point.grazingMode && mass < cobbler.grazerHybridSwitchMass ){
  430. point.grazingMode = 1; // We lost too much mass. Use old grazer.
  431. }
  432. }
  433. switch(point.grazingMode) {
  434. case 1: {
  435.  
  436. if(!zeach.allNodes.hasOwnProperty(point.grazingTargetID)) {
  437. target = findFoodToEat_old(point, zeach.allItems);
  438. if(-1 == target){
  439. point.grazingMode = 2;
  440. return;
  441. }
  442. point.grazingTargetID = target.id;
  443. } else {
  444. target = zeach.allNodes[point.grazingTargetID];
  445. }
  446. if (!cobbler.grazerMultiBlob2) {
  447. sendMouseUpdate(zeach.webSocket, target.x + Math.random(), target.y + Math.random());
  448. } else {
  449. sendMouseUpdate(zeach.webSocket, target.x + Math.random(), target.y + Math.random(), point);
  450. }
  451.  
  452. break;
  453. }
  454. case 2: {
  455. if (!cobbler.grazerMultiBlob2) {
  456. target = _.max(targets, "v");
  457. sendMouseUpdate(zeach.webSocket, target.x + Math.random(), target.y + Math.random());
  458. } else {
  459. target = targets[point.id];
  460. sendMouseUpdate(zeach.webSocket, target.x + Math.random(), target.y + Math.random(), point);
  461. }
  462.  
  463. break;
  464. }
  465. }
  466. }
  467.  
  468. }
  469.  
  470. function dasMouseSpeedFunction(id, cx, cy, radius, nx, ny) {
  471. this.cx = cx; this.cy = cy; this.radius = radius; this.nx = nx; this.ny = ny;
  472. this.value = function(x, y) {
  473. x -= this.cx; y -= this.cy;
  474. var lensq = x*x + y*y;
  475. var len = Math.sqrt(lensq);
  476.  
  477. var val = x * this.nx + y * this.ny;
  478. if (len > this.radius) {
  479. return {
  480. id : id,
  481. v: val / len,
  482. dx: y * (this.nx * y - this.ny * x) / (lensq * len),
  483. dy: x * (this.ny * x - this.nx * y) / (lensq * len),
  484. };
  485. } else {
  486. return {id: id, v: val / this.radius, dx: this.nx, dy: this.ny};
  487. }
  488. };
  489. }
  490.  
  491. function dasBorderFunction(l, t, r, b, w) {
  492. this.l = l;
  493. this.t = t;
  494. this.r = r;
  495. this.b = b;
  496. this.w = w;
  497. this.value = function(x, y) {
  498. var v = 0, dx = 0, dy = 0;
  499. if (x < this.l) {
  500. v += this.l - x;
  501. dx = -this.w;
  502. } else if (x > this.r) {
  503. v += x - this.r;
  504. dx = this.w;
  505. }
  506.  
  507. if (y < this.t) {
  508. v += this.t - y;
  509. dy = -this.w;
  510. } else if (y > this.b) {
  511. v += y - this.b;
  512. dy = this.w;
  513. }
  514.  
  515. return {v: v * this.w, dx: dx, dy: dy};
  516. };
  517. }
  518.  
  519. function dasSumFunction(sumfuncs) {
  520. this.sumfuncs = sumfuncs;
  521. this.value = function(x, y) {
  522. return sumfuncs.map(function(func) {
  523. return func.value(x, y);
  524. }).reduce(function (acc, val) {
  525. acc.v += val.v; acc.dx += val.dx; acc.dy += val.dy;
  526. return acc;
  527. });
  528. };
  529. }
  530.  
  531. function gradient_ascend(func, step, iters, id, x, y) {
  532. var max_step = step;
  533.  
  534. var last = func.value(x, y);
  535.  
  536. while(iters > 0) {
  537. iters -= 1;
  538.  
  539. x += last.dx * step;
  540. y += last.dy * step;
  541. var tmp = func.value(x, y);
  542. if (tmp.v < last.v) {
  543. step /= 2;
  544. } else {
  545. step = Math.min(2 * step, max_step);
  546. }
  547. //console.log([x, y, tmp[0], step]);
  548.  
  549. last.v = tmp.v;
  550. last.dx = (last.dx + tmp.dx)/2.0;
  551. last.dy = (last.dy + tmp.dy)/2.0;
  552. }
  553.  
  554. return {id: id, x: x, y: y, v: last.v};
  555. }
  556.  
  557. function augmentBlobArray(blobArray) {
  558.  
  559. blobArray = blobArray.slice();
  560.  
  561. var curTimestamp = Date.now();
  562.  
  563. // Outdated blob id set
  564. var ghostSet = [];
  565.  
  566. blobArray.forEach(function (element) {
  567. ghostSet[element.id] = true;
  568. element.lastTimestamp = curTimestamp;
  569. });
  570.  
  571. var viewport = getViewport(false);
  572.  
  573. ghostBlobs = _.filter(ghostBlobs, function (element) {
  574. return !ghostSet[element.id] && // a fresher blob with the same id doesn't exist in blobArray already
  575. (curTimestamp - element.lastTimestamp < 10000) && // last seen no more than 10 seconds ago
  576. (
  577. (Math.abs(viewport.x - element.nx) > (viewport.dx + element.nSize) * 0.9) ||
  578. (Math.abs(viewport.y - element.ny) > (viewport.dy + element.nSize) * 0.9)
  579. ); // outside of firmly visible area, otherwise there's no need to remember it
  580. });
  581.  
  582. ghostBlobs.forEach(function (element) {
  583. blobArray.push(element);
  584. });
  585.  
  586. ghostBlobs = blobArray;
  587.  
  588. return blobArray;
  589. }
  590. function findFoodToEat(useGradient) {
  591. blobArray = augmentBlobArray(zeach.allItems);
  592.  
  593. zeach.myPoints.forEach(function(cell) {
  594. cell.gr_is_mine = true;
  595. });
  596.  
  597. var accs = zeach.myPoints.map(function (cell) {
  598.  
  599.  
  600. var per_food = [], per_threat = [];
  601. var acc = {
  602. id : cell.id,
  603. fx: 0,
  604. fy: 0,
  605. x: cell.nx,
  606. y: cell.ny,
  607. size : cell.nSize,
  608. per_food: per_food,
  609. per_threat: per_threat,
  610. cumulatives: [ { x: 0, y: 0}, { x: 0, y: 0} ],
  611. };
  612.  
  613. if (!useGradient && cell.grazingMode != 2) {
  614. return acc;
  615. }
  616.  
  617. var totalMass = _.sum(_.pluck(zeach.myPoints, "nSize").map(getMass));
  618.  
  619. // Avoid walls too
  620. var wallArray = [];
  621. wallArray.push({id: -2, nx: cell.nx, ny: zeach.mapTop - 1, nSize: cell.nSize * 30});
  622. wallArray.push({id: -3, nx: cell.nx, ny: zeach.mapBottom + 1, nSize: cell.nSize * 30});
  623. wallArray.push({id: -4, ny: cell.ny, nx: zeach.mapLeft - 1, nSize: cell.nSize * 30});
  624. wallArray.push({id: -5, ny: cell.ny, nx: zeach.mapRight + 1, nSize: cell.nSize * 30});
  625. wallArray.forEach(function(el) {
  626. // Calculate repulsion vector
  627. var vec = { id: el.id, gr_type: true, x: cell.nx - el.nx, y: cell.ny - el.ny };
  628. var dist = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
  629.  
  630. // Normalize it to unit length
  631. vec.x /= dist;
  632. vec.y /= dist;
  633.  
  634. // Walls have pseudo-size to generate repulsion, but we can move farther.
  635. dist += cell.nSize / 2.0;
  636.  
  637. dist = Math.max(dist, 0.01);
  638.  
  639. // Walls. Hate them muchly.
  640. dist /= 10;
  641.  
  642. // The more we're split and the more we're to lose, the more we should be afraid.
  643. dist /= cell.nSize * Math.sqrt(zeach.myPoints.length);
  644.  
  645. // The farther they're from us the less repulsive/attractive they are.
  646. vec.x /= dist;
  647. vec.y /= dist;
  648.  
  649. if(!isFinite(vec.x) || !isFinite(vec.y)) {
  650. return;
  651. }
  652.  
  653. // Save element-produced force for visualization
  654. per_threat.push(vec);
  655.  
  656. // Sum forces from all threats
  657. acc.fx += vec.x;
  658. acc.fy += vec.y;
  659. });
  660.  
  661. blobArray.forEach(function(el) {
  662. var vec = { id: el.id, x: cell.nx - el.nx, y: cell.ny - el.ny };
  663.  
  664. if(el.gr_is_mine) {
  665. return; //our cell, ignore
  666. } else if( !el.isVirus && (getMass(el.nSize) * 4 <= getMass(cell.nSize) * 3)) {
  667. //if(!el.isVirus && (getMass(el.nSize) <= 9)) {
  668. //vec.gr_type = null; //edible
  669. } else if (!el.isVirus && (getMass(el.nSize) * 3 < (getMass(cell.nSize) * 4))) {
  670. return; //not edible ignorable
  671. // TODO: shouldn't really be so clear-cut. Must generate minor repulsion/attraction depending on size.
  672. } else {
  673. vec.gr_type = true; //threat
  674. }
  675.  
  676. // Calculate repulsion vector
  677. var dist = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
  678.  
  679. // Normalize it to unit length
  680. vec.x /= dist;
  681. vec.y /= dist;
  682.  
  683. if(el.nSize > cell.nSize) {
  684. if(el.isVirus) {
  685. // Viruses are only a threat if they're smaller than us
  686. return;
  687. }
  688.  
  689. // Distance till consuming
  690. dist -= el.nSize;
  691. dist += cell.nSize / 3.0;
  692. dist -= 11;
  693.  
  694. dist = Math.max(dist, 0.01);
  695.  
  696. // Prioritize targets by size
  697. if(!vec.gr_type) {
  698. //Non-threat
  699. dist /= el.nSize;
  700. } else {
  701. var ratio = getMass(el.nSize) / getMass(cell.nSize);
  702. // Cells that 1 to 8 times bigger are the most dangerous.
  703. // Prioritize them by a truncated parabola up to 6 times.
  704.  
  705. // when we are fractured into small parts, we might underestimate
  706. // how cells a lot bigger than us can be interested in us as a conglomerate of mass.
  707. // So calculate threat index for our total mass too.
  708. var ratio2 = getMass(el.nSize) / totalMass;
  709. if(ratio2 < 4.5 && ratio > 4.5) {
  710. ratio2 = 4.5;
  711. }
  712.  
  713. ratio = Math.min(5, Math.max(0, - (ratio - 1) * (ratio - 8))) + 1;
  714. ratio2 = Math.min(5, Math.max(0, - (ratio2 - 1) * (ratio2 - 8))) + 1;
  715. ratio = Math.max(ratio, ratio2);
  716.  
  717. // The more we're split and the more we're to lose, the more we should be afraid.
  718. dist /= ratio * cell.nSize * Math.sqrt(zeach.myPoints.length);
  719. }
  720.  
  721. } else {
  722. // Distance till consuming
  723. dist += el.nSize * 1 / 3;
  724. dist -= cell.nSize;
  725. dist -= 11;
  726.  
  727. if(el.isVirus) {
  728. if(zeach.myPoints.length >= 16 ) {
  729. // Can't split anymore so viruses are actually a good food!
  730. delete vec.gr_type; //vec.gr_type = null;
  731. } else {
  732. // Hate them a bit less than same-sized blobs.
  733. dist *= 2;
  734. }
  735. }
  736.  
  737. dist = Math.max(dist, 0.01);
  738.  
  739. // Prioritize targets by size
  740. dist /= el.nSize;
  741. }
  742.  
  743. if(!vec.gr_type) {
  744. //Not a threat. Make it attractive.
  745. dist = -dist;
  746. }
  747.  
  748. // The farther they're from us the less repulsive/attractive they are.
  749. vec.x /= dist;
  750. vec.y /= dist;
  751.  
  752. if(!isFinite(vec.x) || !isFinite(vec.y)) {
  753. return;
  754. }
  755.  
  756. // Save element-produced force for visualization
  757. (vec.gr_type ? per_threat : per_food).push(vec);
  758.  
  759. // Sum forces per target type
  760. var cumul = acc.cumulatives[!vec.gr_type ? 1 : 0];
  761. cumul.x += vec.x;
  762. cumul.y += vec.y;
  763. });
  764.  
  765. // Sum forces from all sources
  766. acc.fx += _.sum(_.pluck(acc.cumulatives, "x"));
  767. acc.fy += _.sum(_.pluck(acc.cumulatives, "y"));
  768.  
  769. // Save resulting info for visualization
  770. cell.grazeInfo = acc;
  771. return acc;
  772. });
  773.  
  774. if (useGradient) {
  775. var funcs = accs.map(function(acc) {
  776. return new dasMouseSpeedFunction(acc.id, acc.x, acc.y, 200, acc.fx, acc.fy);
  777. });
  778.  
  779. // Pick gradient ascent step size for better convergence
  780. // so that coord jumps don't exceed ~50 units
  781. var step = _.sum(accs.map(function(acc) {
  782. return Math.sqrt(acc.fx * acc.fx + acc.fy * acc.fy);
  783. }));
  784. step = 50 / step;
  785. if(!isFinite(step)) {
  786. step = 50;
  787. }
  788.  
  789. var viewport = getViewport(false);
  790. funcs.push(
  791. new dasBorderFunction(
  792. viewport.x - viewport.dx,
  793. viewport.y - viewport.dy,
  794. viewport.x + viewport.dx,
  795. viewport.y + viewport.dy,
  796. -1000
  797. )
  798. );
  799.  
  800. var func = new dasSumFunction(funcs);
  801.  
  802. var results = accs.map(function(acc) {
  803. return gradient_ascend(func, step, 100, acc.id, acc.x, acc.y);
  804. });
  805. } else {
  806. results = accs.map(function(acc) {
  807. var norm = Math.sqrt(acc.fx * acc.fx + acc.fy * acc.fy);
  808. return {id: acc.id, x: acc.x + 200 * acc.fx / norm, y: acc.y + 200 * acc.fy / norm };
  809. });
  810. }
  811.  
  812.  
  813. var reply = {};
  814. for (var i = 0; i < results.length; i++) {
  815. reply[results[i].id] = {id : -5, x : results[i].x, y : results[i].y, v : results[i].v};
  816. }
  817.  
  818. return reply;
  819. }
  820.  
  821.  
  822. function findFoodToEat_old(cell, blobArray){
  823. var edibles = [];
  824. var densityResults = [];
  825. var threats = getThreats(blobArray, getMass(cell.size));
  826. blobArray.forEach(function (element){
  827. var distance = lineDistance(cell, element);
  828. if (!element.isSafeTarget) {
  829. element.isSafeTarget = {};
  830. }
  831. element.isSafeTarget[cell.id] = null;
  832. if( getMass(element.size) <= (getMass(cell.size) * 0.4) && !element.isVirus){
  833. if(isSafeTarget(cell, element, threats)){
  834. edibles.push({"distance":distance, "id":element.id});
  835. element.isSafeTarget[cell.id] = true;
  836. } else {
  837. element.isSafeTarget[cell.id] = false;
  838. }
  839. }
  840. });
  841. edibles = edibles.sort(function(x,y){return x.distance<y.distance?-1:1;});
  842. edibles.forEach(function (element){
  843. var density = calcFoodDensity(cell, zeach.allNodes[element.id], blobArray)/(element.distance*2);
  844. densityResults.push({"density":density, "id":element.id});
  845. });
  846. if(0 === densityResults.length){
  847. //console.log("No target found");
  848. return avoidThreats(threats, cell);
  849. return -1;
  850. }
  851. var target = densityResults.sort(function(x,y){return x.density>y.density?-1:1;});
  852. //console.log("Choosing blob (" + target[0].id + ") with density of : "+ target[0].isVirusensity);
  853. return zeach.allNodes[target[0].id];
  854. }
  855.  
  856. function avoidThreats(threats, cell){
  857. // Avoid walls too
  858. threats.push({x: cell.x, y: zeach.mapTop - 1, size: 1});
  859. threats.push({x: cell.x, y: zeach.mapBottom + 1, size: 1});
  860. threats.push({y: cell.y, x: zeach.mapLeft - 1, size: 1});
  861. threats.push({y: cell.y, x: zeach.mapRight + 1, size: 1});
  862.  
  863. var direction = threats.reduce(function(acc, el) {
  864. // Calculate repulsion vector
  865. var vec = { x: cell.x - el.x, y: cell.y - el.y };
  866. var dist = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
  867.  
  868. // Normalize it to unit length
  869. vec.x /= dist;
  870. vec.y /= dist;
  871.  
  872. // Take enemy cell size into account
  873. dist -= el.size;
  874.  
  875. // The farther they're from us the less repulsive they are
  876. vec.x /= dist;
  877. vec.y /= dist;
  878.  
  879. // Sum forces from all threats
  880. acc.x += vec.x;
  881. acc.y += vec.y;
  882.  
  883. return acc;
  884. }, {x: 0, y: 0});
  885.  
  886. // Normalize force to unit direction vector
  887. var dir_norm = Math.sqrt(direction.x * direction.x + direction.y * direction.y);
  888. direction.x /= dir_norm;
  889. direction.y /= dir_norm;
  890.  
  891. if(!isFinite(direction.x) || !isFinite(direction.y)) {
  892. return -1;
  893. }
  894.  
  895. return { id: -5, x: cell.x + direction.x * cell.size * 5, y: cell.y + direction.y * cell.size * 5 };
  896. }
  897.  
  898. function calcFoodDensity(cell, cell2, blobArray2){
  899. var MaxDistance2 = 250;
  900. var pelletCount = 0;
  901. blobArray2.forEach(function (element2){
  902. var distance2 = lineDistance(cell2, element2);
  903.  
  904. var cond1 = getMass(element2.size) <= (getMass(cell.size) * 0.4);
  905. var cond2 = distance2 < MaxDistance2;
  906. var cond3 = !element2.isVirus;
  907. //console.log(cond1 + " " + distance2 + " " + cell2.isSafeTarget);
  908. if( cond1 && cond2 && cond3 && cell2.isSafeTarget[cell.id] ){
  909. pelletCount +=1;
  910. }
  911. });
  912.  
  913. return pelletCount;
  914. }
  915. // ====================== UI stuff ==================================================================
  916.  
  917. function drawRescaledItems(ctx) {
  918. if (showVisualCues && isPlayerAlive()) {
  919. drawMapBorders(ctx);
  920. drawGrazingLines_old(ctx);
  921. drawGrazingLines(ctx);
  922. if(cobbler.drawTail){
  923. drawTrailTail(ctx);
  924. }
  925.  
  926.  
  927. drawSplitGuide(ctx, getSelectedBlob());
  928. drawMiniMap();
  929. }
  930. }
  931.  
  932. function getScoreBoardExtrasString(F) {
  933. var extras = " ";
  934. if (showVisualCues) {
  935. highScore = Math.max(highScore, ~~(F / 100));
  936. extras += " High: " + highScore.toString();
  937. if (isPlayerAlive()) {
  938. extras += "" + isPlayerAlive() ? " Alive: " + (~~((Date.now() - timeSpawned) / 1000)).toString() : "";
  939. }
  940. }
  941. return extras;
  942. }
  943.  
  944. function drawCellInfos(noColors, ctx) {
  945. var color = this.color;
  946. if (showVisualCues) {
  947. color = setCellColors(this, zeach.myPoints);
  948. if (this.isVirus) {
  949. if (!zeach.allNodes.hasOwnProperty(nearestVirusID))
  950. nearestVirusID = this.id;
  951. else if (distanceFromCellZero(this) < distanceFromCellZero(zeach.allNodes[nearestVirusID]))
  952. nearestVirusID = this.id;
  953. }
  954. if(noColors) {
  955. ctx.fillStyle = "#FFFFFF";
  956. ctx.strokeStyle = "#AAAAAA"
  957. }
  958. else {
  959. ctx.fillStyle = color;
  960. ctx.strokeStyle = (this.id == nearestVirusID) ? "red" : color
  961. }
  962. }
  963. }
  964.  
  965. function drawMapBorders(ctx) {
  966. if (zeach.isNightMode) {
  967. ctx.strokeStyle = '#FFFFFF';
  968. }
  969. ctx.beginPath();
  970. ctx.moveTo(zeach.mapLeft, zeach.mapTop); // 0
  971. ctx.lineTo(zeach.mapRight, zeach.mapTop); // >
  972. ctx.lineTo(zeach.mapRight, zeach.mapBottom); // V
  973. ctx.lineTo(zeach.mapLeft, zeach.mapBottom); // <
  974. ctx.lineTo(zeach.mapLeft, zeach.mapTop); // ^
  975. ctx.stroke();
  976. }
  977.  
  978. function drawSplitGuide(ctx, cell) {
  979. if( !isPlayerAlive() || !cobbler.splitGuide){
  980. return;
  981. }
  982. var radius = 660;
  983. var centerX = cell.x;
  984. var centerY = cell.y;
  985. var hold = ctx.globalAlpha;
  986. ctx.beginPath();
  987. ctx.arc(centerX, centerY, radius+cell.size, 0, 2 * Math.PI, false);
  988. ctx.lineWidth = 2;
  989. ctx.strokeStyle = '#FF0000';
  990. ctx.stroke();
  991.  
  992. ctx.beginPath();
  993. ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
  994. ctx.lineWidth = 2;
  995. ctx.strokeStyle = '#00FF00';
  996. ctx.stroke();
  997. ctx.globalAlpha = hold;
  998. }
  999.  
  1000. function isTeamMode(){
  1001. return (zeach.gameMode === ":teams");
  1002. }
  1003. function setCellColors(cell,myPoints){
  1004. if(!showVisualCues){
  1005. return cell.color;
  1006. }
  1007. if(cobbler.rainbowPellets && isFood(cell)){
  1008. return cell.color;
  1009. }
  1010. var color = cell.color;
  1011. if (myPoints.length > 0 && !isTeamMode()) {
  1012. var size_this = getMass(cell.size);
  1013. var size_that = ~~(getSelectedBlob().size * getSelectedBlob().size / 100);
  1014. if (cell.isVirus || myPoints.length === 0) {
  1015. color = virusColor;
  1016. } else if (~myPoints.indexOf(cell)) {
  1017. color = myColor;
  1018. } else if (size_this > size_that * Huge) {
  1019. color = Huge_Color;
  1020. } else if (size_this > size_that * Large) {
  1021. color = Large_Color;
  1022. } else if (size_this > size_that * Small) {
  1023. color = Same_Color;
  1024. } else if (size_this > size_that * Tiny) {
  1025. color = Small_Color;
  1026. } else {
  1027. color = Tiny_Color;
  1028. }
  1029. }
  1030. return color;
  1031. }
  1032.  
  1033. function displayDebugText(ctx, agarTextFunction) {
  1034.  
  1035. if(0 >= cobbler.debugLevel) {
  1036. return;
  1037. }
  1038.  
  1039. var textSize = 15;
  1040. var debugStrings = [];
  1041. if(1 <= cobbler.debugLevel) {
  1042. debugStrings.push("v " + _version_);
  1043. debugStrings.push("Server: " + serverIP);
  1044.  
  1045. debugStrings.push("G - grazing: " + (isGrazing ? (1 == isGrazing) ? "Old" : "New" : "Off"));
  1046. }
  1047. if(2 <= cobbler.debugLevel) {
  1048. debugStrings.push("M - suspend mouse: " + (suspendMouseUpdates ? "On" : "Off"));
  1049. debugStrings.push("P - grazing target fixation :" + (grazingTargetFixation ? "On" : "Off"));
  1050. if(grazingTargetFixation){ debugStrings.push(" (T) to retarget");}
  1051. debugStrings.push("O - right click: " + (cobbler.rightClickFires ? "Fires @ virus" : "Default"))
  1052. debugStrings.push("Z - zoom: " + zoomFactor.toString());
  1053. if (isPlayerAlive()) {
  1054. debugStrings.push("Location: " + Math.floor(getSelectedBlob().x) + ", " + Math.floor(getSelectedBlob().y));
  1055. }
  1056.  
  1057. }
  1058. var offsetValue = 20;
  1059. var text = new agarTextFunction(textSize, (zeach.isNightMode ? '#F2FBFF' : '#111111'));
  1060.  
  1061. for (var i = 0; i < debugStrings.length; i++) {
  1062. text.setValue(debugStrings[i]); // setValue
  1063. var textRender = text.render();
  1064. ctx.drawImage(textRender, 20, offsetValue);
  1065. offsetValue += textRender.height;
  1066. }
  1067. }
  1068.  
  1069. // Probably isn't necessary to throttle it ... but what the hell.
  1070. var rescaleMinimap = _.throttle(function(){
  1071. var minimapScale = cobbler.miniMapScaleValue;
  1072. var scaledWidth = ~~(zeach.mapWidth/minimapScale);
  1073. var scaledHeight = ~~(zeach.mapHeight/minimapScale);
  1074. var minimap = jQuery("#mini-map");
  1075.  
  1076. if(minimap.width() != scaledWidth || minimap.height() != scaledHeight || cobbler.minimapScaleCurrentValue != minimapScale){
  1077. // rescale the div
  1078. minimap.width(scaledWidth);
  1079. minimap.height(scaledHeight);
  1080. // rescale the canvas element
  1081. minimap[0].width = scaledWidth;
  1082. minimap[0].height = scaledHeight;
  1083. cobbler.minimapScaleCurrentValue = minimapScale;
  1084. }
  1085. }, 5*1000);
  1086.  
  1087. function drawMiniMap() {
  1088. rescaleMinimap();
  1089. var minimapScale = cobbler.miniMapScaleValue;
  1090. miniMapCtx.clearRect(0, 0, ~~(zeach.mapWidth/minimapScale), ~~(zeach.mapHeight/minimapScale));
  1091.  
  1092. _.forEach(_.values(getOtherBlobs()), function(blob){
  1093. miniMapCtx.strokeStyle = blob.isVirus ? "#33FF33" : 'rgb(52,152,219)' ;
  1094. miniMapCtx.beginPath();
  1095. miniMapCtx.arc((blob.nx+Math.abs(zeach.mapLeft)) / minimapScale, (blob.ny+Math.abs(zeach.mapTop)) / minimapScale, blob.size / minimapScale, 0, 2 * Math.PI);
  1096. miniMapCtx.stroke();
  1097. });
  1098.  
  1099. _.forEach(zeach.myPoints, function(myBlob){
  1100. miniMapCtx.strokeStyle = "#FFFFFF";
  1101. miniMapCtx.beginPath();
  1102. miniMapCtx.arc((myBlob.nx+Math.abs(zeach.mapLeft)) / minimapScale, (myBlob.ny+Math.abs(zeach.mapTop)) / minimapScale, myBlob.size / minimapScale, 0, 2 * Math.PI);
  1103. miniMapCtx.stroke();
  1104. });
  1105. }
  1106. function drawLine(ctx, point1, point2, color){
  1107. ctx.strokeStyle = color;
  1108. ctx.beginPath();
  1109. ctx.moveTo(point1.x, point1.y);
  1110. ctx.lineTo(point2.x, point2.y);
  1111. ctx.stroke();
  1112. }
  1113.  
  1114. function drawGrazingLines(ctx) {
  1115. if(!isGrazing || !cobbler.visualizeGrazing || !isPlayerAlive())
  1116. {
  1117. //console.log("returning early");
  1118. return;
  1119. }
  1120. var oldLineWidth = ctx.lineWidth;
  1121. var oldColor = ctx.color;
  1122. var oldGlobalAlpha = ctx.globalAlpha;
  1123.  
  1124. zeach.myPoints.forEach(function(playerBlob) {
  1125. if(!playerBlob.grazeInfo || playerBlob.grazingMode != 2) {
  1126. return;
  1127. }
  1128. var grazeInfo = playerBlob.grazeInfo;
  1129.  
  1130. var nullVec = { x: 0, y: 0 };
  1131. var cumulatives = grazeInfo.cumulatives;
  1132. var maxSize = 0.001;
  1133.  
  1134. // Render threat forces
  1135. grazeInfo.per_threat.forEach(function (grazeVec){
  1136. var element = zeach.allNodes[grazeVec.id];
  1137.  
  1138. if(!element) return; //Wall or dead or something
  1139.  
  1140. //drawLine(ctx,element, playerBlob, "red" );
  1141. //drawLine(ctx,element, {x: element.x + grazeVec.x / maxSize, y: element.y + grazeVec.y / maxSize }, "red" );
  1142. drawLine(ctx,playerBlob, {x: playerBlob.x + grazeVec.x / maxSize, y: playerBlob.y + grazeVec.y / maxSize }, "red" );
  1143.  
  1144. var grazeVecLen = Math.sqrt(grazeVec.x * grazeVec.x + grazeVec.y * grazeVec.y);
  1145.  
  1146. ctx.globalAlpha = 0.5 / zeach.myPoints.length;
  1147. ctx.beginPath();
  1148. ctx.arc(element.x, element.y, grazeVecLen / maxSize / 20, 0, 2 * Math.PI, false);
  1149. ctx.fillStyle = 'red';
  1150. ctx.fill();
  1151. ctx.lineWidth = 2;
  1152. ctx.strokeStyle = '#FFFFFF';
  1153. ctx.stroke();
  1154. ctx.globalAlpha = 1;
  1155. });
  1156.  
  1157. if(zeach.myPoints.length <= 1) {
  1158. // If we're not fragmented, render fancy food forces
  1159. grazeInfo.per_food.forEach(function (grazeVec){
  1160. var element = zeach.allNodes[grazeVec.id];
  1161.  
  1162. if(!element) return; //Wall or dead or something
  1163.  
  1164. //drawLine(ctx,element, playerBlob, "white" );
  1165. drawLine(ctx,element, {x: element.x + grazeVec.x / maxSize, y: element.y + grazeVec.y / maxSize }, "green" );
  1166. //drawLine(ctx,playerBlob, {x: playerBlob.x + grazeVec.x / maxSize, y: playerBlob.y + grazeVec.y / maxSize }, "green" );
  1167. });
  1168. }
  1169.  
  1170. // Prepare to render cumulatives
  1171. maxSize *= grazeInfo.per_threat.length + grazeInfo.per_food.length;
  1172. maxSize /= 10;
  1173.  
  1174. ctx.lineWidth = 10;
  1175.  
  1176. // Render summary force without special forces, like walls
  1177. drawLine(ctx,playerBlob,
  1178. {
  1179. x: playerBlob.x + (cumulatives[0].x + cumulatives[1].x) / maxSize,
  1180. y: playerBlob.y + (cumulatives[0].y + cumulatives[1].y) / maxSize,
  1181. }, "gray"
  1182. );
  1183.  
  1184. // Render foods and threats force cumulatives
  1185. drawLine(ctx,playerBlob, {x: playerBlob.x + cumulatives[1].x / maxSize, y: playerBlob.y + cumulatives[1].y / maxSize }, "green" );
  1186. drawLine(ctx,playerBlob, {x: playerBlob.x + cumulatives[0].x / maxSize, y: playerBlob.y + cumulatives[0].y / maxSize }, "red" );
  1187.  
  1188. // Render summary force with special forces, like walls
  1189. ctx.lineWidth = 5;
  1190. drawLine(ctx,playerBlob, {x: playerBlob.x + (grazeInfo.fx) / maxSize, y: playerBlob.y + (grazeInfo.fy) / maxSize }, "orange" );
  1191. ctx.lineWidth = 1;
  1192. drawLine(ctx,playerBlob, {x: playerBlob.x + 300 * (grazeInfo.fx) / maxSize, y: playerBlob.y + 300 * (grazeInfo.fy) / maxSize }, "orange" );
  1193. });
  1194.  
  1195. var viewport = getViewport(true);
  1196.  
  1197. // Render sent mouse coords as a small circle
  1198. ctx.globalAlpha = 0.5;
  1199. ctx.beginPath();
  1200. ctx.arc(lastMouseCoords.x, lastMouseCoords.y, 0.01 * viewport.dx, 0, 2 * Math.PI, false);
  1201. ctx.fillStyle = 'red';
  1202. ctx.fill();
  1203. ctx.lineWidth = 2;
  1204. ctx.strokeStyle = zeach.isNightMode ? '#FFFFFF' : '#000000';
  1205. ctx.stroke();
  1206. ctx.globalAlpha = 1;
  1207.  
  1208. // Render viewport borders, useful for blob lookout and 10-sec-memoization debugging
  1209. ctx.strokeStyle = zeach.isNightMode ? '#FFFFFF' : '#000000';
  1210. ctx.lineWidth = 5;
  1211.  
  1212. ctx.beginPath();
  1213. ctx.moveTo(viewport.x - viewport.dx, viewport.y - viewport.dy);
  1214. ctx.lineTo(viewport.x + viewport.dx, viewport.y - viewport.dy);
  1215. ctx.lineTo(viewport.x + viewport.dx, viewport.y + viewport.dy);
  1216. ctx.lineTo(viewport.x - viewport.dx, viewport.y + viewport.dy);
  1217. ctx.lineTo(viewport.x - viewport.dx, viewport.y - viewport.dy);
  1218. ctx.stroke();
  1219.  
  1220. ctx.globalAlpha = oldGlobalAlpha;
  1221. ctx.lineWidth = oldLineWidth;
  1222. ctx.color = oldColor;
  1223. }
  1224.  
  1225. function drawTrailTail(ctx) {
  1226. // Render trailing tail that indicates real movement,
  1227. // based on the difference between client-interpolated and real coords.
  1228. var trailScale = 5;
  1229. zeach.myPoints.forEach(function(playerBlob) {
  1230. var d = { x: playerBlob.nx - playerBlob.x, y: playerBlob.ny - playerBlob.y };
  1231. drawLine(ctx,playerBlob, {x: playerBlob.x - d.x * trailScale, y: playerBlob.y - d.y * trailScale }, myColor );
  1232. //drawLine(ctx,{x: playerBlob.ox, y: playerBlob.oy }, {x: playerBlob.nx, y: playerBlob.ny }, "green" );
  1233. });
  1234. }
  1235.  
  1236. function drawGrazingLines_old(ctx) {
  1237. if(!isGrazing || !cobbler.visualizeGrazing || !isPlayerAlive())
  1238. {
  1239. //console.log("returning early");
  1240. return;
  1241. }
  1242. var oldLineWidth = ctx.lineWidth;
  1243. var oldColor = ctx.color;
  1244.  
  1245. ctx.lineWidth = 10;
  1246. for(var i = 0; i < zeach.myPoints.length; i++) {
  1247. var point = zeach.myPoints[i];
  1248. if (point.grazingMode != 1) {
  1249. continue;
  1250. }
  1251.  
  1252. if(_.has(zeach.allNodes, point.grazingTargetID)){
  1253. drawLine(ctx, zeach.allNodes[point.grazingTargetID], point, "green");
  1254. }
  1255. }
  1256.  
  1257. ctx.lineWidth = 2;
  1258. for(var i = 0; i < zeach.myPoints.length; i++) {
  1259. var point = zeach.myPoints[i];
  1260. if (point.grazingMode != 1) {
  1261. continue;
  1262. }
  1263. zeach.allItems.forEach(function (element){
  1264. if (!element.isSafeTarget) {
  1265. } else if(element.isSafeTarget[point.id] === true) {
  1266. drawLine(ctx, element, point, "white" );
  1267. } else if (element.isSafeTarget[point.id] === false) {
  1268. drawLine(ctx, element, point, "red" );
  1269. } else {
  1270. //drawLine(ctx,element, getSelectedBlob(), "blue" );
  1271. }
  1272. })
  1273. }
  1274. ctx.lineWidth = oldLineWidth;
  1275. ctx.color = oldColor;
  1276.  
  1277. }
  1278.  
  1279. // ====================== Virus Popper ==================================================================
  1280. function findNearestVirus(cell, blobArray){
  1281. var nearestVirus = _.min(_.filter(blobArray, "isVirus", true), function(element) {
  1282. return lineDistance(cell, element);
  1283. });
  1284.  
  1285. if( Infinity == nearestVirus){
  1286. //console.log("No nearby viruses");
  1287. return -1;
  1288. }
  1289. return nearestVirus;
  1290. }
  1291.  
  1292. function fireAtVirusNearestToBlob(blob, blobArray) {
  1293. console.log("fireAtVirusNearestToBlob");
  1294. var msDelayBetweenShots = cobbler.msDelayBetweenShots;
  1295. nearestVirus = findNearestVirus(blob, blobArray);
  1296.  
  1297. if(-1 == nearestVirus){
  1298. console.log("No Nearby Virus Found");
  1299. console.log(blobArray);
  1300. console.log(blob);
  1301. return;
  1302. }
  1303.  
  1304. // TODO: count availableshots and limit shots sent to Math.min(shotsNeeded, ShotsAvailable)
  1305. var shotsNeeded = getVirusShotsNeededForSplit(nearestVirus.size);
  1306. var shotsFired = 0 / zeach.myPoints.length;
  1307. if(shotsNeeded <= 0){
  1308. return;
  1309. }
  1310.  
  1311. suspendMouseUpdates = true;
  1312. console.log("Nearest Virus at: ("+ nearestVirus.x + "," + nearestVirus.y + ") requires " + shotsNeeded + " shots.");
  1313. // two mouse updates in a row to make sure new position is locked in.
  1314. sendMouseUpdate(zeach.webSocket, nearestVirus.x + Math.random(), nearestVirus.y + Math.random());
  1315. window.setTimeout(function () { sendMouseUpdate(zeach.webSocket, nearestVirus.x + Math.random(), nearestVirus.y + Math.random()); }, 25);
  1316.  
  1317. // schedules all shots needed spaced evenly apart by of 'msDelayBetweenShots'
  1318. for ( ; shotsFired < shotsNeeded; shotsFired++){
  1319. window.setTimeout(function () {
  1320. sendMouseUpdate(zeach.webSocket, nearestVirus.x + Math.random(), nearestVirus.y + Math.random());
  1321. zeach.fireFunction(21);
  1322. }, msDelayBetweenShots *(shotsFired+1));
  1323. }
  1324. window.setTimeout(function () { suspendMouseUpdates = false;}, msDelayBetweenShots *(shotsFired+1));
  1325. }
  1326.  
  1327.  
  1328. function fireAtVirusNearestToCursor(){
  1329. fireAtVirusNearestToBlob(getMouseCoordsAsPseudoBlob(), zeach.allItems);
  1330. }
  1331.  
  1332. // ====================== Skins ==================================================================
  1333. /* AgarioMod.com skins have been moved to the very end of the file */
  1334. var extendedSkins = {
  1335. "billy mays" : "http://i.imgur.com/HavxFJu.jpg",
  1336. "stannis": "http://i.imgur.com/JyZr0CI.jpg",
  1337. "shrek is love" : "http://i.imgur.com/QDhkr4C.jpg",
  1338. "shrek is life" : "http://i.imgur.com/QDhkr4C.jpg",
  1339. "blueeyes" : "http://i.imgur.com/wxCfUws.jpg",
  1340. "ygritte" : "http://i.imgur.com/lDIFCT1.png",
  1341. "lord kience" : "http://i.imgur.com/b2UXk15.png",
  1342. }
  1343.  
  1344. var skinsSpecial = {
  1345. "white light": "https://i.imgur.com/4y8szAE.png",
  1346. "tubbymcfatfuck" : "http://tinyurl.com/TubbyMcFatFuck",
  1347. "texas doge" : "http://i.imgur.com/MVsLldL.jpg",
  1348. "doge helper" : "http://i.imgur.com/FzZebpk.jpg",
  1349. "controless " : "https://i.imgur.com/uD5SW8X.jpg",
  1350. "sqochit" : "http://i.imgur.com/AnowvFI.jpg",
  1351. "drunken" : "http://i.imgur.com/JeKNRss.png",
  1352. };
  1353.  
  1354.  
  1355. // special skins are defined in this script by me and are never translucent
  1356. function isSpecialSkin(targetName){
  1357. return skinsSpecial.hasOwnProperty(targetName.toLowerCase());
  1358. }
  1359. // special skins are defined in this script by me and can be translucent
  1360. function isExtendedSkin(targetName){
  1361. return _.has(extendedSkins, targetName.toLowerCase());
  1362. }
  1363.  
  1364. function isAgarioModsSkin(targetName){
  1365. if(!cobbler.amExtendedSkins){
  1366. return false;
  1367. }
  1368. return _.includes(agariomodsSkins, targetName)
  1369. }
  1370. function isImgurSkin(targetName){
  1371. if(!cobbler.imgurSkins){
  1372. return false;
  1373. }
  1374. return _.startsWith(targetName, "i/");
  1375. }
  1376. function isAMConnectSkin(targetName){
  1377. if(!cobbler.amConnectSkins){
  1378. return false;
  1379. }
  1380. return _.startsWith(targetName, "*");
  1381. }
  1382.  
  1383.  
  1384. function customSkins(cell, defaultSkins, imgCache, showSkins, gameMode) {
  1385. var retval = null;
  1386. var userName = cell.name;
  1387. var userNameLowerCase = userName.toLowerCase();
  1388. if(":teams" == gameMode)
  1389. {
  1390. retval = null;
  1391. }
  1392. else if(!cell.isAgitated && showSkins ){
  1393. if(-1 != defaultSkins.indexOf(userNameLowerCase) || isSpecialSkin(userNameLowerCase) || isImgurSkin(userNameLowerCase) ||
  1394. isAgarioModsSkin(userNameLowerCase) || isAMConnectSkin(userNameLowerCase) || isExtendedSkin(userNameLowerCase)){
  1395. if (!imgCache.hasOwnProperty(userNameLowerCase)){
  1396. if(isSpecialSkin(userNameLowerCase)) {
  1397. imgCache[userNameLowerCase] = new Image;
  1398. imgCache[userNameLowerCase].src = skinsSpecial[userNameLowerCase];
  1399. }
  1400. else if(isExtendedSkin(userNameLowerCase)) {
  1401. imgCache[userNameLowerCase] = new Image;
  1402. imgCache[userNameLowerCase].src = extendedSkins[userNameLowerCase];
  1403. }
  1404. else if(isAgarioModsSkin(userNameLowerCase)) {
  1405. imgCache[userNameLowerCase] = new Image;
  1406. imgCache[userNameLowerCase].src = "http://skins.agariomods.com/i/" + userNameLowerCase + ".png";
  1407. }
  1408. else if(isAMConnectSkin(userNameLowerCase)) {
  1409. console.log("is AmConnect skin")
  1410. imgCache[userNameLowerCase] = new Image;
  1411. imgCache[userNameLowerCase].src = "http://connect.agariomods.com/img_" + userNameLowerCase.slice(1) + ".png";
  1412. }
  1413. else if(isImgurSkin(userNameLowerCase)){
  1414. imgCache[userNameLowerCase] = new Image;
  1415. imgCache[userNameLowerCase].src = "http://i.imgur.com/"+ userName.slice(2) +".png";
  1416. }
  1417.  
  1418. else{
  1419. imgCache[userNameLowerCase] = new Image;
  1420. imgCache[userNameLowerCase].src = "skins/" + userNameLowerCase + ".png";
  1421. }
  1422. }
  1423. if(0 != imgCache[userNameLowerCase].width && imgCache[userNameLowerCase].complete) {
  1424. retval = imgCache[userNameLowerCase];
  1425. } else {
  1426. retval = null;
  1427. }
  1428. }
  1429. else {
  1430. retval = null;
  1431. }
  1432. }
  1433. else {
  1434. retval = null;
  1435. }
  1436. return retval;
  1437. }
  1438.  
  1439.  
  1440. // ====================== Draw Functions ==================================================================
  1441. function shouldRelocateName(){
  1442. if(cobbler.namesUnderBlobs && !this.isVirus) {
  1443. return true;
  1444. }
  1445. return ((isExtendedSkin(this.name)|| isSpecialSkin(this.name) || /*isBitDoSkin(this.name)||*/ isAMConnectSkin(this.name)));
  1446. }
  1447.  
  1448. function drawCellName(isMyCell, kbIndex, itemToDraw){
  1449. var yBasePos;
  1450. var nameCache = this.nameCache;
  1451. yBasePos = ~~this.y;
  1452. // Viruses have empty name caches. If this is a virus with an empty name cache
  1453. // then give it a name of the # of shots needed to split it.
  1454. if(null == nameCache) {
  1455. if (this.isVirus) {
  1456. var virusSize = this.nSize;
  1457. var shotsNeeded = getVirusShotsNeededForSplit(virusSize).toString();
  1458. this.setName(shotsNeeded);
  1459. } else if(!isFood(this)) {
  1460. this.setName(this.nSize.toString()); // Stupid blank cells. Give them a name.
  1461. }
  1462. }
  1463.  
  1464. if((zeach.hasNickname || isMyCell) && (this.name && (nameCache && (null == itemToDraw || -1 == zeach.textBlobs.indexOf(kbIndex)))) ) {
  1465.  
  1466. itemToDraw = nameCache;
  1467. itemToDraw.setValue(this.name);
  1468. setCellName(this, itemToDraw);
  1469. itemToDraw.setSize(this.maxNameSize());
  1470. var scale = Math.ceil(10 * zeach.scale) / 10;
  1471. itemToDraw.setScale(scale);
  1472.  
  1473. setVirusInfo(this, itemToDraw, scale);
  1474. itemToDraw = itemToDraw.render();
  1475. var xPos = ~~(itemToDraw.width / scale);
  1476. var yPos = ~~(itemToDraw.height / scale);
  1477.  
  1478. if(shouldRelocateName.call(this)) {
  1479. // relocate names to UNDER the cell rather than on top of it
  1480. zeach.ctx.drawImage(itemToDraw, ~~this.x - ~~(xPos / 2), yBasePos + ~~(yPos ), xPos, yPos);
  1481. yBasePos += itemToDraw.height / 2 / scale + 8;
  1482. }
  1483. else {
  1484. zeach.ctx.drawImage(itemToDraw, ~~this.x - ~~(xPos / 2), yBasePos - ~~(yPos / 2), xPos, yPos);
  1485. }
  1486. yBasePos += itemToDraw.height / 2 / scale + 4;
  1487. }
  1488. return yBasePos;
  1489. }
  1490.  
  1491. function drawCellMass(yBasePos, itemToDraw){
  1492. var massValue = (~~(getMass(this.size))).toString();
  1493. // Append shots to mass if visual cues are enabled
  1494. if(showVisualCues && _.contains(zeach.myIDs, this.id)){
  1495. massValue += " (" + getBlobShotsAvailable(this).toString() + ")";
  1496. }
  1497.  
  1498. if(zeach.isShowMass) {
  1499. var scale;
  1500. if(itemToDraw || 0 == zeach.myPoints.length && ((!this.isVirus || this.isAgitated) && 20 < this.size)) {
  1501. if(null == this.massText) {
  1502. this.massText = new zeach.CachedCanvas(this.maxNameSize() / 2, "#FFFFFF", true, "#000000");
  1503. }
  1504. itemToDraw = this.massText;
  1505. itemToDraw.setSize(this.maxNameSize() / 2);
  1506. itemToDraw.setValue(massValue); // precalculated & possibly appended
  1507. scale = Math.ceil(10 * zeach.scale) / 10;
  1508. itemToDraw.setScale(scale);
  1509.  
  1510. // Tweak : relocated mass is line is bigger than stock
  1511. itemToDraw.setScale(scale * ( shouldRelocateName.call(this) ? 2 : 1));
  1512.  
  1513. var e = itemToDraw.render();
  1514. var xPos = ~~(e.width / scale);
  1515. var yPos = ~~(e.height / scale);
  1516. if(shouldRelocateName.call(this)) {
  1517. // relocate mass to UNDER the cell rather than on top of it
  1518. zeach.ctx.drawImage(e, ~~this.x - ~~(xPos / 2), yBasePos + ~~(yPos), xPos, yPos);
  1519. }
  1520. else {
  1521. zeach.ctx.drawImage(e, ~~this.x - ~~(xPos / 2), yBasePos - ~~(yPos / 2), xPos, yPos);
  1522. }
  1523. }
  1524. }
  1525.  
  1526. }
  1527.  
  1528. // ====================== Misc ==================================================================
  1529.  
  1530. function switchCurrentBlob() {
  1531. var myids_sorted = _.pluck(zeach.myPoints, "id").sort(); // sort by id
  1532. var indexloc = _.indexOf(myids_sorted, selectedBlobID);
  1533. if(-1 === indexloc){
  1534. selectedBlobID = zeach.myPoints[0].id;
  1535. console.log("Had to select new blob. Its id is " + selectedBlobID);
  1536. return zeach.allNodes[selectedBlobID];
  1537. }
  1538. indexloc += 1;
  1539. if(indexloc >= myids_sorted.length){
  1540. selectedBlobID = zeach.myPoints[0].id;
  1541. console.log("Reached array end. Moving to beginning with id " + selectedBlobID);
  1542. return zeach.allNodes[selectedBlobID];
  1543. }
  1544. selectedBlobID = zeach.myPoints[indexloc].id;
  1545. return zeach.allNodes[selectedBlobID];
  1546. }
  1547.  
  1548. function customKeyDownEvents(d) {
  1549. //if('X'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1550. // jQuery("#overlays").hide();
  1551. // jQuery("#ZCOverlay").hide();
  1552. // isGrazing = 0;
  1553. // showVisualCues = true;
  1554. // suspendMouseUpdates = false;
  1555. // cobbler.enableBlobLock = false;
  1556. //}
  1557. if(jQuery("#overlays").is(':visible')){
  1558. return;
  1559. }
  1560.  
  1561. if(9 === d.keyCode && isPlayerAlive()) {
  1562. d.preventDefault();
  1563. switchCurrentBlob();
  1564. }
  1565. else if('A'.charCodeAt(0) === d.keyCode && isPlayerAlive()){
  1566. cobbler.isAcid = !cobbler.isAcid;
  1567. setAcid(cobbler.isAcid);
  1568. }
  1569. else if('C'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1570. grazzerTargetResetRequest = "all";
  1571. showVisualCues = !showVisualCues;
  1572. if(!showVisualCues) {
  1573. zoomFactor = 10;
  1574. jQuery("#mini-map").hide();
  1575. }
  1576. else
  1577. {
  1578. jQuery("#mini-map").show();
  1579. }
  1580. }
  1581. else if('E'.charCodeAt(0) === d.keyCode && isPlayerAlive()){
  1582. fireAtVirusNearestToCursor();
  1583. }
  1584. else if('G'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1585. if(cobbler.grazerHybridSwitch && isGrazing){
  1586. isGrazing = 0;
  1587. return;
  1588. }
  1589. grazzerTargetResetRequest = "all";
  1590. isGrazing = (2 == isGrazing) ? false : 2;
  1591. }
  1592. else if('H'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1593. if(cobbler.grazerHybridSwitch && isGrazing){
  1594. isGrazing = 0;
  1595. return;
  1596. }
  1597. grazzerTargetResetRequest = "all";
  1598. isGrazing = (1 == isGrazing) ? false : 1;
  1599. }
  1600. else if('M'.charCodeAt(0) === d.keyCode && isPlayerAlive()){
  1601. suspendMouseUpdates = !suspendMouseUpdates;
  1602. }
  1603. else if('O'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1604. cobbler.rightClickFires = !cobbler.rightClickFires;
  1605. }
  1606. else if('P'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1607. grazingTargetFixation = !grazingTargetFixation;
  1608. }
  1609. else if('R'.charCodeAt(0) === d.keyCode && isPlayerAlive()){
  1610. fireAtVirusNearestToBlob(getSelectedBlob(),zeach.allItems);
  1611. }
  1612. else if('T'.charCodeAt(0) === d.keyCode && isPlayerAlive() && (1 == isGrazing)) {
  1613. console.log("Retarget requested");
  1614. grazzerTargetResetRequest = "current";
  1615. }
  1616. else if('V'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1617. cobbler.visualizeGrazing = !cobbler.visualizeGrazing;
  1618. }
  1619. else if('Z'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1620. // /*old*/ zoomFactor = (zoomFactor == 10 ? 11 : 10);
  1621. /*new*/ zoomFactor = zoomFactor >= 11 ? 10 : +(zoomFactor + 0.1).toFixed(2);
  1622. }
  1623. else if('1'.charCodeAt(0) <= d.keyCode && '7'.charCodeAt(0) >= d.keyCode && isPlayerAlive()) {
  1624. var id = d.keyCode - '1'.charCodeAt(0);
  1625. if(id >= _.size(zeach.myPoints)) {return; }
  1626. var arr = _.sortBy(zeach.myPoints, "nSize").reverse();
  1627. selectedBlobID = arr[id].id;
  1628. }
  1629. else if('S'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
  1630. for(var i = 0; i < zeach.myPoints.length; i++) {
  1631. var point = zeach.myPoints[i];
  1632. point.locked = false;
  1633. }
  1634. }
  1635. }
  1636.  
  1637. function onAfterUpdatePacket() {
  1638. if (!isPlayerAlive()){
  1639. timeSpawned = null;
  1640. }
  1641. if(null == timeSpawned && isPlayerAlive()) {
  1642. timeSpawned = Date.now(); // it's been reported we miss some instances of player spawning
  1643. }
  1644. }
  1645.  
  1646. function onBeforeNewPointPacket() {
  1647. if (0 == _.size(zeach.myPoints)){
  1648. timeSpawned = Date.now();
  1649. }
  1650. }
  1651.  
  1652. function setCellName(cell, d) {
  1653. if (showVisualCues) {
  1654. var pct;
  1655. if (_.size(zeach.myPoints) > 1 && _.contains(zeach.myIDs, cell.id)) {
  1656. var oldestSplitTime = _.min(zeach.myPoints, "splitTime");
  1657. if(oldestSplitTime.id == cell.id){
  1658. d.setValue(cell.name);
  1659. } else {
  1660. pct = (cell.nSize * cell.nSize) * 100 / (getSelectedBlob().nSize * getSelectedBlob().nSize);
  1661. d.setValue(calcTTR(cell) + " ttr" + " " + ~~(pct) + "%");}
  1662. } else if (!cell.isVirus && isPlayerAlive()) {
  1663. pct = ~~((cell.nSize * cell.nSize) * 100 / (getSelectedBlob().nSize * getSelectedBlob().nSize));
  1664. d.setValue(cell.name + " " + pct.toString() + "%");
  1665. }
  1666. }
  1667. }
  1668.  
  1669. function setVirusInfo(cell, ctx, c) {
  1670. ctx.setScale(c * 1.25);
  1671. if (showVisualCues) {
  1672. if (cell.isVirus) {
  1673. cell.nameCache.setValue(getVirusShotsNeededForSplit(cell.nSize));
  1674. var nameSizeMultiplier = 4;
  1675. ctx.setScale(c * nameSizeMultiplier);
  1676. }
  1677. }
  1678. if (cell.isVirus && !showVisualCues) {
  1679. cell.nameCache.setValue(" ");
  1680. }
  1681. }
  1682.  
  1683.  
  1684. function sendMultyMouseUpdate(send_normal) {
  1685. for (var i = 0; i < zeach.myPoints.length; i++) {
  1686. var blob = zeach.myPoints[i];
  1687. var x = zeach.mouseX2;
  1688. var y = zeach.mouseY2;
  1689. if (blob.locked) {
  1690. blob.last_locked--;
  1691. if (blob.last_locked < 0) {
  1692. continue;
  1693. }
  1694. x = blob.locked_x;
  1695. y = blob.locked_y;
  1696. } else if (!send_normal) {
  1697. continue;
  1698. }
  1699. var z0 = new ArrayBuffer(13);
  1700. var z1 = new DataView(z0);
  1701. z1.setUint8(0, 16);
  1702. z1.setInt32(1, x, true);
  1703. z1.setInt32(5, y, true);
  1704. z1.setUint32(9, blob.id, true);
  1705. zeach.webSocket.send(z0);
  1706. }
  1707. }
  1708.  
  1709. function lockCurrentBlob() {
  1710. if(!isPlayerAlive()){
  1711. return;
  1712. }
  1713. var blob = getSelectedBlob();
  1714. if (blob.locked) {
  1715. blob.locked = false;
  1716. } else {
  1717. if (cobbler.nextOnBlobLock) {
  1718. switchCurrentBlob();
  1719. }
  1720. blob.locked = true;
  1721. blob.last_locked = 10;
  1722. blob.locked_x = zeach.mouseX2;
  1723. blob.locked_y = zeach.mouseY2;
  1724. }
  1725. }
  1726.  
  1727.  
  1728. // ====================== Start main ==================================================================
  1729.  
  1730. function kb() {
  1731. wa = true;
  1732. La();
  1733. setInterval(La, 18E4);
  1734. F = xa = document.getElementById("canvas");
  1735. g = F.getContext("2d");
  1736. // /*old*/ (/*new*/ /remap/) F.onmousewheel = function (e) {zoomFactor = e.wheelDelta > 0 ? 10 : 11;}
  1737. /*new*/ F.onmousewheel = function (e) {
  1738. if (e.wheelDelta > 0) {
  1739. zoomFactor = zoomFactor <= 9.50 ? 9.50 : +(zoomFactor - 0.05).toFixed(2);
  1740. } else {
  1741. zoomFactor = zoomFactor >= 11 ? 11 : +(zoomFactor + 0.05).toFixed(2);
  1742. }
  1743.  
  1744. };
  1745. F.onmousedown = function(a) {
  1746. /*new*/if(cobbler.enableBlobLock) {lockCurrentBlob();}
  1747. /*new*/if(isPlayerAlive() && cobbler.rightClickFires){fireAtVirusNearestToCursor();}return;
  1748. if (Ma) {
  1749. var c = a.clientX - (5 + q / 5 / 2);
  1750. var b = a.clientY - (5 + q / 5 / 2);
  1751. if (Math.sqrt(c * c + b * b) <= q / 5 / 2) {
  1752. U();
  1753. G(17);
  1754. return;
  1755. }
  1756. }
  1757. ca = a.clientX;
  1758. da = a.clientY;
  1759. ya();
  1760. U();
  1761. };
  1762. F.onmousemove = function(a) {
  1763. ca = a.clientX;
  1764. da = a.clientY;
  1765. ya();
  1766. };
  1767. F.onmouseup = function() {
  1768. };
  1769. if (/firefox/i.test(navigator.userAgent)) {
  1770. document.addEventListener("DOMMouseScroll", Na, false);
  1771. } else {
  1772. document.body.onmousewheel = Na;
  1773. }
  1774. var a = false;
  1775. var c = false;
  1776. var b = false;
  1777. d.onkeydown = function(e) {
  1778. if (!(32 != e.keyCode)) {
  1779. if (!a) {
  1780. U();
  1781. G(17);
  1782. a = true;
  1783. }
  1784. }
  1785. if (!(81 != e.keyCode)) {
  1786. if (!c) {
  1787. G(18);
  1788. c = true;
  1789. }
  1790. }
  1791. if (!(87 != e.keyCode)) {
  1792. if (!b) {
  1793. U();
  1794. G(21);
  1795. b = true;
  1796. }
  1797. }
  1798. if (27 == e.keyCode) {
  1799. Oa(true);
  1800. }
  1801. /*new*/customKeyDownEvents(e);
  1802. };
  1803. d.onkeyup = function(e) {
  1804. if (32 == e.keyCode) {
  1805. a = false;
  1806. }
  1807. if (87 == e.keyCode) {
  1808. b = false;
  1809. }
  1810. if (81 == e.keyCode) {
  1811. if (c) {
  1812. G(19);
  1813. c = false;
  1814. }
  1815. }
  1816. };
  1817. d.onblur = function() {
  1818. G(19);
  1819. b = c = a = false;
  1820. };
  1821. d.onresize = Pa;
  1822. d.requestAnimationFrame(Qa);
  1823. setInterval(U, 40);
  1824. if (x) {
  1825. f("#region").val(x);
  1826. }
  1827. Ra();
  1828. ea(f("#region").val());
  1829. if (0 == za) {
  1830. if (x) {
  1831. N();
  1832. }
  1833. }
  1834. V = true;
  1835. f("#overlays").show();
  1836. Pa();
  1837. }
  1838. function Na(a) {
  1839. // /*new*/ H *= Math.pow(0.9, a.wheelDelta / -120 || (a.detail || 0));
  1840. if (1 > H) {
  1841. H = 1;
  1842. }
  1843. if (H > 4 / k) {
  1844. H = 4 / k;
  1845. }
  1846. }
  1847. function lb() {
  1848. if (0.4 > k) {
  1849. W = null;
  1850. } else {
  1851. var a = Number.POSITIVE_INFINITY;
  1852. var c = Number.POSITIVE_INFINITY;
  1853. var b = Number.NEGATIVE_INFINITY;
  1854. var e = Number.NEGATIVE_INFINITY;
  1855. var l = 0;
  1856. var p = 0;
  1857. for (;p < v.length;p++) {
  1858. var h = v[p];
  1859. if (!!h.N()) {
  1860. if (!h.R) {
  1861. if (!(20 >= h.size * k)) {
  1862. l = Math.max(h.size, l);
  1863. a = Math.min(h.x, a);
  1864. c = Math.min(h.y, c);
  1865. b = Math.max(h.x, b);
  1866. e = Math.max(h.y, e);
  1867. }
  1868. }
  1869. }
  1870. }
  1871. W = mb.ja({
  1872. ca : a - (l + 100),
  1873. da : c - (l + 100),
  1874. ma : b + (l + 100),
  1875. na : e + (l + 100),
  1876. ka : 2,
  1877. la : 4
  1878. });
  1879. p = 0;
  1880. for (;p < v.length;p++) {
  1881. if (h = v[p], h.N() && !(20 >= h.size * k)) {
  1882. a = 0;
  1883. for (;a < h.a.length;++a) {
  1884. c = h.a[a].x;
  1885. b = h.a[a].y;
  1886. if (!(c < t - q / 2 / k)) {
  1887. if (!(b < u - s$$0 / 2 / k)) {
  1888. if (!(c > t + q / 2 / k)) {
  1889. if (!(b > u + s$$0 / 2 / k)) {
  1890. W.m(h.a[a]);
  1891. }
  1892. }
  1893. }
  1894. }
  1895. }
  1896. }
  1897. }
  1898. }
  1899. }
  1900. function ya() {
  1901. fa = (ca - q / 2) / k + t;
  1902. ga = (da - s$$0 / 2) / k + u;
  1903. }
  1904. function La() {
  1905. if (null == ha) {
  1906. ha = {};
  1907. f("#region").children().each(function() {
  1908. var a = f(this);
  1909. var c = a.val();
  1910. if (c) {
  1911. ha[c] = a.text();
  1912. }
  1913. });
  1914. }
  1915. f.get("https://m.agar.io/info", function(a) {
  1916. var c = {};
  1917. var b;
  1918. for (b in a.regions) {
  1919. var e = b.split(":")[0];
  1920. c[e] = c[e] || 0;
  1921. c[e] += a.regions[b].numPlayers;
  1922. }
  1923. for (b in c) {
  1924. f('#region option[value="' + b + '"]').text(ha[b] + " (" + c[b] + " players)");
  1925. }
  1926. }, "json");
  1927. }
  1928. function Sa() {
  1929. f("#adsBottom").hide();
  1930. f("#overlays").hide();
  1931. V = false;
  1932. Ra();
  1933. if (d.googletag) {
  1934. if (d.googletag.pubads && d.googletag.pubads().clear) {
  1935. d.googletag.pubads().clear(d.aa);
  1936. }
  1937. }
  1938. }
  1939. function ea(a) {
  1940. if (a) {
  1941. if (a != x) {
  1942. if (f("#region").val() != a) {
  1943. f("#region").val(a);
  1944. }
  1945. x = d.localStorage.location = a;
  1946. f(".region-message").hide();
  1947. f(".region-message." + a).show();
  1948. f(".btn-needs-server").prop("disabled", false);
  1949. if (wa) {
  1950. N();
  1951. }
  1952. }
  1953. }
  1954. }
  1955. function Oa(a) {
  1956. if (!V) {
  1957. I = null;
  1958. nb();
  1959. if (a) {
  1960. w = 1;
  1961. }
  1962. V = true;
  1963. f("#overlays").fadeIn(a ? 200 : 3E3);
  1964. /*new*//*mikey*/OnShowOverlay(a);
  1965. }
  1966. }
  1967. function ia(a) {
  1968. f("#helloContainer").attr("data-gamemode", a);
  1969. O = a;
  1970. f("#gamemode").val(a);
  1971. }
  1972. function Ra() {
  1973. if (f("#region").val()) {
  1974. d.localStorage.location = f("#region").val();
  1975. } else {
  1976. if (d.localStorage.location) {
  1977. f("#region").val(d.localStorage.location);
  1978. }
  1979. }
  1980. if (f("#region").val()) {
  1981. f("#locationKnown").append(f("#region"));
  1982. } else {
  1983. f("#locationUnknown").append(f("#region"));
  1984. }
  1985. }
  1986. function nb() {
  1987. if (ja) {
  1988. ja = false;
  1989. setTimeout(function() {
  1990. ja = true;
  1991. }, 6E4 * Ta);
  1992. if (d.googletag) {
  1993. if (d.googletag.pubads && d.googletag.pubads().clear) {
  1994. d.googletag.pubads().refresh(d.aa);
  1995. }
  1996. }
  1997. }
  1998. }
  1999. function X(a) {
  2000. return d.i18n[a] || (d.i18n_dict.en[a] || a);
  2001. }
  2002. function Ua() {
  2003. var a = ++za;
  2004. console.log("Find " + x + O);
  2005. f.ajax("https://m.agar.io/", {
  2006. error : function() {
  2007. setTimeout(Ua, 1E3);
  2008. },
  2009. success : function(c) {
  2010. if (a == za) {
  2011. c = c.split("\n");
  2012. if (c[2]) {
  2013. alert(c[2]);
  2014. }
  2015. Aa("ws://" + c[0], c[1]);
  2016. /*new*/ serverIP = c[0];
  2017. }
  2018. },
  2019. dataType : "text",
  2020. method : "POST",
  2021. cache : false,
  2022. crossDomain : true,
  2023. data : (x + O || "?") + "\n154669603"
  2024. });
  2025. }
  2026. function N() {
  2027. if (wa) {
  2028. if (x) {
  2029. f("#connecting").show();
  2030. Ua();
  2031. }
  2032. }
  2033. }
  2034. function Aa(a$$0, c) {
  2035. if (r) {
  2036. r.onopen = null;
  2037. r.onmessage = null;
  2038. r.onclose = null;
  2039. try {
  2040. r.close();
  2041. } catch (b$$0) {
  2042. }
  2043. r = null;
  2044. }
  2045. if (null != J) {
  2046. var e = J;
  2047. J = function() {
  2048. e(c);
  2049. };
  2050. }
  2051. if (ob) {
  2052. var l = a$$0.split(":");
  2053. a$$0 = l[0] + "s://ip-" + l[1].replace(/\./g, "-").replace(/\//g, "") + ".tech.agar.io:" + (+l[2] + 2E3);
  2054. }
  2055. K = [];
  2056. m = [];
  2057. D = {};
  2058. v = [];
  2059. P = [];
  2060. E = [];
  2061. y = z = null;
  2062. Q = 0;
  2063. ka = false;
  2064. console.log("Connecting to " + a$$0);
  2065. r = new WebSocket(a$$0);
  2066. r.binaryType = "arraybuffer";
  2067. r.onopen = function() {
  2068. var a;
  2069. console.log("socket open");
  2070. a = L(5);
  2071. a.setUint8(0, 254);
  2072. a.setUint32(1, 5, true);
  2073. M(a);
  2074. a = L(5);
  2075. a.setUint8(0, 255);
  2076. a.setUint32(1, 154669603, true);
  2077. M(a);
  2078. a = L(1 + c.length);
  2079. a.setUint8(0, 80);
  2080. var b = 0;
  2081. for (;b < c.length;++b) {
  2082. a.setUint8(b + 1, c.charCodeAt(b));
  2083. }
  2084. M(a);
  2085. Va();
  2086. };
  2087. r.onmessage = pb;
  2088. r.onclose = qb;
  2089. r.onerror = function() {
  2090. console.log("socket error");
  2091. };
  2092. }
  2093. function L(a) {
  2094. return new DataView(new ArrayBuffer(a));
  2095. }
  2096. function M(a) {
  2097. r.send(a.buffer);
  2098. }
  2099. function qb() {
  2100. if (ka) {
  2101. la = 500;
  2102. }
  2103. console.log("socket close");
  2104. setTimeout(N, la);
  2105. la *= 2;
  2106. }
  2107. function pb(a) {
  2108. rb(new DataView(a.data));
  2109. }
  2110. function rb(a) {
  2111. function c$$0() {
  2112. var c = "";
  2113. for (;;) {
  2114. var e = a.getUint16(b, true);
  2115. b += 2;
  2116. if (0 == e) {
  2117. break;
  2118. }
  2119. c += String.fromCharCode(e);
  2120. }
  2121. return c;
  2122. }
  2123. var b = 0;
  2124. if (240 == a.getUint8(b)) {
  2125. b += 5;
  2126. }
  2127. switch(a.getUint8(b++)) {
  2128. case 16:
  2129. sb(a, b);
  2130. /*new*/onAfterUpdatePacket();
  2131. break;
  2132. case 17:
  2133. Y = a.getFloat32(b, true);
  2134. b += 4;
  2135. Z = a.getFloat32(b, true);
  2136. b += 4;
  2137. $ = a.getFloat32(b, true);
  2138. b += 4;
  2139. break;
  2140. case 20:
  2141. m = [];
  2142. K = [];
  2143. break;
  2144. case 21:
  2145. Ba = a.getInt16(b, true);
  2146. b += 2;
  2147. Ca = a.getInt16(b, true);
  2148. b += 2;
  2149. if (!Da) {
  2150. Da = true;
  2151. ma = Ba;
  2152. na = Ca;
  2153. }
  2154. break;
  2155. case 32:
  2156. /*new*/onBeforeNewPointPacket();
  2157. K.push(a.getUint32(b, true));
  2158. b += 4;
  2159. break;
  2160. case 49:
  2161. if (null != z) {
  2162. break;
  2163. }
  2164. var e$$0 = a.getUint32(b, true);
  2165. b = b + 4;
  2166. E = [];
  2167. var l = 0;
  2168. for (;l < e$$0;++l) {
  2169. var p = a.getUint32(b, true);
  2170. b = b + 4;
  2171. E.push({
  2172. id : p,
  2173. name : c$$0()
  2174. });
  2175. }
  2176. Wa();
  2177. break;
  2178. case 50:
  2179. z = [];
  2180. e$$0 = a.getUint32(b, true);
  2181. b += 4;
  2182. l = 0;
  2183. for (;l < e$$0;++l) {
  2184. z.push(a.getFloat32(b, true));
  2185. b += 4;
  2186. }
  2187. Wa();
  2188. break;
  2189. case 64:
  2190. oa = a.getFloat64(b, true);
  2191. b += 8;
  2192. pa = a.getFloat64(b, true);
  2193. b += 8;
  2194. qa = a.getFloat64(b, true);
  2195. b += 8;
  2196. ra = a.getFloat64(b, true);
  2197. b += 8;
  2198. Y = (qa + oa) / 2;
  2199. Z = (ra + pa) / 2;
  2200. $ = 1;
  2201. if (0 == m.length) {
  2202. t = Y;
  2203. u = Z;
  2204. k = $;
  2205. }
  2206. break;
  2207. case 81:
  2208. var h = a.getUint32(b, true);
  2209. b = b + 4;
  2210. var d = a.getUint32(b, true);
  2211. b = b + 4;
  2212. var f = a.getUint32(b, true);
  2213. b = b + 4;
  2214. setTimeout(function() {
  2215. R({
  2216. e : h,
  2217. f : d,
  2218. d : f
  2219. });
  2220. }, 1200);
  2221. }
  2222. }
  2223. function sb(a, c) {
  2224. Xa = A = Date.now();
  2225. if (!ka) {
  2226. ka = true;
  2227. f("#connecting").hide();
  2228. Ya();
  2229. if (J) {
  2230. J();
  2231. J = null;
  2232. }
  2233. }
  2234. var b = Math.random();
  2235. Ea = false;
  2236. var e = a.getUint16(c, true);
  2237. c += 2;
  2238. var l = 0;
  2239. for (;l < e;++l) {
  2240. var p = D[a.getUint32(c, true)];
  2241. var h = D[a.getUint32(c + 4, true)];
  2242. c += 8;
  2243. if (p) {
  2244. if (h) {
  2245. /*new*//*mikey*//*remap*/OnCellEaten(p,h);
  2246. /*new*/// Remove from 10-sec-remembered cells list by id
  2247. /*new*//*remap*/_.remove(ghostBlobs, {id: h.id});
  2248. h.X();
  2249. h.s = h.x;
  2250. h.t = h.y;
  2251. h.r = h.size;
  2252. h.J = p.x;
  2253. h.K = p.y;
  2254. h.q = h.size;
  2255. h.Q = A;
  2256. }
  2257. }
  2258. }
  2259. l = 0;
  2260. for (;;) {
  2261. e = a.getUint32(c, true);
  2262. c += 4;
  2263. if (0 == e) {
  2264. break;
  2265. }
  2266. ++l;
  2267. var d;
  2268. p = a.getInt32(c, true);
  2269. c += 4;
  2270. h = a.getInt32(c, true);
  2271. c += 4;
  2272. d = a.getInt16(c, true);
  2273. c += 2;
  2274. var g = a.getUint8(c++);
  2275. var k = a.getUint8(c++);
  2276. var q = a.getUint8(c++);
  2277. g = (g << 16 | k << 8 | q).toString(16);
  2278. for (;6 > g.length;) {
  2279. g = "0" + g;
  2280. }
  2281. g = "#" + g;
  2282. k = a.getUint8(c++);
  2283. q = !!(k & 1);
  2284. var s = !!(k & 16);
  2285. if (k & 2) {
  2286. c += 4;
  2287. }
  2288. if (k & 4) {
  2289. c += 8;
  2290. }
  2291. if (k & 8) {
  2292. c += 16;
  2293. }
  2294. var r;
  2295. var n = "";
  2296. for (;;) {
  2297. r = a.getUint16(c, true);
  2298. c += 2;
  2299. if (0 == r) {
  2300. break;
  2301. }
  2302. n += String.fromCharCode(r);
  2303. }
  2304. r = n;
  2305. n = null;
  2306. if (D.hasOwnProperty(e)) {
  2307. n = D[e];
  2308. n.P();
  2309. n.s = n.x;
  2310. n.t = n.y;
  2311. n.r = n.size;
  2312. n.color = g;
  2313. } else {
  2314. n = new aa(e, p, h, d, g, r);
  2315. v.push(n);
  2316. D[e] = n;
  2317. n.sa = p;
  2318. n.ta = h;
  2319. }
  2320. n.h = q;
  2321. n.n = s;
  2322. n.J = p;
  2323. n.K = h;
  2324. n.q = d;
  2325. n.qa = b;
  2326. n.Q = A;
  2327. n.ba = k;
  2328. if (r) {
  2329. n.B(r);
  2330. }
  2331. if (-1 != K.indexOf(e)) {
  2332. if (-1 == m.indexOf(n)) {
  2333. document.getElementById("overlays").style.display = "none";
  2334. m.push(n);
  2335. if (1 == m.length) {
  2336. /*new*//*mikey*/OnGameStart(zeach.myPoints);
  2337. t = n.x;
  2338. u = n.y;
  2339. Za();
  2340. }
  2341. }
  2342. }
  2343. }
  2344. b = a.getUint32(c, true);
  2345. c += 4;
  2346. l = 0;
  2347. for (;l < b;l++) {
  2348. e = a.getUint32(c, true);
  2349. c += 4;
  2350. n = D[e];
  2351. if (null != n) {
  2352. n.X();
  2353. }
  2354. }
  2355. if (Ea) {
  2356. if (0 == m.length) {
  2357. Oa(false);
  2358. }
  2359. }
  2360. }
  2361. function U() {
  2362. /*new*/if(isGrazing){ doGrazing(); return; }
  2363. /*new*/if(suspendMouseUpdates){return;}
  2364. var a;
  2365. if (S()) {
  2366. a = ca - q / 2;
  2367. var c = da - s$$0 / 2;
  2368. if (!(64 > a * a + c * c)) {
  2369. if (!(0.01 > Math.abs($a - fa) && 0.01 > Math.abs(ab - ga))) {
  2370. $a = fa;
  2371. ab = ga;
  2372. a = L(13);
  2373. a.setUint8(0, 16);
  2374. a.setInt32(1, fa, true);
  2375. a.setInt32(5, ga, true);
  2376. a.setUint32(9, 0, true);
  2377. M(a);
  2378.  
  2379. }
  2380. }
  2381. }
  2382. }
  2383. function Ya() {
  2384. if (S() && null != I) {
  2385. var a = L(1 + 2 * I.length);
  2386. a.setUint8(0, 0);
  2387. var c = 0;
  2388. for (;c < I.length;++c) {
  2389. a.setUint16(1 + 2 * c, I.charCodeAt(c), true);
  2390. }
  2391. M(a);
  2392. }
  2393. }
  2394. function S() {
  2395. return null != r && r.readyState == r.OPEN;
  2396. }
  2397. function G(a) {
  2398. if (S()) {
  2399. var c = L(1);
  2400. c.setUint8(0, a);
  2401. M(c);
  2402. }
  2403. }
  2404. function Va() {
  2405. if (S() && null != B) {
  2406. var a = L(1 + B.length);
  2407. a.setUint8(0, 81);
  2408. var c = 0;
  2409. for (;c < B.length;++c) {
  2410. a.setUint8(c + 1, B.charCodeAt(c));
  2411. }
  2412. M(a);
  2413. }
  2414. }
  2415. function Pa() {
  2416. q = d.innerWidth;
  2417. s$$0 = d.innerHeight;
  2418. xa.width = F.width = q;
  2419. xa.height = F.height = s$$0;
  2420. var a = f("#helloContainer");
  2421. a.css("transform", "none");
  2422. var c = a.height();
  2423. var b = d.innerHeight;
  2424. if (c > b / 1.1) {
  2425. a.css("transform", "translate(-50%, -50%) scale(" + b / c / 1.1 + ")");
  2426. } else {
  2427. a.css("transform", "translate(-50%, -50%)");
  2428. }
  2429. bb();
  2430. }
  2431. function cb() {
  2432. var a;
  2433. a = 1 * Math.max(s$$0 / 1080, q / 1920);
  2434. return a *= H;
  2435. }
  2436. function tb() {
  2437. if (0 != m.length) {
  2438. var a = 0;
  2439. var c = 0;
  2440. for (;c < m.length;c++) {
  2441. a += m[c].size;
  2442. }
  2443. a = Math.pow(Math.min(64 / a, 1), 0.4) * cb();
  2444. //k = (9 * k + a) / 10;
  2445. /*new*//*remap*/k = (9 * k + a) / zoomFactor;
  2446. }
  2447. }
  2448. function bb() {
  2449. var a$$0;
  2450. var c$$0 = Date.now();
  2451. ++ub;
  2452. A = c$$0;
  2453. if (0 < m.length) {
  2454. tb();
  2455. var b = a$$0 = 0;
  2456. var e = 0;
  2457. for (;e < m.length;e++) {
  2458. m[e].P();
  2459. a$$0 += m[e].x / m.length;
  2460. b += m[e].y / m.length;
  2461. }
  2462. Y = a$$0;
  2463. Z = b;
  2464. $ = k;
  2465. t = (t + a$$0) / 2;
  2466. u = (u + b) / 2;
  2467. } else {
  2468. t = (29 * t + Y) / 30;
  2469. u = (29 * u + Z) / 30;
  2470. k = (9 * k + $ * cb()) / 10;
  2471. }
  2472. lb();
  2473. ya();
  2474. if (!Fa) {
  2475. g.clearRect(0, 0, q, s$$0);
  2476. }
  2477. if (Fa) {
  2478. g.fillStyle = sa ? "#111111" : "#F2FBFF";
  2479. g.globalAlpha = 0.05;
  2480. g.fillRect(0, 0, q, s$$0);
  2481. g.globalAlpha = 1;
  2482. } else {
  2483. vb();
  2484. }
  2485. v.sort(function(a, c) {
  2486. return a.size == c.size ? a.id - c.id : a.size - c.size;
  2487. });
  2488. g.save();
  2489. g.translate(q / 2, s$$0 / 2);
  2490. g.scale(k, k);
  2491. g.translate(-t, -u);
  2492. e = 0;
  2493. for (;e < P.length;e++) {
  2494. P[e].w(g);
  2495. }
  2496. e = 0;
  2497. for (;e < v.length;e++) {
  2498. v[e].w(g);
  2499. }
  2500. /*new*/drawRescaledItems(zeach.ctx);
  2501. if (Da) {
  2502. ma = (3 * ma + Ba) / 4;
  2503. na = (3 * na + Ca) / 4;
  2504. g.save();
  2505. g.strokeStyle = "#FFAAAA";
  2506. g.lineWidth = 10;
  2507. g.lineCap = "round";
  2508. g.lineJoin = "round";
  2509. g.globalAlpha = 0.5;
  2510. g.beginPath();
  2511. e = 0;
  2512. for (;e < m.length;e++) {
  2513. g.moveTo(m[e].x, m[e].y);
  2514. g.lineTo(ma, na);
  2515. }
  2516. g.stroke();
  2517. g.restore();
  2518. }
  2519. g.restore();
  2520. if (y) {
  2521. if (y.width) {
  2522. g.drawImage(y, q - y.width - 10, 10);
  2523. }
  2524. }
  2525. /*new*//*mikey*/OnDraw(zeach.ctx);
  2526. Q = Math.max(Q, wb());
  2527. /*new*//*remap*/ var extras = " " + getScoreBoardExtrasString(Q);
  2528. if (0 != Q) {
  2529. if (null == ta) {
  2530. ta = new ua(24, "#FFFFFF");
  2531. }
  2532. ta.C(X("score") + ": " + ~~(Q / 100));
  2533. /*new*/ /*remap*/ ta.setValue("Score: " + ~~(Q / 100) + extras);
  2534. b = ta.L();
  2535. a$$0 = b.width;
  2536. g.globalAlpha = 0.2;
  2537. g.fillStyle = "#000000";
  2538. g.fillRect(10, s$$0 - 10 - 24 - 10, a$$0 + 10, 34);
  2539. g.globalAlpha = 1;
  2540. g.drawImage(b, 15, s$$0 - 10 - 24 - 5);
  2541. /*new*//*mikey*//*remap*/(zeach.myPoints&&zeach.myPoints[0]&&OnUpdateMass(wb()));
  2542. }
  2543. xb();
  2544. c$$0 = Date.now() - c$$0;
  2545. if (c$$0 > 1E3 / 60) {
  2546. C -= 0.01;
  2547. } else {
  2548. if (c$$0 < 1E3 / 65) {
  2549. C += 0.01;
  2550. }
  2551. }
  2552. if (0.4 > C) {
  2553. C = 0.4;
  2554. }
  2555. if (1 < C) {
  2556. C = 1;
  2557. }
  2558. c$$0 = A - db;
  2559. if (!S() || V) {
  2560. w += c$$0 / 2E3;
  2561. if (1 < w) {
  2562. w = 1;
  2563. }
  2564. } else {
  2565. w -= c$$0 / 300;
  2566. if (0 > w) {
  2567. w = 0;
  2568. }
  2569. }
  2570. if (0 < w) {
  2571. g.fillStyle = "#000000";
  2572. g.globalAlpha = 0.5 * w;
  2573. g.fillRect(0, 0, q, s$$0);
  2574. g.globalAlpha = 1;
  2575. }
  2576. db = A;
  2577. /*new*/displayDebugText(zeach.ctx,zeach.textFunc);
  2578. }
  2579. function vb() {
  2580. g.fillStyle = sa ? "#111111" : "#F2FBFF";
  2581. g.fillRect(0, 0, q, s$$0);
  2582. /*new*/if(!cobbler.gridLines){return;}
  2583. g.save();
  2584. g.strokeStyle = sa ? "#AAAAAA" : "#000000";
  2585. g.globalAlpha = 0.2 * k;
  2586. var a = q / k;
  2587. var c = s$$0 / k;
  2588. var b = (-t + a / 2) % 50;
  2589. for (;b < a;b += 50) {
  2590. g.beginPath();
  2591. g.moveTo(b * k - 0.5, 0);
  2592. g.lineTo(b * k - 0.5, c * k);
  2593. g.stroke();
  2594. }
  2595. b = (-u + c / 2) % 50;
  2596. for (;b < c;b += 50) {
  2597. g.beginPath();
  2598. g.moveTo(0, b * k - 0.5);
  2599. g.lineTo(a * k, b * k - 0.5);
  2600. g.stroke();
  2601. }
  2602. g.restore();
  2603. }
  2604. function xb() {
  2605. if (Ma && Ga.width) {
  2606. var a = q / 5;
  2607. g.drawImage(Ga, 5, 5, a, a);
  2608. }
  2609. }
  2610. function wb() {
  2611. var a = 0;
  2612. var c = 0;
  2613. for (;c < m.length;c++) {
  2614. a += m[c].q * m[c].q;
  2615. }
  2616. return a;
  2617. }
  2618. function Wa() {
  2619. y = null;
  2620. if (null != z || 0 != E.length) {
  2621. if (null != z || va) {
  2622. y = document.createElement("canvas");
  2623. var a = y.getContext("2d");
  2624. var c = 60;
  2625. c = null == z ? c + 24 * E.length : c + 180;
  2626. var b = Math.min(200, 0.3 * q) / 200;
  2627. y.width = 200 * b;
  2628. y.height = c * b;
  2629. a.scale(b, b);
  2630. a.globalAlpha = 0.4;
  2631. a.fillStyle = "#000000";
  2632. a.fillRect(0, 0, 200, c);
  2633. a.globalAlpha = 1;
  2634. a.fillStyle = "#FFFFFF";
  2635. b = null;
  2636. b = X("leaderboard");
  2637. a.font = "30px Ubuntu";
  2638. a.fillText(b, 100 - a.measureText(b).width / 2, 40);
  2639. if (null == z) {
  2640. a.font = "20px Ubuntu";
  2641. c = 0;
  2642. for (;c < E.length;++c) {
  2643. b = E[c].name || X("unnamed_cell");
  2644. if (!va) {
  2645. b = X("unnamed_cell");
  2646. }
  2647. if (-1 != K.indexOf(E[c].id)) {
  2648. if (m[0].name) {
  2649. b = m[0].name;
  2650. }
  2651. a.fillStyle = "#FFAAAA";
  2652. /*new*//*mikey*//*remap*/OnLeaderboard(c+1);
  2653. } else {
  2654. a.fillStyle = "#FFFFFF";
  2655. }
  2656. b = c + 1 + ". " + b;
  2657. a.fillText(b, 100 - a.measureText(b).width / 2, 70 + 24 * c);
  2658. }
  2659. } else {
  2660. c = b = 0;
  2661. for (;c < z.length;++c) {
  2662. var e = b + z[c] * Math.PI * 2;
  2663. a.fillStyle = yb[c + 1];
  2664. a.beginPath();
  2665. a.moveTo(100, 140);
  2666. a.arc(100, 140, 80, b, e, false);
  2667. a.fill();
  2668. b = e;
  2669. }
  2670. }
  2671. }
  2672. }
  2673. }
  2674. function Ha(a, c, b, e, l) {
  2675. this.V = a;
  2676. this.x = c;
  2677. this.y = b;
  2678. this.i = e;
  2679. this.b = l;
  2680. }
  2681. function aa(a, c, b, e, l, p) {
  2682. this.id = a;
  2683. this.s = this.x = c;
  2684. this.t = this.y = b;
  2685. this.r = this.size = e;
  2686. this.color = l;
  2687. this.a = [];
  2688. this.W();
  2689. this.B(p);
  2690. /*new*/this.splitTime = Date.now();
  2691. }
  2692. function ua(a, c, b, e) {
  2693. if (a) {
  2694. this.u = a;
  2695. }
  2696. if (c) {
  2697. this.S = c;
  2698. }
  2699. this.U = !!b;
  2700. if (e) {
  2701. this.v = e;
  2702. }
  2703. }
  2704. function R(a, c) {
  2705. var b$$0 = "1" == f("#helloContainer").attr("data-has-account-data");
  2706. /*new*/var b$$0 = "1" == f("#ZCOverlay").attr("data-has-account-data");
  2707.  
  2708. f("#helloContainer").attr("data-has-account-data", "1");
  2709. if (null == c && d.localStorage.loginCache) {
  2710. var e = JSON.parse(d.localStorage.loginCache);
  2711. e.f = a.f;
  2712. e.d = a.d;
  2713. e.e = a.e;
  2714. d.localStorage.loginCache = JSON.stringify(e);
  2715. }
  2716. if (b$$0) {
  2717. var l = +f(".agario-exp-bar .progress-bar-text").text().split("/")[0];
  2718. b$$0 = +f(".agario-exp-bar .progress-bar-text").text().split("/")[1].split(" ")[0];
  2719. e = f(".agario-profile-panel .progress-bar-star").text();
  2720. if (e != a.e) {
  2721. R({
  2722. f : b$$0,
  2723. d : b$$0,
  2724. e : e
  2725. }, function() {
  2726. f(".agario-profile-panel .progress-bar-star").text(a.e);
  2727. f(".agario-exp-bar .progress-bar").css("width", "100%");
  2728. f(".progress-bar-star").addClass("animated tada").one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend", function() {
  2729. f(".progress-bar-star").removeClass("animated tada");
  2730. });
  2731. setTimeout(function() {
  2732. f(".agario-exp-bar .progress-bar-text").text(a.d + "/" + a.d + " XP");
  2733. R({
  2734. f : 0,
  2735. d : a.d,
  2736. e : a.e
  2737. }, function() {
  2738. R(a, c);
  2739. });
  2740. }, 1E3);
  2741. });
  2742. } else {
  2743. var p = Date.now();
  2744. var h = function() {
  2745. var b;
  2746. b = (Date.now() - p) / 1E3;
  2747. b = 0 > b ? 0 : 1 < b ? 1 : b;
  2748. b = b * b * (3 - 2 * b);
  2749. f(".agario-exp-bar .progress-bar-text").text(~~(l + (a.f - l) * b) + "/" + a.d + " XP");
  2750. f(".agario-exp-bar .progress-bar").css("width", (88 * (l + (a.f - l) * b) / a.d).toFixed(2) + "%");
  2751. if (1 > b) {
  2752. d.requestAnimationFrame(h);
  2753. } else {
  2754. if (c) {
  2755. c();
  2756. }
  2757. }
  2758. };
  2759. d.requestAnimationFrame(h);
  2760. }
  2761. } else {
  2762. f(".agario-profile-panel .progress-bar-star").text(a.e);
  2763. f(".agario-exp-bar .progress-bar-text").text(a.f + "/" + a.d + " XP");
  2764. f(".agario-exp-bar .progress-bar").css("width", (88 * a.f / a.d).toFixed(2) + "%");
  2765. if (c) {
  2766. c();
  2767. }
  2768. }
  2769. }
  2770. function eb(a) {
  2771. if ("string" == typeof a) {
  2772. a = JSON.parse(a);
  2773. }
  2774. if (Date.now() + 18E5 > a.ia) {
  2775. f("#helloContainer").attr("data-logged-in", "0");
  2776. } else {
  2777. d.localStorage.loginCache = JSON.stringify(a);
  2778. B = a.fa;
  2779. f(".agario-profile-name").text(a.name);
  2780. Va();
  2781. R({
  2782. f : a.f,
  2783. d : a.d,
  2784. e : a.e
  2785. });
  2786. f("#helloContainer").attr("data-logged-in", "1");
  2787. }
  2788. }
  2789. function zb(a) {
  2790. a = a.split("\n");
  2791. eb({
  2792. name : a[0],
  2793. ra : a[1],
  2794. fa : a[2],
  2795. ia : 1E3 * +a[3],
  2796. e : +a[4],
  2797. f : +a[5],
  2798. d : +a[6]
  2799. });
  2800. }
  2801. function Ia(a$$0) {
  2802. if ("connected" == a$$0.status) {
  2803. var c = a$$0.authResponse.accessToken;
  2804. d.FB.api("/me/picture?width=180&height=180", function(a) {
  2805. d.localStorage.fbPictureCache = a.data.url;
  2806. f(".agario-profile-picture").attr("src", a.data.url);
  2807. });
  2808. f("#helloContainer").attr("data-logged-in", "1");
  2809. if (null != B) {
  2810. f.ajax("https://m.agar.io/checkToken", {
  2811. error : function() {
  2812. B = null;
  2813. Ia(a$$0);
  2814. },
  2815. success : function(a) {
  2816. a = a.split("\n");
  2817. R({
  2818. e : +a[0],
  2819. f : +a[1],
  2820. d : +a[2]
  2821. });
  2822. },
  2823. dataType : "text",
  2824. method : "POST",
  2825. cache : false,
  2826. crossDomain : true,
  2827. data : B
  2828. });
  2829. } else {
  2830. f.ajax("https://m.agar.io/facebookLogin", {
  2831. error : function() {
  2832. B = null;
  2833. f("#helloContainer").attr("data-logged-in", "0");
  2834. },
  2835. success : zb,
  2836. dataType : "text",
  2837. method : "POST",
  2838. cache : false,
  2839. crossDomain : true,
  2840. data : c
  2841. });
  2842. }
  2843. }
  2844. }
  2845. if (!d.agarioNoInit) {
  2846. var Ja = d.location.protocol;
  2847. var ob = "https:" == Ja;
  2848. var xa;
  2849. var g;
  2850. var F;
  2851. var q;
  2852. var s$$0;
  2853. var W = null;
  2854. var r = null;
  2855. var t = 0;
  2856. var u = 0;
  2857. var K = [];
  2858. var m = [];
  2859. var D = {};
  2860. var v = [];
  2861. var P = [];
  2862. var E = [];
  2863. var ca = 0;
  2864. var da = 0;
  2865. var fa = -1;
  2866. var ga = -1;
  2867. var ub = 0;
  2868. var A = 0;
  2869. var db = 0;
  2870. var I = null;
  2871. var oa = 0;
  2872. var pa = 0;
  2873. var qa = 1E4;
  2874. var ra = 1E4;
  2875. var k = 1;
  2876. var x = null;
  2877. var fb = true;
  2878. var va = true;
  2879. var Ka = false;
  2880. var Ea = false;
  2881. var Q = 0;
  2882. var sa = false;
  2883. var gb = false;
  2884. var Y = t = ~~((oa + qa) / 2);
  2885. var Z = u = ~~((pa + ra) / 2);
  2886. var $ = 1;
  2887. var O = "";
  2888. var z = null;
  2889. var wa = false;
  2890. var Da = false;
  2891. var Ba = 0;
  2892. var Ca = 0;
  2893. var ma = 0;
  2894. var na = 0;
  2895. var hb = 0;
  2896. var yb = ["#333333", "#FF3333", "#33FF33", "#3333FF"];
  2897. var Fa = false;
  2898. var ka = false;
  2899. var Xa = 0;
  2900. var B = null;
  2901. var H = 1;
  2902. var w = 1;
  2903. var V = true;
  2904. var za = 0;
  2905. var Ma = "ontouchstart" in d && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  2906. var Ga = new Image;
  2907. Ga.src = "img/split.png";
  2908. var ib = document.createElement("canvas");
  2909. if ("undefined" == typeof console || ("undefined" == typeof DataView || ("undefined" == typeof WebSocket || (null == ib || (null == ib.getContext || null == d.localStorage))))) {
  2910. alert("You browser does not support this game, we recommend you to use Firefox to play this");
  2911. } else {
  2912.  
  2913. var ha = null;
  2914. d.setNick = function(a) {
  2915. Sa();
  2916. I = a;
  2917. Ya();
  2918. Q = 0;
  2919. /*new*/GM_setValue("nick", a);
  2920. /*new*/console.log("Storing '" + a + "' as nick");
  2921. };
  2922. d.setRegion = ea;
  2923. d.setSkins = function(a) {
  2924. fb = a;
  2925. };
  2926. d.setNames = function(a) {
  2927. va = a;
  2928. };
  2929. d.setDarkTheme = function(a) {
  2930. sa = a;
  2931. };
  2932. d.setColors = function(a) {
  2933. Ka = a;
  2934. };
  2935. d.setShowMass = function(a) {
  2936. gb = a;
  2937. };
  2938. d.spectate = function() {
  2939. I = null;
  2940. G(1);
  2941. Sa();
  2942. };
  2943. d.setGameMode = function(a) {
  2944. if (a != O) {
  2945. if (":party" == O) {
  2946. f("#helloContainer").attr("data-party-state", "0");
  2947. }
  2948. ia(a);
  2949. if (":party" != a) {
  2950. N();
  2951. }
  2952. }
  2953. };
  2954. d.setAcid = function(a) {
  2955. Fa = a;
  2956. };
  2957. if (null != d.localStorage) {
  2958. if (null == d.localStorage.AB9) {
  2959. d.localStorage.AB9 = 0 + ~~(100 * Math.random());
  2960. }
  2961. hb = +d.localStorage.AB9;
  2962. d.ABGroup = hb;
  2963. }
  2964. f.get(Ja + "//gc.agar.io", function(a) {
  2965. var c = a.split(" ");
  2966. a = c[0];
  2967. c = c[1] || "";
  2968. if (-1 == ["UA"].indexOf(a)) {
  2969. jb.push("ussr");
  2970. }
  2971. if (-1 != d.navigator.userAgent.indexOf("Android")) {
  2972. d.location.href = "market://details?id=com.miniclip.agar.io";
  2973. }
  2974. if (-1 != d.navigator.userAgent.indexOf("iPhone") || (-1 != d.navigator.userAgent.indexOf("iPad") || -1 != d.navigator.userAgent.indexOf("iPod"))) {
  2975. d.location.href = "https://itunes.apple.com/app/agar.io/id995999703";
  2976. }
  2977. if (ba.hasOwnProperty(a)) {
  2978. if ("string" == typeof ba[a]) {
  2979. if (!x) {
  2980. ea(ba[a]);
  2981. }
  2982. } else {
  2983. if (ba[a].hasOwnProperty(c)) {
  2984. if (!x) {
  2985. ea(ba[a][c]);
  2986. }
  2987. }
  2988. }
  2989. }
  2990. }, "text");
  2991. var ja = false;
  2992. var Ta = 0;
  2993. setTimeout(function() {
  2994. ja = true;
  2995. }, Math.max(6E4 * Ta, 1E4));
  2996. var ba = {
  2997. AF : "JP-Tokyo",
  2998. AX : "EU-London",
  2999. AL : "EU-London",
  3000. DZ : "EU-London",
  3001. AS : "SG-Singapore",
  3002. AD : "EU-London",
  3003. AO : "EU-London",
  3004. AI : "US-Atlanta",
  3005. AG : "US-Atlanta",
  3006. AR : "BR-Brazil",
  3007. AM : "JP-Tokyo",
  3008. AW : "US-Atlanta",
  3009. AU : "SG-Singapore",
  3010. AT : "EU-London",
  3011. AZ : "JP-Tokyo",
  3012. BS : "US-Atlanta",
  3013. BH : "JP-Tokyo",
  3014. BD : "JP-Tokyo",
  3015. BB : "US-Atlanta",
  3016. BY : "EU-London",
  3017. BE : "EU-London",
  3018. BZ : "US-Atlanta",
  3019. BJ : "EU-London",
  3020. BM : "US-Atlanta",
  3021. BT : "JP-Tokyo",
  3022. BO : "BR-Brazil",
  3023. BQ : "US-Atlanta",
  3024. BA : "EU-London",
  3025. BW : "EU-London",
  3026. BR : "BR-Brazil",
  3027. IO : "JP-Tokyo",
  3028. VG : "US-Atlanta",
  3029. BN : "JP-Tokyo",
  3030. BG : "EU-London",
  3031. BF : "EU-London",
  3032. BI : "EU-London",
  3033. KH : "JP-Tokyo",
  3034. CM : "EU-London",
  3035. CA : "US-Atlanta",
  3036. CV : "EU-London",
  3037. KY : "US-Atlanta",
  3038. CF : "EU-London",
  3039. TD : "EU-London",
  3040. CL : "BR-Brazil",
  3041. CN : "CN-China",
  3042. CX : "JP-Tokyo",
  3043. CC : "JP-Tokyo",
  3044. CO : "BR-Brazil",
  3045. KM : "EU-London",
  3046. CD : "EU-London",
  3047. CG : "EU-London",
  3048. CK : "SG-Singapore",
  3049. CR : "US-Atlanta",
  3050. CI : "EU-London",
  3051. HR : "EU-London",
  3052. CU : "US-Atlanta",
  3053. CW : "US-Atlanta",
  3054. CY : "JP-Tokyo",
  3055. CZ : "EU-London",
  3056. DK : "EU-London",
  3057. DJ : "EU-London",
  3058. DM : "US-Atlanta",
  3059. DO : "US-Atlanta",
  3060. EC : "BR-Brazil",
  3061. EG : "EU-London",
  3062. SV : "US-Atlanta",
  3063. GQ : "EU-London",
  3064. ER : "EU-London",
  3065. EE : "EU-London",
  3066. ET : "EU-London",
  3067. FO : "EU-London",
  3068. FK : "BR-Brazil",
  3069. FJ : "SG-Singapore",
  3070. FI : "EU-London",
  3071. FR : "EU-London",
  3072. GF : "BR-Brazil",
  3073. PF : "SG-Singapore",
  3074. GA : "EU-London",
  3075. GM : "EU-London",
  3076. GE : "JP-Tokyo",
  3077. DE : "EU-London",
  3078. GH : "EU-London",
  3079. GI : "EU-London",
  3080. GR : "EU-London",
  3081. GL : "US-Atlanta",
  3082. GD : "US-Atlanta",
  3083. GP : "US-Atlanta",
  3084. GU : "SG-Singapore",
  3085. GT : "US-Atlanta",
  3086. GG : "EU-London",
  3087. GN : "EU-London",
  3088. GW : "EU-London",
  3089. GY : "BR-Brazil",
  3090. HT : "US-Atlanta",
  3091. VA : "EU-London",
  3092. HN : "US-Atlanta",
  3093. HK : "JP-Tokyo",
  3094. HU : "EU-London",
  3095. IS : "EU-London",
  3096. IN : "JP-Tokyo",
  3097. ID : "JP-Tokyo",
  3098. IR : "JP-Tokyo",
  3099. IQ : "JP-Tokyo",
  3100. IE : "EU-London",
  3101. IM : "EU-London",
  3102. IL : "JP-Tokyo",
  3103. IT : "EU-London",
  3104. JM : "US-Atlanta",
  3105. JP : "JP-Tokyo",
  3106. JE : "EU-London",
  3107. JO : "JP-Tokyo",
  3108. KZ : "JP-Tokyo",
  3109. KE : "EU-London",
  3110. KI : "SG-Singapore",
  3111. KP : "JP-Tokyo",
  3112. KR : "JP-Tokyo",
  3113. KW : "JP-Tokyo",
  3114. KG : "JP-Tokyo",
  3115. LA : "JP-Tokyo",
  3116. LV : "EU-London",
  3117. LB : "JP-Tokyo",
  3118. LS : "EU-London",
  3119. LR : "EU-London",
  3120. LY : "EU-London",
  3121. LI : "EU-London",
  3122. LT : "EU-London",
  3123. LU : "EU-London",
  3124. MO : "JP-Tokyo",
  3125. MK : "EU-London",
  3126. MG : "EU-London",
  3127. MW : "EU-London",
  3128. MY : "JP-Tokyo",
  3129. MV : "JP-Tokyo",
  3130. ML : "EU-London",
  3131. MT : "EU-London",
  3132. MH : "SG-Singapore",
  3133. MQ : "US-Atlanta",
  3134. MR : "EU-London",
  3135. MU : "EU-London",
  3136. YT : "EU-London",
  3137. MX : "US-Atlanta",
  3138. FM : "SG-Singapore",
  3139. MD : "EU-London",
  3140. MC : "EU-London",
  3141. MN : "JP-Tokyo",
  3142. ME : "EU-London",
  3143. MS : "US-Atlanta",
  3144. MA : "EU-London",
  3145. MZ : "EU-London",
  3146. MM : "JP-Tokyo",
  3147. NA : "EU-London",
  3148. NR : "SG-Singapore",
  3149. NP : "JP-Tokyo",
  3150. NL : "EU-London",
  3151. NC : "SG-Singapore",
  3152. NZ : "SG-Singapore",
  3153. NI : "US-Atlanta",
  3154. NE : "EU-London",
  3155. NG : "EU-London",
  3156. NU : "SG-Singapore",
  3157. NF : "SG-Singapore",
  3158. MP : "SG-Singapore",
  3159. NO : "EU-London",
  3160. OM : "JP-Tokyo",
  3161. PK : "JP-Tokyo",
  3162. PW : "SG-Singapore",
  3163. PS : "JP-Tokyo",
  3164. PA : "US-Atlanta",
  3165. PG : "SG-Singapore",
  3166. PY : "BR-Brazil",
  3167. PE : "BR-Brazil",
  3168. PH : "JP-Tokyo",
  3169. PN : "SG-Singapore",
  3170. PL : "EU-London",
  3171. PT : "EU-London",
  3172. PR : "US-Atlanta",
  3173. QA : "JP-Tokyo",
  3174. RE : "EU-London",
  3175. RO : "EU-London",
  3176. RU : "RU-Russia",
  3177. RW : "EU-London",
  3178. BL : "US-Atlanta",
  3179. SH : "EU-London",
  3180. KN : "US-Atlanta",
  3181. LC : "US-Atlanta",
  3182. MF : "US-Atlanta",
  3183. PM : "US-Atlanta",
  3184. VC : "US-Atlanta",
  3185. WS : "SG-Singapore",
  3186. SM : "EU-London",
  3187. ST : "EU-London",
  3188. SA : "EU-London",
  3189. SN : "EU-London",
  3190. RS : "EU-London",
  3191. SC : "EU-London",
  3192. SL : "EU-London",
  3193. SG : "JP-Tokyo",
  3194. SX : "US-Atlanta",
  3195. SK : "EU-London",
  3196. SI : "EU-London",
  3197. SB : "SG-Singapore",
  3198. SO : "EU-London",
  3199. ZA : "EU-London",
  3200. SS : "EU-London",
  3201. ES : "EU-London",
  3202. LK : "JP-Tokyo",
  3203. SD : "EU-London",
  3204. SR : "BR-Brazil",
  3205. SJ : "EU-London",
  3206. SZ : "EU-London",
  3207. SE : "EU-London",
  3208. CH : "EU-London",
  3209. SY : "EU-London",
  3210. TW : "JP-Tokyo",
  3211. TJ : "JP-Tokyo",
  3212. TZ : "EU-London",
  3213. TH : "JP-Tokyo",
  3214. TL : "JP-Tokyo",
  3215. TG : "EU-London",
  3216. TK : "SG-Singapore",
  3217. TO : "SG-Singapore",
  3218. TT : "US-Atlanta",
  3219. TN : "EU-London",
  3220. TR : "TK-Turkey",
  3221. TM : "JP-Tokyo",
  3222. TC : "US-Atlanta",
  3223. TV : "SG-Singapore",
  3224. UG : "EU-London",
  3225. UA : "EU-London",
  3226. AE : "EU-London",
  3227. GB : "EU-London",
  3228. US : "US-Atlanta",
  3229. UM : "SG-Singapore",
  3230. VI : "US-Atlanta",
  3231. UY : "BR-Brazil",
  3232. UZ : "JP-Tokyo",
  3233. VU : "SG-Singapore",
  3234. VE : "BR-Brazil",
  3235. VN : "JP-Tokyo",
  3236. WF : "SG-Singapore",
  3237. EH : "EU-London",
  3238. YE : "JP-Tokyo",
  3239. ZM : "EU-London",
  3240. ZW : "EU-London"
  3241. };
  3242. /*new*/// Hack to kill an established websocket
  3243. /*new*//*remap*/d.connect2 = d.connect;d.connect = zeach.connect;setTimeout(function(){try {d.connect2("Killing_original_websocket","");}catch(err){}} ,1500);
  3244.  
  3245. var J = null;
  3246. d.connect = Aa;
  3247. var la = 500;
  3248. var $a = -1;
  3249. var ab = -1;
  3250. var y = null;
  3251. var C = 1;
  3252. var ta = null;
  3253. var Qa = function() {
  3254. var a = Date.now();
  3255. var c = 1E3 / 60;
  3256. return function() {
  3257. d.requestAnimationFrame(Qa);
  3258. var b = Date.now();
  3259. var e = b - a;
  3260. if (e > c) {
  3261. a = b - e % c;
  3262. if (!S() || 240 > Date.now() - Xa) {
  3263. bb();
  3264. } else {
  3265. /*new*///console.warn("Skipping draw");
  3266. }
  3267. Ab();
  3268. }
  3269. };
  3270. }();
  3271. var T = {};
  3272. var jb = "poland;usa;china;russia;canada;australia;spain;brazil;germany;ukraine;france;sweden;chaplin;north korea;south korea;japan;united kingdom;earth;greece;latvia;lithuania;estonia;finland;norway;cia;maldivas;austria;nigeria;reddit;yaranaika;confederate;9gag;indiana;4chan;italy;bulgaria;tumblr;2ch.hk;hong kong;portugal;jamaica;german empire;mexico;sanik;switzerland;croatia;chile;indonesia;bangladesh;thailand;iran;iraq;peru;moon;botswana;bosnia;netherlands;european union;taiwan;pakistan;hungary;satanist;qing dynasty;matriarchy;patriarchy;feminism;ireland;texas;facepunch;prodota;cambodia;steam;piccolo;ea;india;kc;denmark;quebec;ayy lmao;sealand;bait;tsarist russia;origin;vinesauce;stalin;belgium;luxembourg;stussy;prussia;8ch;argentina;scotland;sir;romania;belarus;wojak;doge;nasa;byzantium;imperial japan;french kingdom;somalia;turkey;mars;pokerface;8;irs;receita federal;facebook".split(";");
  3273. var Bb = ["8", "nasa"];
  3274. var Cb = ["m'blob"];
  3275. Ha.prototype = {
  3276. V : null,
  3277. x : 0,
  3278. y : 0,
  3279. i : 0,
  3280. b : 0
  3281. };
  3282. aa.prototype = {
  3283. /*new*/ locked : false,
  3284. id : 0,
  3285. a : null,
  3286. name : null,
  3287. o : null,
  3288. O : null,
  3289. x : 0,
  3290. y : 0,
  3291. size : 0,
  3292. s : 0,
  3293. t : 0,
  3294. r : 0,
  3295. J : 0,
  3296. K : 0,
  3297. q : 0,
  3298. ba : 0,
  3299. Q : 0,
  3300. qa : 0,
  3301. ha : 0,
  3302. G : false,
  3303. h : false,
  3304. n : false,
  3305. R : true,
  3306. Y : 0,
  3307. X : function() {
  3308. var a;
  3309. a = 0;
  3310. for (;a < v.length;a++) {
  3311. if (v[a] == this) {
  3312. v.splice(a, 1);
  3313. break;
  3314. }
  3315. }
  3316. delete D[this.id];
  3317. a = m.indexOf(this);
  3318. if (-1 != a) {
  3319. Ea = true;
  3320. m.splice(a, 1);
  3321. }
  3322. a = K.indexOf(this.id);
  3323. if (-1 != a) {
  3324. K.splice(a, 1);
  3325. }
  3326. this.G = true;
  3327. if (0 < this.Y) {
  3328. P.push(this);
  3329. }
  3330. },
  3331. l : function() {
  3332. return Math.max(~~(0.3 * this.size), 24);
  3333. },
  3334. B : function(a) {
  3335. if (this.name = a) {
  3336. if (null == this.o) {
  3337. this.o = new ua(this.l(), "#FFFFFF", true, "#000000");
  3338. } else {
  3339. this.o.M(this.l());
  3340. }
  3341. this.o.C(this.name);
  3342. }
  3343. },
  3344. W : function() {
  3345. var a = this.I();
  3346. for (;this.a.length > a;) {
  3347. var c = ~~(Math.random() * this.a.length);
  3348. this.a.splice(c, 1);
  3349. }
  3350. if (0 == this.a.length) {
  3351. if (0 < a) {
  3352. this.a.push(new Ha(this, this.x, this.y, this.size, Math.random() - 0.5));
  3353. }
  3354. }
  3355. for (;this.a.length < a;) {
  3356. c = ~~(Math.random() * this.a.length);
  3357. c = this.a[c];
  3358. this.a.push(new Ha(this, c.x, c.y, c.i, c.b));
  3359. }
  3360. },
  3361. I : function() {
  3362. var a = 10;
  3363. if (20 > this.size) {
  3364. a = 0;
  3365. }
  3366. if (this.h) {
  3367. a = 30;
  3368. }
  3369. var c = this.size;
  3370. if (!this.h) {
  3371. c *= k;
  3372. }
  3373. c *= C;
  3374. if (this.ba & 32) {
  3375. c *= 0.25;
  3376. }
  3377. return~~Math.max(c, a);
  3378. },
  3379. oa : function() {
  3380. this.W();
  3381. var a$$0 = this.a;
  3382. var c = a$$0.length;
  3383. var b = 0;
  3384. for (;b < c;++b) {
  3385. var e = a$$0[(b - 1 + c) % c].b;
  3386. var l = a$$0[(b + 1) % c].b;
  3387. a$$0[b].b += (Math.random() - 0.5) * (this.n ? 3 : 1);
  3388. a$$0[b].b *= 0.7;
  3389. if (10 < a$$0[b].b) {
  3390. a$$0[b].b = 10;
  3391. }
  3392. if (-10 > a$$0[b].b) {
  3393. a$$0[b].b = -10;
  3394. }
  3395. a$$0[b].b = (e + l + 8 * a$$0[b].b) / 10;
  3396. }
  3397. var p = this;
  3398. var h = this.h ? 0 : (this.id / 1E3 + A / 1E4) % (2 * Math.PI);
  3399. b = 0;
  3400. for (;b < c;++b) {
  3401. var d = a$$0[b].i;
  3402. e = a$$0[(b - 1 + c) % c].i;
  3403. l = a$$0[(b + 1) % c].i;
  3404. if (15 < this.size && (null != W && (20 < this.size * k && 0 < this.id))) {
  3405. var f = false;
  3406. var g = a$$0[b].x;
  3407. var m = a$$0[b].y;
  3408. W.pa(g - 5, m - 5, 10, 10, function(a) {
  3409. if (a.V != p) {
  3410. if (25 > (g - a.x) * (g - a.x) + (m - a.y) * (m - a.y)) {
  3411. f = true;
  3412. }
  3413. }
  3414. });
  3415. if (!f) {
  3416. if (a$$0[b].x < oa || (a$$0[b].y < pa || (a$$0[b].x > qa || a$$0[b].y > ra))) {
  3417. f = true;
  3418. }
  3419. }
  3420. if (f) {
  3421. if (0 < a$$0[b].b) {
  3422. a$$0[b].b = 0;
  3423. }
  3424. a$$0[b].b -= 1;
  3425. }
  3426. }
  3427. d += a$$0[b].b;
  3428. if (0 > d) {
  3429. d = 0;
  3430. }
  3431. d = this.n ? (19 * d + this.size) / 20 : (12 * d + this.size) / 13;
  3432. a$$0[b].i = (e + l + 8 * d) / 10;
  3433. e = 2 * Math.PI / c;
  3434. l = this.a[b].i;
  3435. if (this.h) {
  3436. if (0 == b % 2) {
  3437. l += 5;
  3438. }
  3439. }
  3440. a$$0[b].x = this.x + Math.cos(e * b + h) * l;
  3441. a$$0[b].y = this.y + Math.sin(e * b + h) * l;
  3442. }
  3443. },
  3444. P : function() {
  3445. if (0 >= this.id) {
  3446. return 1;
  3447. }
  3448. var a;
  3449. a = (A - this.Q) / 120;
  3450. a = 0 > a ? 0 : 1 < a ? 1 : a;
  3451. var c = 0 > a ? 0 : 1 < a ? 1 : a;
  3452. this.l();
  3453. if (this.G && 1 <= c) {
  3454. var b = P.indexOf(this);
  3455. if (-1 != b) {
  3456. P.splice(b, 1);
  3457. }
  3458. }
  3459. this.x = a * (this.J - this.s) + this.s;
  3460. this.y = a * (this.K - this.t) + this.t;
  3461. this.size = c * (this.q - this.r) + this.r;
  3462. return c;
  3463. },
  3464. N : function() {
  3465. return 0 >= this.id ? true : this.x + this.size + 40 < t - q / 2 / k || (this.y + this.size + 40 < u - s$$0 / 2 / k || (this.x - this.size - 40 > t + q / 2 / k || this.y - this.size - 40 > u + s$$0 / 2 / k)) ? false : true;
  3466. },
  3467. w : function(a) {
  3468. if (this.N()) {
  3469. ++this.Y;
  3470. var c = 0 < this.id && (!this.h && (!this.n && 0.4 > k));
  3471. if (5 > this.I()) {
  3472. c = true;
  3473. }
  3474. if (this.R && !c) {
  3475. var b = 0;
  3476. for (;b < this.a.length;b++) {
  3477. this.a[b].i = this.size;
  3478. }
  3479. }
  3480. this.R = c;
  3481. a.save();
  3482. this.ha = A;
  3483. b = this.P();
  3484. if (this.G) {
  3485. a.globalAlpha *= 1 - b;
  3486. }
  3487. a.lineWidth = 10;
  3488. a.lineCap = "round";
  3489. a.lineJoin = this.h ? "miter" : "round";
  3490. if (Ka) {
  3491. a.fillStyle = "#FFFFFF";
  3492. a.strokeStyle = "#AAAAAA";
  3493. } else {
  3494. a.fillStyle = this.color;
  3495. a.strokeStyle = this.color;
  3496. }
  3497. /*new*/drawCellInfos.call(this, zeach.isColors, zeach.ctx);
  3498. if (c) {
  3499. a.beginPath();
  3500. a.arc(this.x, this.y, this.size + 5, 0, 2 * Math.PI, false);
  3501. } else {
  3502. this.oa();
  3503. a.beginPath();
  3504. var e = this.I();
  3505. a.moveTo(this.a[0].x, this.a[0].y);
  3506. b = 1;
  3507. for (;b <= e;++b) {
  3508. var d = b % e;
  3509. a.lineTo(this.a[d].x, this.a[d].y);
  3510. }
  3511. }
  3512. a.closePath();
  3513. e = this.name.toLowerCase();
  3514. //if (!this.n && (fb && ":teams" != O)) {
  3515. // if (-1 != jb.indexOf(e)) {
  3516. // if (!T.hasOwnProperty(e)) {
  3517. // T[e] = new Image;
  3518. // T[e].src = "skins/" + e + ".png";
  3519. // }
  3520. // b = 0 != T[e].width && T[e].complete ? T[e] : null;
  3521. // } else {
  3522. // b = null;
  3523. // }
  3524. //} else {
  3525. // b = null;
  3526. //}
  3527. /*new*//*remap*/var b = customSkins(this, zeach.defaultSkins, zeach.imgCache, zeach.isShowSkins, zeach.gameMode);
  3528. b = (d = b) ? -1 != Cb.indexOf(e) : false;
  3529. /*new*///if (!c) {
  3530. a.stroke();
  3531. /*new*///}}
  3532. /*new*/if(!cobbler.isLiteBrite)
  3533. a.fill();
  3534.  
  3535. if (!(null == d)) {
  3536. if (!b) {
  3537. a.save();
  3538. /*new*/zeach.ctx.globalAlpha = (isSpecialSkin(this.name.toLowerCase()) || _.contains(zeach.myIDs, this.id)) ? 1 : 0.5;
  3539. a.clip();
  3540. a.drawImage(d, this.x - this.size, this.y - this.size, 2 * this.size, 2 * this.size);
  3541. a.restore();
  3542. }
  3543. }
  3544. if (Ka || 15 < this.size) {
  3545. if (!c) {
  3546. a.strokeStyle = "#000000";
  3547. a.globalAlpha *= 0.1;
  3548. a.stroke();
  3549. }
  3550. }
  3551. a.globalAlpha = 1;
  3552. if (null != d) {
  3553. if (b) {
  3554. a.drawImage(d, this.x - 2 * this.size, this.y - 2 * this.size, 4 * this.size, 4 * this.size);
  3555. }
  3556. }
  3557. b = -1 != m.indexOf(this);
  3558. c = ~~this.y;
  3559. //if (0 != this.id && ((va || b) && (this.name && (this.o && (null == d || -1 == Bb.indexOf(e)))))) {
  3560. // d = this.o;
  3561. // d.C(this.name);
  3562. // d.M(this.l());
  3563. // e = 0 >= this.id ? 1 : Math.ceil(10 * k) / 10;
  3564. // d.ea(e);
  3565. // d = d.L();
  3566. // var p = ~~(d.width / e);
  3567. // var h = ~~(d.height / e);
  3568. // a.drawImage(d, ~~this.x - ~~(p / 2), c - ~~(h / 2), p, h);
  3569. // c += d.height / 2 / e + 4;
  3570. //}
  3571. //if (0 < this.id) {
  3572. // if (gb) {
  3573. // if (b || 0 == m.length && ((!this.h || this.n) && 20 < this.size)) {
  3574. // if (null == this.O) {
  3575. // this.O = new ua(this.l() / 2, "#FFFFFF", true, "#000000");
  3576. // }
  3577. // b = this.O;
  3578. // b.M(this.l() / 2);
  3579. // b.C(~~(this.size * this.size / 100));
  3580. // e = Math.ceil(10 * k) / 10;
  3581. // b.ea(e);
  3582. // d = b.L();
  3583. // p = ~~(d.width / e);
  3584. // h = ~~(d.height / e);
  3585. // a.drawImage(d, ~~this.x - ~~(p / 2), c - ~~(h / 2), p, h);
  3586. // }
  3587. // }
  3588. //}
  3589. /*new*//*remap*/if(0 != this.id) {
  3590. /*new*//*remap*/var vertical_offset = drawCellName.call(this,b,e,d);
  3591. /*new*//*remap*/ drawCellMass.call(this,vertical_offset,b);
  3592. }
  3593. a.restore();
  3594. }
  3595. }
  3596. };
  3597. /*new*//*remap*/restorePointObj(aa.prototype);
  3598. ua.prototype = {
  3599. F : "",
  3600. S : "#000000",
  3601. U : false,
  3602. v : "#000000",
  3603. u : 16,
  3604. p : null,
  3605. T : null,
  3606. k : false,
  3607. D : 1,
  3608. M : function(a) {
  3609. if (this.u != a) {
  3610. this.u = a;
  3611. this.k = true;
  3612. }
  3613. },
  3614. ea : function(a) {
  3615. if (this.D != a) {
  3616. this.D = a;
  3617. this.k = true;
  3618. }
  3619. },
  3620. setStrokeColor : function(a) {
  3621. if (this.v != a) {
  3622. this.v = a;
  3623. this.k = true;
  3624. }
  3625. },
  3626. C : function(a) {
  3627. if (a != this.F) {
  3628. this.F = a;
  3629. this.k = true;
  3630. }
  3631. },
  3632. L : function() {
  3633. if (null == this.p) {
  3634. this.p = document.createElement("canvas");
  3635. this.T = this.p.getContext("2d");
  3636. }
  3637. if (this.k) {
  3638. this.k = false;
  3639. var a = this.p;
  3640. var c = this.T;
  3641. var b = this.F;
  3642. var e = this.D;
  3643. var d = this.u;
  3644. var p = d + "px Ubuntu";
  3645. c.font = p;
  3646. var h = ~~(0.2 * d);
  3647. a.width = (c.measureText(b).width + 6) * e;
  3648. a.height = (d + h) * e;
  3649. c.font = p;
  3650. c.scale(e, e);
  3651. c.globalAlpha = 1;
  3652. c.lineWidth = 3;
  3653. c.strokeStyle = this.v;
  3654. c.fillStyle = this.S;
  3655. if (this.U) {
  3656. c.strokeText(b, 3, d - h / 2);
  3657. }
  3658. c.fillText(b, 3, d - h / 2);
  3659. }
  3660. return this.p;
  3661. }
  3662. };
  3663. /*new*//*remap*/restoreCanvasElementObj(ua.prototype);
  3664. if (!Date.now) {
  3665. Date.now = function() {
  3666. return(new Date).getTime();
  3667. };
  3668. }
  3669. (function() {
  3670. var a$$0 = ["ms", "moz", "webkit", "o"];
  3671. var c = 0;
  3672. for (;c < a$$0.length && !d.requestAnimationFrame;++c) {
  3673. d.requestAnimationFrame = d[a$$0[c] + "RequestAnimationFrame"];
  3674. d.cancelAnimationFrame = d[a$$0[c] + "CancelAnimationFrame"] || d[a$$0[c] + "CancelRequestAnimationFrame"];
  3675. }
  3676. if (!d.requestAnimationFrame) {
  3677. d.requestAnimationFrame = function(a) {
  3678. return setTimeout(a, 1E3 / 60);
  3679. };
  3680. d.cancelAnimationFrame = function(a) {
  3681. clearTimeout(a);
  3682. };
  3683. }
  3684. })();
  3685. var mb = {
  3686. ja : function(a$$0) {
  3687. function c$$1(a, c, b, d, e) {
  3688. this.x = a;
  3689. this.y = c;
  3690. this.j = b;
  3691. this.g = d;
  3692. this.depth = e;
  3693. this.items = [];
  3694. this.c = [];
  3695. }
  3696. var b$$1 = a$$0.ka || 2;
  3697. var e$$0 = a$$0.la || 4;
  3698. c$$1.prototype = {
  3699. x : 0,
  3700. y : 0,
  3701. j : 0,
  3702. g : 0,
  3703. depth : 0,
  3704. items : null,
  3705. c : null,
  3706. H : function(a) {
  3707. var c$$0 = 0;
  3708. for (;c$$0 < this.items.length;++c$$0) {
  3709. var b = this.items[c$$0];
  3710. if (b.x >= a.x && (b.y >= a.y && (b.x < a.x + a.j && b.y < a.y + a.g))) {
  3711. return true;
  3712. }
  3713. }
  3714. if (0 != this.c.length) {
  3715. var d = this;
  3716. return this.$(a, function(c) {
  3717. return d.c[c].H(a);
  3718. });
  3719. }
  3720. return false;
  3721. },
  3722. A : function(a, c) {
  3723. var b$$0 = 0;
  3724. for (;b$$0 < this.items.length;++b$$0) {
  3725. c(this.items[b$$0]);
  3726. }
  3727. if (0 != this.c.length) {
  3728. var d = this;
  3729. this.$(a, function(b) {
  3730. d.c[b].A(a, c);
  3731. });
  3732. }
  3733. },
  3734. m : function(a) {
  3735. if (0 != this.c.length) {
  3736. this.c[this.Z(a)].m(a);
  3737. } else {
  3738. if (this.items.length >= b$$1 && this.depth < e$$0) {
  3739. this.ga();
  3740. this.c[this.Z(a)].m(a);
  3741. } else {
  3742. this.items.push(a);
  3743. }
  3744. }
  3745. },
  3746. Z : function(a) {
  3747. return a.x < this.x + this.j / 2 ? a.y < this.y + this.g / 2 ? 0 : 2 : a.y < this.y + this.g / 2 ? 1 : 3;
  3748. },
  3749. $ : function(a, c) {
  3750. return a.x < this.x + this.j / 2 && (a.y < this.y + this.g / 2 && c(0) || a.y >= this.y + this.g / 2 && c(2)) || a.x >= this.x + this.j / 2 && (a.y < this.y + this.g / 2 && c(1) || a.y >= this.y + this.g / 2 && c(3)) ? true : false;
  3751. },
  3752. ga : function() {
  3753. var a = this.depth + 1;
  3754. var b = this.j / 2;
  3755. var d = this.g / 2;
  3756. this.c.push(new c$$1(this.x, this.y, b, d, a));
  3757. this.c.push(new c$$1(this.x + b, this.y, b, d, a));
  3758. this.c.push(new c$$1(this.x, this.y + d, b, d, a));
  3759. this.c.push(new c$$1(this.x + b, this.y + d, b, d, a));
  3760. a = this.items;
  3761. this.items = [];
  3762. b = 0;
  3763. for (;b < a.length;b++) {
  3764. this.m(a[b]);
  3765. }
  3766. },
  3767. clear : function() {
  3768. var a = 0;
  3769. for (;a < this.c.length;a++) {
  3770. this.c[a].clear();
  3771. }
  3772. this.items.length = 0;
  3773. this.c.length = 0;
  3774. }
  3775. };
  3776. var d$$0 = {
  3777. x : 0,
  3778. y : 0,
  3779. j : 0,
  3780. g : 0
  3781. };
  3782. return{
  3783. root : new c$$1(a$$0.ca, a$$0.da, a$$0.ma - a$$0.ca, a$$0.na - a$$0.da, 0),
  3784. m : function(a) {
  3785. this.root.m(a);
  3786. },
  3787. A : function(a, c) {
  3788. this.root.A(a, c);
  3789. },
  3790. pa : function(a, c, b, e, f) {
  3791. d$$0.x = a;
  3792. d$$0.y = c;
  3793. d$$0.j = b;
  3794. d$$0.g = e;
  3795. this.root.A(d$$0, f);
  3796. },
  3797. H : function(a) {
  3798. return this.root.H(a);
  3799. },
  3800. clear : function() {
  3801. this.root.clear();
  3802. }
  3803. };
  3804. }
  3805. };
  3806. var Za = function() {
  3807. var a = new aa(0, 0, 0, 32, "#ED1C24", "");
  3808. var c = document.createElement("canvas");
  3809. c.width = 32;
  3810. c.height = 32;
  3811. var b = c.getContext("2d");
  3812. return function() {
  3813. if (0 < m.length) {
  3814. a.color = m[0].color;
  3815. a.B(m[0].name);
  3816. }
  3817. b.clearRect(0, 0, 32, 32);
  3818. b.save();
  3819. b.translate(16, 16);
  3820. b.scale(0.4, 0.4);
  3821. a.w(b);
  3822. b.restore();
  3823. var d = document.getElementById("favicon");
  3824. var f = d.cloneNode(true);
  3825. /*new*/try{
  3826. f.setAttribute("href", c.toDataURL("image/png"));
  3827. /*new*/}catch(err){}
  3828. d.parentNode.replaceChild(f, d);
  3829. };
  3830. }();
  3831. /*new*///kb();
  3832. /*new*///f(function() {
  3833. /*new*/// Za();
  3834. /*new*///});
  3835.  
  3836. f(function() {
  3837. if (d.localStorage.loginCache) {
  3838. eb(d.localStorage.loginCache);
  3839. }
  3840. if (d.localStorage.fbPictureCache) {
  3841. f(".agario-profile-picture").attr("src", d.localStorage.fbPictureCache);
  3842. }
  3843. });
  3844.  
  3845. d.fbAsyncInit = function() {
  3846. function a$$0() {
  3847. d.FB.login(function(a) {
  3848. Ia(a);
  3849. }, {
  3850. scope : "public_profile, email"
  3851. });
  3852. }
  3853. d.FB.init({
  3854. appId : "677505792353827",
  3855. cookie : true,
  3856. xfbml : true,
  3857. status : true,
  3858. version : "v2.2"
  3859. });
  3860. d.FB.Event.subscribe("auth.statusChange", function(c) {
  3861. if ("connected" == c.status) {
  3862. Ia(c);
  3863. } else {
  3864. a$$0();
  3865. }
  3866. });
  3867. d.facebookLogin = a$$0;
  3868. };
  3869.  
  3870. var Ab = function() {
  3871. function a$$0(a, c, b, d, e) {
  3872. var f = c.getContext("2d");
  3873. var g = c.width;
  3874. c = c.height;
  3875. a.color = e;
  3876. a.B(b);
  3877. a.size = d;
  3878. f.save();
  3879. f.translate(g / 2, c / 2);
  3880. a.w(f);
  3881. f.restore();
  3882. }
  3883. var c$$0 = new aa(0, 0, 0, 32, "#5bc0de", "");
  3884. c$$0.id = -1;
  3885. var b$$0 = new aa(0, 0, 0, 32, "#5bc0de", "");
  3886. b$$0.id = -1;
  3887. var d$$0 = document.createElement("canvas");
  3888. d$$0.getContext("2d");
  3889. d$$0.width = d$$0.height = 70;
  3890. a$$0(b$$0, d$$0, "", 26, "#ebc0de");
  3891. return function() {
  3892. f(".cell-spinner").filter(":visible").each(function() {
  3893. var b = f(this);
  3894. var g = Date.now();
  3895. var h = this.width;
  3896. var k = this.height;
  3897. var m = this.getContext("2d");
  3898. m.clearRect(0, 0, h, k);
  3899. m.save();
  3900. m.translate(h / 2, k / 2);
  3901. var q = 0;
  3902. for (;10 > q;++q) {
  3903. m.drawImage(d$$0, (0.1 * g + 80 * q) % (h + 140) - h / 2 - 70 - 35, k / 2 * Math.sin((0.001 * g + q) % Math.PI * 2) - 35, 70, 70);
  3904. }
  3905. m.restore();
  3906. if (b = b.attr("data-itr")) {
  3907. b = X(b);
  3908. }
  3909. a$$0(c$$0, this, b || "", +f(this).attr("data-size"), "#5bc0de");
  3910. /*new*/ });
  3911. };
  3912. };
  3913.  
  3914. d.createParty = function() {
  3915. ia(":party");
  3916. J = function(a) {
  3917. f(".partyToken").val(a);
  3918. f("#helloContainer").attr("data-party-state", "1");
  3919. };
  3920. N();
  3921. };
  3922.  
  3923. d.joinParty = function(a) {
  3924. f("#helloContainer").attr("data-party-state", "4");
  3925. f.ajax(Ja + "//m.agar.io/getToken", {
  3926. error : function() {
  3927. f("#helloContainer").attr("data-party-state", "6");
  3928. },
  3929. success : function(c) {
  3930. c = c.split("\n");
  3931. f(".partyToken").val(a);
  3932. f("#helloContainer").attr("data-party-state", "5");
  3933. ia(":party");
  3934. Aa("ws://" + c[0], a);
  3935. },
  3936. dataType : "text",
  3937. method : "POST",
  3938. cache : false,
  3939. crossDomain : true,
  3940. data : a
  3941. });
  3942. };
  3943. d.cancelParty = function() {
  3944. f("#helloContainer").attr("data-party-state", "0");
  3945. ia("");
  3946. N();
  3947. };
  3948.  
  3949. /*new*///f(function() {
  3950. /*new*/// f(kb);
  3951. /*new*///});
  3952. /*new*/d.onload = kb;
  3953. }
  3954. }
  3955. /*new*/})(unsafeWindow, unsafeWindow.jQuery);
  3956.  
  3957. // ====================================== Stats Screen ===========================================================
  3958.  
  3959. var __STORAGE_PREFIX = "mikeyk730__";
  3960. var chart_update_interval = 10;
  3961. jQuery('body').append('<div id="chart-container" style="display:none; position:absolute; height:176px; width:300px; left:10px; bottom:44px"></div>');
  3962. var checkbox_div = jQuery('#settings input[type=checkbox]').closest('div');
  3963.  
  3964. // make sure player sees ads at least once so Zeach doesn't go medieval on me.
  3965. var PlayerHasSeenOfficialAds =_.once(function (){
  3966. jQuery("#ZCPlay").show();
  3967. jQuery("#ZCClose").text("Close");
  3968. });
  3969.  
  3970. unsafeWindow.hideZCOverlay = function(){
  3971. PlayerHasSeenOfficialAds();
  3972. jQuery('#ZCOverlay').fadeOut();
  3973. }
  3974. unsafeWindow.showZCOverlay = function (){
  3975. jQuery('#ZCOverlay').fadeIn();
  3976. OnShowOverlay(false);
  3977. };
  3978. jQuery('body').append('<div id="ZCOverlay" class="bs-example-modal-lg" style="position:relative;z-index: 300;">'+
  3979. '<div class="modal-dialog modal-lg">'+
  3980. ' <div class="modal-content">'+
  3981. ' <div class="modal-header">'+
  3982. ' <button type="button" class="close" onclick="hideZCOverlay();")><span>×</span></button>'+
  3983. '<h4 class="modal-title">A1iens Agar Mod v' +GM_info.script.version + '</h4>'+
  3984. '</div>'+
  3985. '<div id="ZCOverlayBody" class="modal-body" style="height:675px;">'+
  3986. ' </div>'+
  3987. ' <div class="modal-footer">'+
  3988. ' <button type="button" id="ZCClose" class="btn btn-default" onclick="hideZCOverlay();">Let\'s Roll</button>'+
  3989. ' <button type="button" id="ZCPlay" class="btn btn-primary" onclick="hideZCOverlay();setNick(document.getElementById(\'nick\').value); return false;">Play</button>'+
  3990. '</div>'+
  3991. '</div><!-- /.modal-content -->'+
  3992. '</div><!-- /.modal-dialog -->'+
  3993. '</div><!-- /.modal -->');
  3994.  
  3995. jQuery("#ZCPlay").hide();
  3996.  
  3997. jQuery("#agario-main-buttons")
  3998. .append('<button type="button" class="btn btn-danger" id="opnZC" onclick="showZCOverlay()" style="margin-top:5px;position:relative;width:100%;">More Options</button>');
  3999. jQuery("#agario-main-buttons")
  4000. .append('<button type="button" id="opnBrowser" onclick="openServerbrowser();" style="margin-top:5px;position:relative;width:100%" class="btn btn-success">Agariomods Private Servers</button><br>');
  4001.  
  4002. jQuery('#ZCOverlayBody').append('<div id="ZCStats" style="position:relative;width:100%; background-color: #FFFFFF; border-radius: 15px; padding: 5px 15px 5px 15px;">'+
  4003. '<ul class="nav nav-pills" role="tablist">' +
  4004. '<li role="presentation" class="active" > <a href="#page0" id="newsTab" role="tab" data-toggle="tab">News</a></li>' +
  4005. '<li role="presentation"> <a href="#page1" id="statsTab" role="tab" data-toggle="tab">Stats</a></li>' +
  4006. '<li role="presentation"> <a href="#page2" id="configTab" role="tab" data-toggle="tab">Extended Options</a></li>' +
  4007. '<li role="presentation"> <a href="#page3" id="helpTab" role="tab" data-toggle="tab">Help</a></li>' +
  4008. //'<li role="presentation"><a href="#page3" role="tab" data-toggle="tab">IP Connect</a></li>' +
  4009. '</ul>'+
  4010.  
  4011. '<div id="bigbox" class="tab-content">' +
  4012. '<div id="page0" role="tabpanel" class="tab-pane active">'+ debugMonkeyReleaseMessage +'</div>' +
  4013.  
  4014. '<div id="page1" role="tabpanel" class="tab-pane">' +
  4015. '<div class="row">' +
  4016. '<div id="statArea" class="col-sm-6" style="vertical-align:top;"></div>' +
  4017. '<div id="pieArea" class="col-sm-5" style="vertical-align: top; height:250px;"></div>' +
  4018. '<div id="padder" class="col-sm-1"></div>' +
  4019. '</div>' +
  4020. '<div class="row">' +
  4021. '<div id="gainArea" class="col-sm-6" style="vertical-align:top;"></div>' +
  4022. '<div id="lossArea" class="col-sm-6" style="vertical-align:top;"></div>' +
  4023. '</div>' +
  4024. '<div class="row">' +
  4025. '<div id="chartArea" class="col-sm-8" ></div>' +
  4026. '<div id="XPArea" class="col-sm-4"></div>' +
  4027. '</div>' +
  4028. '</div>' +
  4029. '<div id="page2" role="tabpanel" class="tab-pane">' +
  4030. '<div class="row">' +
  4031. '<div id="col1" class="col-sm-4 checkbox" style="padding-left: 5%; padding-right: 1%;"></div>' +
  4032. '<div id="col2" class="col-sm-4" style="padding-left: 2%; padding-right: 2%;"></div>' +
  4033. '<div id="col3" class="col-sm-4" style="padding-left: 2%; padding-right: 5%;"></div>' +
  4034. '</div>' +
  4035. '</div>'+
  4036. '<div id="page3" role="tabpanel" class="tab-pane">' +
  4037. '<div class="row">' +
  4038. '<div id="col1" class="col-sm-6" style="padding-left: 5%; padding-right: 1%;"><h3>Keys</h3><ul>' +
  4039. ' <li><B>TAB</B> - When split switches selected blob</li>' +
  4040. ' <li><B>A</B> - Toggle Acid mode</li>' +
  4041. ' <li><B>Q</B> - Macro mode (Shots mass out fast)</li>' +
  4042. ' <li><B>C</B> - Toggle display of visual cues</li>' +
  4043. ' <li><B>G</B> - Toggle new grazer (better overall)</li>' +
  4044. ' <li><B>H</B> - Toggle old grazer (slightly better early on)' +
  4045. ' <li><B>E</B> - Fire at virus near cursor</li>' +
  4046. ' <li><B>R</B> - Fire at virus near selected blob (virus is highlighted in red)</li>' +
  4047. ' <li><B>M</B> - Enables/Disables mouse input</li>' +
  4048. ' <li><B>Z</B> - Zoom in/zoom out</li>' +
  4049. ' <li><B>1...7</B> - Selecte n-th blob sorted by size</li>' +
  4050. ' <li><B>Click</B> - Lock currently selected blob (if blob locking enabled)</li>' +
  4051. ' <li><B>S</B> - Unlock all blobs (if blob locking enabled)</li>' +
  4052. '</ul></div>' +
  4053. '<div id="col2" class="col-sm-6" style="padding-left: 5%; padding-right: 2%;"><h3></h3></div>' +
  4054. '</div>' +
  4055. '</div>');
  4056. jQuery(".agario-profile-panel").appendTo("#XPArea");
  4057. jQuery("#statsTab").click(function(){OnShowOverlay(false);});
  4058. function LS_getValue(aKey, aDefault) {
  4059. var val = localStorage.getItem(__STORAGE_PREFIX + aKey);
  4060. if (null === val && 'undefined' != typeof aDefault) return aDefault;
  4061. return val;
  4062. }
  4063.  
  4064. function LS_setValue(aKey, aVal) {
  4065. localStorage.setItem(__STORAGE_PREFIX + aKey, aVal);
  4066. }
  4067.  
  4068. function GetRgba(hex_color, opacity)
  4069. {
  4070. var patt = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/;
  4071. var matches = patt.exec(hex_color);
  4072. return "rgba("+parseInt(matches[1], 16)+","+parseInt(matches[2], 16)+","+parseInt(matches[3], 16)+","+opacity+")";
  4073. }
  4074.  
  4075. function secondsToHms(d)
  4076. {
  4077. d = Number(d);
  4078. var h = Math.floor(d / 3600);
  4079. var m = Math.floor(d % 3600 / 60);
  4080. var s = Math.floor(d % 3600 % 60);
  4081. return ((h > 0 ? h + ":" + (m < 10 ? "0" : "") : "") + m + ":" + (s < 10 ? "0" : "") + s);
  4082. }
  4083.  
  4084. var chart = null;
  4085. var chart_data = [];
  4086. var num_cells_data = [];
  4087. var chart_counter = 0;
  4088. var stat_canvas = null;
  4089.  
  4090. var stats = null;
  4091. var my_cells = null;
  4092. var my_color = "#ff8888";
  4093. var pie = null;
  4094. var stats_chart;
  4095.  
  4096. var display_chart = LS_getValue('display_chart', 'true') === 'true';
  4097. var display_stats = LS_getValue('display_stats', 'false') === 'true';
  4098.  
  4099. function AppendCheckbox(e, id, label, checked, on_change)
  4100. {
  4101. e.append('<label><input type="checkbox" id="'+id+'">'+label+'</label><br>');
  4102. jQuery('#'+id).attr('checked', checked);
  4103. jQuery('#'+id).change(function(){
  4104. on_change(!!this.checked);
  4105. });
  4106. on_change(checked);
  4107. }
  4108. function AppendCheckboxP(e, id, label, checked, on_change)
  4109. {
  4110. e.append('<p><input type="checkbox" id="'+id+'">'+label+'</p>');
  4111. jQuery('#'+id).attr('checked', checked);
  4112. jQuery('#'+id).change(function(){
  4113. on_change(!!this.checked);
  4114. });
  4115. on_change(checked);
  4116. }
  4117.  
  4118. function OnChangeDisplayChart(display)
  4119. {
  4120. LS_setValue('display_chart', display ? 'true' : 'false');
  4121. display_chart = display;
  4122. display ? jQuery('#chart-container').show() : jQuery('#chart-container').hide();
  4123. }
  4124.  
  4125. function OnChangeDisplayStats(display)
  4126. {
  4127. LS_setValue('display_stats', display ? 'true' : 'false');
  4128. display_stats = display;
  4129. RenderStats(false);
  4130. }
  4131.  
  4132. function ResetChart()
  4133. {
  4134. chart = null;
  4135. chart_data.length = 0;
  4136. num_cells_data.length = 0;
  4137. chart_counter = 0;
  4138. jQuery('#chart-container').empty();
  4139. }
  4140.  
  4141. function UpdateChartData(mass)
  4142. {
  4143. chart_counter++;
  4144. if (chart_counter%chart_update_interval > 0)
  4145. return false;
  4146.  
  4147. num_cells_data.push({
  4148. x: chart_counter,
  4149. y: my_cells.length
  4150. });
  4151.  
  4152. chart_data.push({
  4153. x: chart_counter,
  4154. y: mass/100
  4155. });
  4156. return true;
  4157. }
  4158.  
  4159. function CreateChart(e, color, interactive)
  4160. {
  4161. return new CanvasJS.Chart(e,{
  4162. interactivityEnabled: false,
  4163. title: null,
  4164. axisX:{
  4165. valueFormatString: " ",
  4166. lineThickness: 0,
  4167. tickLength: 0
  4168. },
  4169. axisY:{
  4170. lineThickness: 0,
  4171. tickLength: 0,
  4172. gridThickness: 2,
  4173. gridColor: "white",
  4174. labelFontColor: "white"
  4175. },
  4176. backgroundColor: "rgba(0,0,0,0.2)",
  4177. data: [{
  4178. type: "area",
  4179. color: color,
  4180. dataPoints: chart_data
  4181. }]
  4182. });
  4183. }
  4184.  
  4185. function UpdateChart(mass, color)
  4186. {
  4187. my_color = color;
  4188. if (chart === null)
  4189. chart = CreateChart("chart-container", color, false);
  4190. if (UpdateChartData(mass) && display_chart)
  4191. chart.render();
  4192.  
  4193. jQuery('.canvasjs-chart-credit').hide();
  4194. }
  4195.  
  4196. function ResetStats()
  4197. {
  4198. stats = {
  4199. pellets: {num:0, mass:0},
  4200. w: {num:0, mass:0},
  4201. cells: {num:0, mass:0},
  4202. viruses: {num:0, mass:0},
  4203.  
  4204. birthday: Date.now(),
  4205. time_of_death: null,
  4206. high_score: 0,
  4207. top_slot: Number.POSITIVE_INFINITY,
  4208.  
  4209. gains: {},
  4210. losses: {},
  4211. };
  4212. }
  4213.  
  4214. function OnGainMass(me, other)
  4215. {
  4216. var mass = other.size * other.size;
  4217. if (other.isVirus){
  4218. stats.viruses.num++;
  4219. stats.viruses.mass += mass; //TODO: shouldn't add if game mode is teams
  4220. sfx_event("virushit");
  4221. }
  4222. else if (Math.floor(mass) <= 400 && !other.name){
  4223. stats.pellets.num++;
  4224. stats.pellets.mass += mass;
  4225. sfx_event("pellet");
  4226. }
  4227. // heuristic to determine if mass is 'w', not perfect
  4228. else if (!other.name && mass <= 1444 && (mass >= 1369 || (other.x == other.ox && other.y == other.oy))){
  4229. //console.log('w', mass, other.name, other);
  4230. if (other.color != me.color){ //don't count own ejections, again not perfect
  4231. stats.w.num++;
  4232. stats.w.mass += mass;
  4233. }
  4234. sfx_event("eat");
  4235. }
  4236. else {
  4237. //console.log('cell', mass, other.name, other);
  4238. var key = other.name + ':' + other.color;
  4239. stats.cells.num++;
  4240. stats.cells.mass += mass;
  4241. if (stats.gains[key] == undefined)
  4242. stats.gains[key] = {num: 0, mass: 0};
  4243. stats.gains[key].num++;
  4244. stats.gains[key].mass += mass;
  4245. sfx_event("eat");
  4246. }
  4247. }
  4248.  
  4249. function OnLoseMass(me, other)
  4250. {
  4251. var mass = me.size * me.size;
  4252. var key = other.name + ':' + other.color;
  4253. if (stats.losses[key] == undefined)
  4254. stats.losses[key] = {num: 0, mass: 0};
  4255. stats.losses[key].num++;
  4256. stats.losses[key].mass += mass;
  4257. sfx_event("eat");
  4258. }
  4259.  
  4260. function DrawPie(pellet, w, cells, viruses)
  4261. {
  4262. var total = pellet + w + cells + viruses;
  4263. pie = new CanvasJS.Chart("pieArea", {
  4264. title: null,
  4265. animationEnabled: false,
  4266. legend:{
  4267. verticalAlign: "center",
  4268. horizontalAlign: "left",
  4269. fontSize: 20,
  4270. fontFamily: "Helvetica"
  4271. },
  4272. theme: "theme2",
  4273. data: [{
  4274. type: "pie",
  4275. startAngle:-20,
  4276. showInLegend: true,
  4277. toolTipContent:"{legendText} {y}%",
  4278. dataPoints: [
  4279. { y: 100*pellet/total, legendText:"pellets"},
  4280. { y: 100*cells/total, legendText:"cells"},
  4281. { y: 100*w/total, legendText:"w"},
  4282. { y: 100*viruses/total, legendText:"viruses"},
  4283. ]
  4284. }]
  4285. });
  4286. pie.render();
  4287. }
  4288.  
  4289. function GetTopN(n, p){
  4290. var r = [];
  4291. var a = Object.keys(stats[p]).sort(function(a, b) {return -(stats[p][a].mass - stats[p][b].mass)});
  4292. for (var i = 0; i < n && i < a.length; ++i){
  4293. var key = a[i];
  4294. var mass = stats[p][key].mass;
  4295. var name = key.slice(0,key.length-8);
  4296. if (!name) name = "An unnamed cell";
  4297. var color = key.slice(key.length-7);
  4298. r.push({name:name, color:color, mass:Math.floor(mass/100)});
  4299. }
  4300. return r;
  4301. }
  4302.  
  4303. function AppendTopN(n, p, list) {
  4304. var a = GetTopN(n,p);
  4305. for (var i = 0; i < a.length; ++i){
  4306. var text = a[i].name + ' (' + (p == 'gains' ? '+' : '-') + a[i].mass + ' mass)';
  4307. list.append('<li style="font-size: 16px; "><div style="width: 16px; height: 16px; border-radius: 50%; margin-right:5px; background-color: ' + a[i].color + '; display: inline-block;"></div>' + text + '</li>');
  4308. };
  4309. return a.length > 0;
  4310. }
  4311.  
  4312. function ShowZCStats(){
  4313. if(cobbler.showZcStats){
  4314. jQuery("#ZCOverlay").fadeIn();
  4315. jQuery('#statsTab').tab('show');
  4316. }
  4317.  
  4318. }
  4319.  
  4320. function DrawStats(game_over) {
  4321. if (!stats) return;
  4322.  
  4323. jQuery('#statArea').empty();
  4324. jQuery('#pieArea').empty();
  4325. jQuery('#gainArea').empty();
  4326. jQuery('#lossArea').empty();
  4327. jQuery('#chartArea').empty();
  4328. //jQuery('#statsTab').tab('show');
  4329.  
  4330. if (game_over){
  4331. stats.time_of_death = Date.now();
  4332. sfx_play(1);
  4333. StopBGM();
  4334. ShowZCStats();
  4335. if(window.cobbler.autoRespawn && window.cobbler.grazingMode){setTimeout(function(){jQuery(".btn-play-guest").click();},3000);}
  4336. }
  4337. var time = stats.time_of_death ? stats.time_of_death : Date.now();
  4338. var seconds = (time - stats.birthday)/1000;
  4339.  
  4340. var list = jQuery('<ul>');
  4341. list.append('<li style="font-size: 16px; ">Game time: ' + secondsToHms(seconds) + '</li>');
  4342. list.append('<li style="font-size: 16px; ">High score: ' + ~~(stats.high_score/100) + '</li>');
  4343. if (stats.top_slot == Number.POSITIVE_INFINITY){
  4344. list.append('<li style="font-size: 16px; ">You didn\'t make the leaderboard</li>');
  4345. }
  4346. else {
  4347. list.append('<li style="font-size: 16px; ">Leaderboard max: ' + stats.top_slot + '</li>');
  4348. }
  4349. list.append('<li style="font-size: 16px; padding-top: 15px">' + stats.pellets.num + " pellets eaten (" + ~~(stats.pellets.mass/100) + ' mass)</li>');
  4350. list.append('<li style="font-size: 16px; ">' + stats.cells.num + " cells eaten (" + ~~(stats.cells.mass/100) + ' mass)</li>');
  4351. list.append('<li style="font-size: 16px; ">' + stats.w.num + " masses eaten (" + ~~(stats.w.mass/100) + ' mass)</li>');
  4352. list.append('<li style="font-size: 16px; ">' + stats.viruses.num + " viruses eaten (" + ~~(stats.viruses.mass/100) + ' mass)</li>');
  4353. jQuery('#statArea').append('<h2>Game Summary</h2>');
  4354. jQuery('#statArea').append(list);
  4355.  
  4356. DrawPie(stats.pellets.mass, stats.w.mass, stats.cells.mass, stats.viruses.mass);
  4357.  
  4358. jQuery('#gainArea').append('<h3>Top Gains</h3>');
  4359. list = jQuery('<ol>');
  4360. if (AppendTopN(5, 'gains', list))
  4361. jQuery('#gainArea').append(list);
  4362. else
  4363. jQuery('#gainArea').append('<ul><li style="font-size: 16px; ">You have not eaten anybody</li></ul>');
  4364.  
  4365. jQuery('#lossArea').append('<h3>Top Losses</h3>');
  4366. list = jQuery('<ol>');
  4367. if (AppendTopN(5, 'losses', list))
  4368. jQuery('#lossArea').append(list);
  4369. else
  4370. jQuery('#lossArea').append('<ul><li style="font-size: 16px; ">Nobody has eaten you</li></ul>');
  4371.  
  4372. if (stats.time_of_death !== null){
  4373. jQuery('#chartArea').height(200);
  4374. jQuery('#chartArea')[0].height=200;
  4375. stat_chart = CreateChart('chartArea', my_color, true);
  4376. var scale = Math.max.apply(Math,chart_data.map(function(o){return o.y;}))/16;
  4377. var scaled_data = num_cells_data.map(function(a){return {x:a.x, y:a.y*scale};});
  4378. stat_chart.options.data.push({type: "line", dataPoints: scaled_data, toolTipContent:" "});
  4379. stat_chart.render();
  4380. }
  4381. else {
  4382. jQuery('#chartArea').height(200);
  4383. jQuery('#chartArea')[0].height=200;
  4384. }
  4385. }
  4386.  
  4387. var styles = {
  4388. heading: {font:"30px Ubuntu", spacing: 41, alpha: 1},
  4389. subheading: {font:"25px Ubuntu", spacing: 31, alpha: 1},
  4390. normal: {font:"17px Ubuntu", spacing: 21, alpha: 0.6}
  4391. };
  4392.  
  4393. var g_stat_spacing = 0;
  4394. var g_display_width = 220;
  4395. var g_layout_width = g_display_width;
  4396.  
  4397. function AppendText(text, context, style) {
  4398. context.globalAlpha = styles[style].alpha;
  4399. context.font = styles[style].font;
  4400. g_stat_spacing += styles[style].spacing;
  4401.  
  4402. var width = context.measureText(text).width;
  4403. g_layout_width = Math.max(g_layout_width, width);
  4404. context.fillText(text, g_layout_width/2 - width/2, g_stat_spacing);
  4405. }
  4406.  
  4407. function RenderStats(reset) {
  4408. if (reset) g_layout_width = g_display_width;
  4409. if (!display_stats || !stats) return;
  4410. g_stat_spacing = 0;
  4411.  
  4412. var gains = GetTopN(3, 'gains');
  4413. var losses = GetTopN(3, 'losses');
  4414. var height = 30 + styles['heading'].spacing + styles['subheading'].spacing * 2 + styles['normal'].spacing * (4 + gains.length + losses.length);
  4415.  
  4416. stat_canvas = document.createElement("canvas");
  4417. var scale = Math.min(g_display_width, .3 * window.innerWidth) / g_layout_width;
  4418. stat_canvas.width = g_layout_width * scale;
  4419. stat_canvas.height = height * scale;
  4420. var context = stat_canvas.getContext("2d");
  4421. context.scale(scale, scale);
  4422.  
  4423. context.globalAlpha = .4;
  4424. context.fillStyle = "#000000";
  4425. context.fillRect(0, 0, g_layout_width, height);
  4426.  
  4427. context.fillStyle = "#FFFFFF";
  4428. AppendText("Stats", context, 'heading');
  4429.  
  4430. var text = stats.pellets.num + " pellets eaten (" + ~~(stats.pellets.mass/100) + ")";
  4431. AppendText(text, context,'normal');
  4432. text = stats.w.num + " mass eaten (" + ~~(stats.w.mass/100) + ")";
  4433. AppendText(text, context,'normal');
  4434. text = stats.cells.num + " cells eaten (" + ~~(stats.cells.mass/100) + ")";
  4435. AppendText(text, context,'normal');
  4436. text = stats.viruses.num + " viruses eaten (" + ~~(stats.viruses.mass/100) + ")";
  4437. AppendText(text, context,'normal');
  4438.  
  4439. AppendText("Top Gains",context,'subheading');
  4440. for (var j = 0; j < gains.length; ++j){
  4441. text = (j+1) + ". " + gains[j].name + " (" + gains[j].mass + ")";
  4442. context.fillStyle = gains[j].color;
  4443. AppendText(text, context,'normal');
  4444. }
  4445.  
  4446. context.fillStyle = "#FFFFFF";
  4447. AppendText("Top Losses",context,'subheading');
  4448. for (var j = 0; j < losses.length; ++j){
  4449. text = (j+1) + ". " + losses[j].name + " (" + losses[j].mass + ")";
  4450. context.fillStyle = losses[j].color;
  4451. AppendText(text, context,'normal');
  4452. }
  4453. }
  4454.  
  4455. jQuery(unsafeWindow).resize(function() {
  4456. RenderStats(false);
  4457. });
  4458.  
  4459. unsafeWindow.OnGameStart = function(cells) {
  4460. my_cells = cells;
  4461. ResetChart();
  4462. ResetStats();
  4463. RenderStats(true);
  4464. StartBGM();
  4465. sfx_play(0);
  4466. };
  4467.  
  4468. unsafeWindow.OnShowOverlay = function(game_in_progress) {
  4469. DrawStats(!game_in_progress);
  4470. };
  4471.  
  4472. unsafeWindow.OnUpdateMass = function(mass) {
  4473. stats.high_score = Math.max(stats.high_score, mass);
  4474. UpdateChart(mass, GetRgba(my_cells[0].color,0.4));
  4475. };
  4476.  
  4477. unsafeWindow.OnCellEaten = function(predator, prey) {
  4478. if (!my_cells) return;
  4479.  
  4480. if (my_cells.indexOf(predator) != -1){
  4481. OnGainMass(predator, prey);
  4482. RenderStats(false);
  4483. }
  4484. if (my_cells.indexOf(prey) != -1){
  4485. OnLoseMass(prey, predator);
  4486. RenderStats(false);
  4487. }
  4488. };
  4489.  
  4490. unsafeWindow.OnLeaderboard = function(position) {
  4491. stats.top_slot = Math.min(stats.top_slot, position);
  4492. };
  4493. unsafeWindow.OnDraw = function(context) {
  4494. display_stats && stat_canvas && context.drawImage(stat_canvas, 10, 10);
  4495. };
  4496.  
  4497.  
  4498. //wspam
  4499. (function() {
  4500. var amount = 2;
  4501. var duration = 50; //ms
  4502.  
  4503. var overwriting = function(evt) {
  4504. if (evt.keyCode === 81) { // 81=KEY_Q <<<------------- set key for W spam 86 means W just works, but after long press starts spamming
  4505. for (var i = 0; i < amount; ++i) {
  4506. setTimeout(function() {
  4507. window.onkeydown({keyCode: 87}); // KEY_W
  4508. window.onkeyup({keyCode: 87});
  4509. }, i * duration);
  4510. }
  4511. }
  4512. };
  4513.  
  4514. window.addEventListener('keydown', overwriting);
  4515. })();
  4516.  
  4517.  
  4518.  
  4519.  
  4520.  
  4521.  
  4522.  
  4523.  
  4524.  
  4525.  
  4526.  
  4527. // ====================== Music & SFX System ==============================================================
  4528. //sfx play on event (only one of each sfx can play - for sfx that won't overlap with itself)
  4529. var ssfxlist = [
  4530. 'spawn',
  4531. 'gameover'
  4532. ];
  4533. var ssfxs = [];
  4534. for (i=0;i<ssfxlist.length;i++) {
  4535. var newsfx = new Audio("http://skins.agariomods.com/botb/sfx/" + ssfxlist[i] + ".mp3");
  4536. newsfx.loop = false;
  4537. ssfxs.push(newsfx);
  4538. }
  4539. function sfx_play(id) {
  4540. if (document.getElementById("sfx").value==0) return;
  4541. var event = ssfxs[id];
  4542. event.volume = document.getElementById("sfx").value;
  4543. event.play();
  4544. }
  4545.  
  4546. //sfx insertion on event (multiple of same sfx can be played simultaneously)
  4547. var sfxlist = [
  4548. 'pellet',
  4549. 'split',
  4550. 'eat',
  4551. 'bounce',
  4552. 'merge',
  4553. 'virusfeed',
  4554. 'virusshoot',
  4555. 'virushit'
  4556. ];
  4557.  
  4558. var sfxs = {};
  4559. for (i=0;i<sfxlist.length;i++) {
  4560. var newsfx = new Audio("//skins.agariomods.com/botb/sfx/" + sfxlist[i] + ".mp3");
  4561. newsfx.loop = false;
  4562. newsfx.onended = function() {
  4563. $(this).remove();
  4564. };
  4565. sfxs[sfxlist[i]] = newsfx;
  4566. }
  4567. function sfx_event(id) {
  4568. if (document.getElementById("sfx").value==0) return;
  4569. var event = jQuery.clone(sfxs[id]);
  4570. event.volume = document.getElementById("sfx").value;
  4571. event.play();
  4572. }
  4573.  
  4574. var StartBGM = function () {
  4575. if (document.getElementById("bgm").value==0) return;
  4576. if (bgmusic.src == ""){
  4577. bgmusic.src = _.sample(tracks, 1);
  4578. bgmusic.load()
  4579. }
  4580. bgmusic.volume = document.getElementById("bgm").value;
  4581. bgmusic.play();
  4582. };
  4583.  
  4584. var StopBGM = function () {
  4585. bgmusic.pause();
  4586. if (document.getElementById("bgm").value==0) return;
  4587. bgmusic.src = _.sample(tracks, 1);
  4588. bgmusic.load()
  4589. };
  4590.  
  4591. volBGM = function (vol) {
  4592. console.log(vol.toString() + " - " + document.getElementById("bgm").value)
  4593. bgmusic.volume = document.getElementById("bgm").value;
  4594. window.cobbler.bgmVol = document.getElementById("bgm").value;
  4595. };
  4596.  
  4597. volSFX = function (vol) {
  4598. window.cobbler.sfxVol = vol;
  4599. };
  4600.  
  4601. var tracks = ['http://incompetech.com/music/royalty-free/mp3-preview2/Frost%20Waltz.mp3',
  4602. 'http://incompetech.com/music/royalty-free/mp3-preview2/Frozen%20Star.mp3',
  4603. 'http://incompetech.com/music/royalty-free/mp3-preview2/Groove%20Grove.mp3',
  4604. 'http://incompetech.com/music/royalty-free/mp3-preview2/Dreamy%20Flashback.mp3',
  4605. 'http://incompetech.com/music/royalty-free/mp3-preview2/Impact%20Lento.mp3',
  4606. 'http://incompetech.com/music/royalty-free/mp3-preview2/Wizardtorium.mp3'];
  4607. /*sfx*/
  4608. var nodeAudio = document.createElement("audio");
  4609. nodeAudio.id = 'audiotemplate';
  4610. nodeAudio.preload = "auto";
  4611. jQuery(".agario-panel").get(0).appendChild(nodeAudio);
  4612.  
  4613.  
  4614. var bgmusic = $('#audiotemplate').clone()[0];
  4615. bgmusic.src = tracks[Math.floor(Math.random() * tracks.length)];
  4616. bgmusic.load();
  4617. bgmusic.loop = false;
  4618. bgmusic.onended = function() {
  4619. var track = tracks[Math.floor(Math.random() * tracks.length)];
  4620. bgmusic.src = track;
  4621. bgmusic.play();
  4622. };
  4623.  
  4624. function uiOnLoadTweaks(){
  4625. $("label:contains('Dark theme') input").prop('checked', true);
  4626. setDarkTheme(true);
  4627. $("label:contains('Show mass') input").prop('checked', true);
  4628. setShowMass(true);
  4629.  
  4630. $('#nick').val(GM_getValue("nick", ""));
  4631. }
  4632. //================================ AgarioMods Private Servers ========================================================
  4633. unsafeWindow.openServerbrowser = function (a) {
  4634. var b = unsafeWindow.openServerbrowser.loading;
  4635. if(b) {
  4636. return;
  4637. }
  4638. b = true;
  4639. jQuery("#rsb")
  4640. .prop("disabled", true);
  4641. if(!a) {
  4642. jQuery("#serverBrowser")
  4643. .fadeIn();
  4644. }
  4645. getServers();
  4646. };
  4647.  
  4648. function serverinfo(list, index) {
  4649. if(index >= list.length) {
  4650. unsafeWindow.openServerbrowser.loading = false;
  4651. jQuery("#rsb")
  4652. .prop("disabled", false);
  4653. return;
  4654. }
  4655. value = list[index];
  4656. started = Date.now();
  4657. statsurl = "http://" + value[0] + ".iomods.com:" + (8080 + value[1]);
  4658. jQuery.ajax({
  4659. url: statsurl,
  4660. dataType: "json",
  4661. success: function (data) {
  4662. $("#" + (value[0] + value[1]) + " #player")
  4663. .text(data.current_players + "/" + data.max_players);
  4664. latency = Date.now() - started;
  4665. if(latency < 100) {
  4666. jQuery("#" + (value[0] + value[1]) + " #latency")
  4667. .css("color", "#19A652");
  4668. } else {
  4669. if(latency < 250) {
  4670. jQuery("#" + (value[0] + value[1]) + " #latency")
  4671. .css("color", "#E1BD2C");
  4672. } else {
  4673. jQuery("#" + (value[0] + value[1]) + " #latency")
  4674. .css("color", "#F00");
  4675. }
  4676. }
  4677. jQuery("#" + (value[0] + value[1]) + " #latencyres")
  4678. .text(latency + "ms");
  4679. },
  4680. error: function (data) {
  4681. jQuery("#" + (value[0] + value[1]) + " #player")
  4682. .text("No information");
  4683. jQuery("#" + (value[0] + value[1]) + " #latency")
  4684. .css("color", "#f00");
  4685. jQuery("#" + (value[0] + value[1]) + " #latency")
  4686. .text("Failed");
  4687. },
  4688. complete: function (data) {
  4689. if(!(document.getElementById("serverBrowser")
  4690. .style.display == "none")) {
  4691. serverinfo(list, index + 1);
  4692. }
  4693. }
  4694. });
  4695. }
  4696. unsafeWindow.connectPrivate = function (location, i) {
  4697. var ip = location.toLowerCase()
  4698. .replace(" ", "") + ".iomods.com";
  4699. var port = 1500 + parseInt(i);
  4700. //server.ip = ip;
  4701. //server.i = i;
  4702. //server.location = location;
  4703. connect("ws://" + ip + ":" + port, "");
  4704. //openChat();
  4705. };
  4706. var st = document.createElement("style");
  4707. st.innerHTML = ".serveritem {display:block;border-bottom:1px solid #ccc;padding:4px;}.serveritem:hover{text-decoration:none;background-color:#E9FCFF;}.overlay{line-height:1.2;margin:0;font-family:sans-serif;text-align:center;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1000;background-color:rgba(0,0,0,0.2)}.popupbox{position:absolute;height:100%;width:60%;left:20%;background-color:rgba(255,255,255,0.95);box-shadow:0 0 20px #000}.popheader{position:absolute;top:0;width:100%;height:50px;background-color:rgba(200,200,200,0.5)}.browserfilter{position:absolute;padding:5px;top:50px;width:100%;height:60px;background-color:rgba(200,200,200,0.5)}.scrollable{position:absolute;border-top:#eee 1px solid;border-bottom:#eee 1px solid;width:100%;top:50px;bottom:50px;overflow:auto}.popupbuttons{background-color:rgba(200,200,200,0.4);height:50px;position:absolute;bottom:0;width:100%}.popupbox td,th{padding:5px}.popupbox tbody tr{border-top:#ccc solid 1px}#tooltip{display:inline;position:relative}#tooltip:hover:after{background:#333;background:rgba(0,0,0,.8);border-radius:5px;bottom:26px;color:#fff;content:attr(title);left:20%;padding:5px 15px;position:absolute;z-index:98;width:220px}#chat{z-index:2000;width:500px;position:absolute;right:15px;bottom:50px}#chatinput{bottom:0;position:absolute;opacity:.8}#chatlines a{color:#086A87}#chatlines{position:absolute;bottom:40px;width:500px;color:#333;word-wrap:break-word;box-shadow:0 0 10px #111;background-color:rgba(0,0,0,0.1);border-radius:5px;padding:5px;height:200px;overflow:auto}.listing>span{display:block;font-size:11px;font-weight:400;color:#999}.list{padding:0 0;list-style:none;display:block;font:12px/20px 'Lucida Grande',Verdana,sans-serif}.listing{border-bottom:1px solid #e8e8e8;display:block;padding:10px 12px;font-weight:700;color:#555;text-decoration:none;cursor:pointer;line-height:18px}li:last-child > .listing{border-radius:0 0 3px 3px}.listing:hover{background:#e5e5e5}";
  4708. document.head.appendChild(st);
  4709.  
  4710. unsafeWindow.closeServerbrowser = function () {
  4711. jQuery("#serverBrowser")
  4712. .fadeOut();
  4713. };
  4714. var locations=new Array("Chicago Beta","Dallas Beta","Frankfurt Beta","London Beta","Los Angeles Beta","Miami Beta","New Jersey Beta","Paris Beta","Seattle Beta","Silicon Valley Beta","Sydney Beta","Amsterdam","Amsterdam Beta","Atlanta Beta","Frankfurt Alpha","Frankfurt","London","Quebec","Paris","Paris Gamma","Atlanta","Chicago","Dallas","Los Angeles","Miami","New Jersey","Seattle","Silicon Valley","Sydney","Tokyo");
  4715. locations.sort();
  4716. locations[0] = [locations[1], locations[1] = locations[0]][0];
  4717.  
  4718. function getServers() {
  4719. jQuery("#serverlist1")
  4720. .empty();
  4721. jQuery("#serverlist2")
  4722. .empty();
  4723. var latencylist = Array();
  4724. jQuery.each(locations, function (index, value) {
  4725. var i = 1;
  4726. for(; i <= 2; i++) {
  4727. serverid = value.toLowerCase()
  4728. .replace(" ", "") + i;
  4729. $("#serverlist" + i)
  4730. .append('<a href class="serveritem" id="' + serverid + '" onclick="connectPrivate(\'' + value + "', '" + i + '\');closeServerbrowser();return false;"><b style="color: #222">' + value + " #" + i + '</b><br>\t\t\t<i style="color: #999"><span id="player">fetching data...</span> <i style="color: #ccc" class="fa fa-users" /> | </i><span id="latency"><i class="fa fa-signal"></i> <span id="latencyres"></span></span></a>');
  4731. latencylist.push(new Array(value.toLowerCase()
  4732. .replace(" ", ""), i));
  4733. }
  4734. });
  4735. serverinfo(latencylist, 0);
  4736. }
  4737.  
  4738. jQuery(document)
  4739. .ready(function () {
  4740. jQuery("body")
  4741. .append('<div id="serverBrowser" class="overlay" style="display:none"><div class="valign"><div class="popupbox"><div class="popheader"><h3>Agariomods Ogar Server Browser</h3></div>\t<div class="scrollable"><center style="border-right:1px solid #e8e8e8;float:left;width:50%;"><div id="serverlist1"></div></center><center style="float:right;width:50%;"><div id="serverlist2"></div></center></div><div class="popupbuttons"><button onclick="closeServerbrowser()" type="button" style="transform:translateX(72%);margin:4px"\tclass="btn btn-danger">Back</button><button id="rsb" onclick="openServerbrowser(true)" class="btn btn-info" type="button" style="float:right;margin:4px;">Refresh <i class="glyphicon glyphicon-refresh"></i></button></div></div></div></div>');
  4742. jQuery("body")
  4743. .append('<div id="chat" style="display:none"><div id="chatlines"></div><div id="chatinput" style="display:none" class="input-group">\t<input type="text" id="chatinputfield" class="form-control" maxlength="120"><span class="input-group-btn">\t<button onclick="sendMSG()" class="btn btn-default" type="button">Send</button></span></div></div>');
  4744. });
  4745. // ===============================================================================================================
  4746. uiOnLoadTweaks();
  4747.  
  4748. var col1 = $("#col1");
  4749. col1.append("<h4>Options</h4>");
  4750. AppendCheckbox(col1, 'showZcStats-checkbox', ' Show ZC Stats On Death', window.cobbler.showZcStats, function(val){window.cobbler.showZcStats = val;});
  4751. col1.append("<h4>Modes</h4>");
  4752. AppendCheckbox(col1, 'litebrite-checkbox', ' Enable Lite Brite Mode', window.cobbler.isLiteBrite, function(val){window.cobbler.isLiteBrite = val;});
  4753. col1.append("<h4>Visual</h4>");
  4754. AppendCheckbox(col1, 'trailingtail-checkbox', ' Draw Trailing Tail', window.cobbler.drawTail, function(val){window.cobbler.drawTail = val;});
  4755. AppendCheckbox(col1, 'splitguide-checkbox', ' Draw Split Guide', window.cobbler.splitGuide, function(val){window.cobbler.splitGuide = val;});
  4756. AppendCheckbox(col1, 'rainbow-checkbox', ' Rainbow Pellets', window.cobbler.rainbowPellets, function(val){window.cobbler.rainbowPellets = val;});
  4757. AppendCheckbox(col1, 'namesunder-checkbox', ' Names under blobs', window.cobbler.namesUnderBlobs, function(val){window.cobbler.namesUnderBlobs = val;});
  4758. AppendCheckbox(col1, 'gridlines-checkbox', ' Show Gridlines', window.cobbler.gridLines, function(val){window.cobbler.gridLines = val;});
  4759. col1.append("<h4>Stats</h4>");
  4760. AppendCheckbox(col1, 'chart-checkbox', ' Show in-game chart', display_chart, OnChangeDisplayChart);
  4761. AppendCheckbox(col1, 'stats-checkbox', ' Show in-game stats', display_stats, OnChangeDisplayStats);
  4762. col1.append("<h4>Features</h4>");
  4763. AppendCheckbox(col1, 'feature-click-fire', ' Click to fire @ virus', window.cobbler.rightClickFires, function(val) {window.cobbler.rightClickFires = val;});
  4764. AppendCheckbox(col1, 'feature-blob-lock', ' Click to lock blob', window.cobbler.enableBlobLock, function(val) {window.cobbler.enableBlobLock = val;});
  4765. AppendCheckbox(col1, 'feature-blob-lock-next', ' Switch blob on lock', window.cobbler.nextOnBlobLock, function(val) {window.cobbler.nextOnBlobLock = val;});
  4766.  
  4767. var col2 = $("#col2");
  4768. col2.append('<h4>Debug Level</h4><div class="btn-group-sm" role="group" data-toggle="buttons">' +
  4769. '<label class="btn btn-primary"><input type="radio" name="DebugLevel" id="DebugNone" autocomplete="off" value=0>None</label>' +
  4770. '<label class="btn btn-primary"><input type="radio" name="DebugLevel" id="DebugLow" autocomplete="off" value=1>Low</label>' +
  4771. '<label class="btn btn-primary"><input type="radio" name="DebugLevel" id="DebugHigh" autocomplete="off" value=2>High</label>' +
  4772. '</div>');
  4773. $('input[name="DebugLevel"]:radio[value='+window.cobbler.debugLevel +']').parent().addClass("active");
  4774. $('input[name="DebugLevel"]').change( function() {window.cobbler.debugLevel = $(this).val();});
  4775.  
  4776. col2.append('<h4>Virus Popper</h4><h5>Milliseconds between shots</h5><div id="mspershot-group" class="input-group input-group-sm"> <input type="text" id="mspershot-textbox" class="form-control" placeholder="1-2000 (Default: 100)"' +
  4777. 'value=' + cobbler.msDelayBetweenShots.toString() + '><span class="input-group-addon">ms</span></div><h6>145ms = 7 shots per second. Lower values are faster but less stable.</h6>');
  4778. $('#mspershot-textbox').on('input propertychange paste', function() {
  4779. var newval = parseInt(this.value);
  4780. if(!_.isNaN(newval) && newval > 0 && newval <= 2000) {
  4781. $("#mspershot-group").removeClass('has-error');
  4782. cobbler.msDelayBetweenShots = newval;
  4783. }
  4784. else{
  4785. $("#mspershot-group").addClass('has-error');
  4786. }
  4787. });
  4788.  
  4789. col2.append('<h4>Minimap Scale</h4>' +
  4790. '<div id="minimap-group" class="input-group input-group-sm"><span class="input-group-addon"><input id="minimap-checkbox" type="checkbox"></span>' +
  4791. '<input id="minimap-textbox" type="text" placeholder="64 = 1/64 scale" class="form-control" value='+ cobbler.miniMapScaleValue +'></div>');
  4792. $('#minimap-checkbox').change(function(){
  4793. if(!!this.checked){
  4794. $('#minimap-textbox').removeAttr("disabled");
  4795. } else {
  4796. $('#minimap-textbox').attr({disabled:"disabled"})
  4797. }
  4798. cobbler.miniMapScale = !!this.checked;
  4799. });
  4800. if(cobbler.miniMapScale){$('#minimap-checkbox').prop('checked', true);}else{ $('#minimap-textbox').attr({disabled:"disabled"})}
  4801. $('#minimap-textbox').on('input propertychange paste', function() {
  4802. var newval = parseInt(this.value);
  4803. if(!_.isNaN(newval) && newval > 1 && newval < 999) {
  4804. $("#minimap-group").removeClass('has-error');
  4805. cobbler.miniMapScaleValue = newval;
  4806. }
  4807. else{
  4808. $("#minimap-group").addClass('has-error');
  4809. }
  4810. });
  4811.  
  4812. col2.append('<h4>Grazer</h4><div id="grazer-checks" class="checkbox" ></div>');
  4813. var grazerChecks = $("#grazer-checks");
  4814. AppendCheckbox(grazerChecks, 'autorespawn-checkbox', ' Grazer Auto-Respawns', window.cobbler.autoRespawn, function(val){window.cobbler.autoRespawn = val;});
  4815. AppendCheckbox(grazerChecks, 'option5', ' Visualize Grazer', window.cobbler.visualizeGrazing, function(val){window.cobbler.visualizeGrazing = val;});
  4816. AppendCheckbox(grazerChecks, 'grazer-multiBlob-checkbox', ' Grazer MultiBlob', window.cobbler.grazerMultiBlob2, function(val){window.cobbler.grazerMultiBlob2 = val;});
  4817.  
  4818. col2.append('<h5>Hybrid Grazer</h5>' +
  4819. '<div id="hybrid-group" class="input-group input-group-sm"><span class="input-group-addon"><input id="hybrid-checkbox" type="checkbox"></span>' +
  4820. '<input id="hybrid-textbox" type="text" class="form-control" value='+ cobbler.grazerHybridSwitchMass +' placeholder="Default: 300"></div>' +
  4821. '<h6>Starts with old grazer and at specified mass switches to new grazer</h6>');
  4822. $('#hybrid-checkbox').change(function(){
  4823. if(!!this.checked){
  4824. $('#hybrid-textbox').removeAttr("disabled");
  4825. } else {
  4826. $('#hybrid-textbox').attr({disabled:"disabled"})
  4827. }
  4828. cobbler.grazerHybridSwitch = !!this.checked;
  4829. });
  4830. if(cobbler.grazerHybridSwitch){$('#hybrid-checkbox').prop('checked', true);}else{ $('#hybrid-textbox').attr({disabled:"disabled"})}
  4831. $('#hybrid-textbox').on('input propertychange paste', function() {
  4832. var newval = parseInt(this.value);
  4833. if(!_.isNaN(newval)) {
  4834. $("#hybrid-group").removeClass('has-error');
  4835. cobbler.grazerHybridSwitchMass = newval;
  4836. }
  4837. else{
  4838. $("#hybrid-group").addClass('has-error');
  4839. }
  4840. });
  4841.  
  4842.  
  4843. var col3 = $("#col3");
  4844. col3.append("<h4>Music/Sound</h4>");
  4845. col3.append('<p>Sound Effects<input id="sfx" type="range" value=' + window.cobbler.sfxVol + ' step=".1" min="0" max="1" oninput="volSFX(this.value);"></p>');
  4846. col3.append('<p>Music<input type="range" id="bgm" value=' + window.cobbler.bgmVol + ' step=".1" min="0" max="1" oninput="volBGM(this.value);"></p>');
  4847. col3.append('<h4>Skins Support</h4>');
  4848. AppendCheckboxP(col3, 'amConnect-checkbox', ' AgarioMods Connect *skins', window.cobbler.amConnectSkins, function(val){window.cobbler.amConnectSkins = val;});
  4849. AppendCheckboxP(col3, 'amExtended-checkbox', ' AgarioMods Extended skins', window.cobbler.amExtendedSkins, function(val){window.cobbler.amExtendedSkins = val;});
  4850. AppendCheckboxP(col3, 'imgur-checkbox', ' Imgur.com i/skins', window.cobbler.imgurSkins, function(val){window.cobbler.imgurSkins = val;});
  4851.  
  4852. // ---- Tooltips
  4853. $("#rainbow-checkbox").attr({"data-toggle": "tooltip", "data-placement": "right",
  4854. "title": "Allow food pellets to be rainbow colored rather than purple. Combines well with Lite Brite Mode"});
  4855. $("#litebrite-checkbox").attr({"data-toggle": "tooltip", "data-placement": "right",
  4856. "title": "Leaves blob centers empty except for skins."});
  4857. setTimeout(function(){$(function () { $('[data-toggle="tooltip"]').tooltip()})}, 5000); // turn on all tooltips.
  4858.  
  4859. // Ugly ass hack to fix effects of official code loading before mod
  4860. //$("#canvas").remove();
  4861. //$("body").prepend('<canvas id="canvas" width="800" height="600"></canvas>');
  4862.  
  4863.  
  4864.  
  4865.  
  4866. //================================ Skins from skins.AgarioMods.com ===================================================
  4867.  
  4868. var agariomodsSkins = ("0chan;18-25;1up;360nati0n;8ball;UmguwJ0;aa9skillz;ace;adamzonetopmarks;advertisingmz;agariomods.com;al sahim;alaska;albania;alchestbreach;alexelcapo;algeria;am3nlc;amoodiesqueezie;amway921wot;amyleethirty3;anarchy;android;angrybirdsnest;angryjoeshow;animebromii;anonymous;antvenom;aperture;apple;arcadego;assassinscreed;atari;athenewins;authenticgames;avatar;aviatorgaming;awesome;awwmuffin;aypierre;baka;balenaproductions;bandaid;bane;baseball;bashurverse;basketball;bateson87;batman;battlefield;bdoubleo100;beats;bebopvox;belarus;belgium;bender;benderchat;bereghostgames;bert;bestcodcomedy;bielarus;bitcoin;bjacau1;bjacau2;black widow;blackiegonth;blitzwinger;blobfish;bluexephos;bluh;blunty3000;bobross;bobsaget;bodil30;bodil40;bohemianeagle;boo;boogie2988;borg;bowserbikejustdance;bp;breakfast;breizh;brksedu;buckballs;burgundy;butters;buzzbean11;bystaxx;byzantium;calfreezy;callofduty;captainsparklez;casaldenerd;catalonia;catalunya;catman;cavemanfilms;celopand;chaboyyhd;chaika;chaosxsilencer;chaoticmonki;charlie615119;charmander;chechenya;checkpointplus;cheese;chickfila;chimneyswift11;chocolate;chrisandthemike;chrisarchieprods;chrome;chucknorris;chuggaaconroy;cicciogamer89;cinnamontoastken;cirno;cj;ckaikd0021;clanlec;clashofclansstrats;cling on;cobanermani456;coca cola;codqg;coisadenerd;cokacola;colombia;colombiaa;commanderkrieger;communitygame;concrafter;consolesejogosbrasil;controless ;converse;cookie;coolifegame;coookie;cornella;cornellà;coruja;craftbattleduty;creeper;creepydoll;criken2;criousgamers;cristian4games;csfb;cuba;cubex55;cyberman65;cypriengaming;cyprus;czech;czechia;czechrepublic;d7297ut;d7oomy999;dagelijkshaadee;daithidenogla;darduinmymenlon;darksideofmoon;darksydephil;darkzerotv;dashiegames;day9tv;deadloxmc;deadpool;deal with it;deathly hallows;deathstar;debitorlp;deigamer;demon;derp;desu;dhole;diabl0x9;dickbutt;dilleron;dilleronplay;direwolf20;dissidiuswastaken;dnb;dnermc;doge;doggie;dolan;domo;domokun;donald;dong;donut;doraemon;dotacinema;douglby;dpjsc08;dreamcast;drift0r;drunken;dspgaming;dusdavidgames;dykgaming;ea;easports;easportsfootball;eatmydiction1;eavision;ebin;eeoneguy;egg;egoraptor;eguri89games;egypt;eksi;electrokitty;electronicartsde;elementanimation;elezwarface;eligorko;elrubiusomg;enzoknol;eowjdfudshrghk;epicface;ethoslab;exetrizegamer;expand;eye;facebook;fantabobgames;fast forward;fastforward;favijtv;fazeclan;fbi;fer0m0nas;fernanfloo;fgteev;fidel;fiji;finn;fir4sgamer;firefox;fishies;flash;florida;fnatic;fnaticc;foe;folagor03;forcesc2strategy;forocoches;frankieonpcin1080p;freeman;freemason;friesland;frigiel;frogout;fuckfacebook;fullhdvideos4me;funkyblackcat;gaben;gabenn;gagatunfeed;gamebombru;gamefails;gamegrumps;gamehelper;gameloft;gamenewsofficial;gameplayrj;gamerspawn;games;gameshqmedia;gamespot;gamestarde;gametrailers;gametube;gamexplain;garenavietnam;garfield;gassymexican;gaston;geilkind;generikb;germanletsfail;getinmybelly;getinthebox;ghostrobo;giancarloparimango11;gimper;gimperr;github;giygas;gizzy14gazza;gnomechild;gocalibergaming;godsoncoc;gogomantv;gokoutv;goldglovetv;gommehd;gona89;gonzo;gonzossm;grammar nazi;grayhat;grima;gronkh;grumpy;gtamissions;gtaseriesvideos;guccinoheya;guilhermegamer;guilhermeoss;gurren lagann;h2odelirious;haatfilms;hagrid;halflife;halflife3;halo;handicapped;hap;hassanalhajry;hatty;hawaii;hawkeye;hdluh;hdstarcraft;heartrockerchannel;hebrew;heisenburg;helix;helldogmadness;hikakingames;hikeplays;hipsterwhale;hispachan;hitler;homestuck;honeycomb;hosokawa;hue;huskymudkipz;huskystarcraft;hydro;iballisticsquid;iceland;ie;igameplay1337;ignentertainment;ihascupquake;illuminati;illuminatiii;ilvostrocarodexter;imaqtpie;imgur;immortalhdfilms;imperial japan;imperialists;imperialjapan;imvuinc;insanegaz;insidegaming;insidersnetwork;instagram;instalok;inthelittlewood;ipodmail;iron man;isaac;isamuxpompa;isis;isreal;itchyfeetleech;itsjerryandharry;itsonbtv;iulitm;ivysaur;izuniy;jackfrags;jacksepticeye;jahovaswitniss;jahrein;jaidefinichon;james bond;jamesnintendonerd;jamonymow;java;jellyyt;jeromeasf;jew;jewnose;jibanyan;jimmies;jjayjoker;joeygraceffagames;johnsju;jontronshow;josemicod5;joueurdugrenier;juegagerman;jumpinthepack;jupiter;kalmar union;kame;kappa;karamba728;kenny;keralis;kiloomobile;kingdomoffrance;kingjoffrey;kinnpatuhikaru;kirby;kitty;kjragaming;klingon;knekrogamer;knights templar;knightstemplar;knowyourmeme;kootra;kripparrian;ksiolajidebt;ksiolajidebthd;kuplinovplay;kurdistan;kwebbelkop;kyle;kyokushin4;kyrsp33dy;ladle;laggerfeed;lazuritnyignom;ldshadowlady;le snake;lenny;letsplay;letsplayshik;letstaddl;level5ch;levelcapgaming;lgbt;liberland;libertyy;liechtenstien;lifesimmer;linux;lisbug;littlelizardgaming;llessur;loadingreadyrun;loki;lolchampseries;lonniedos;love;lpmitkev;luigi;luke4316;m3rkmus1c;macedonia;machinimarealm;machinimarespawn;magdalenamariamonika;mahalovideogames;malena010102;malta;mario;mario11168;markipliergame;mars;maryland;masterball;mastercheif;mateiformiga;matroix;matthdgamer;matthewpatrick13;mattshea;maxmoefoegames;mcdonalds;meatboy;meatwad;meatwagon22;megamilk;messyourself;mickey;mike tyson;mike;miles923;minecraftblow;minecraftfinest;minecraftuniverse;miniladdd;miniminter;minnesotaburns;minnie;mkiceandfire;mlg;mm7games;mmohut;mmoxreview;mod3rnst3pny;moldova;morealia;mortalkombat;mr burns;mr.bean;mr.popo;mrchesterccj;mrdalekjd;mredxwx;mrlev12;mrlololoshka;mrvertez;mrwoofless;multirawen;munchingorange;n64;naga;namcobandaigameseu;nasa;natusvinceretv;nauru;nazi;nbgi;needforspeed;nepenthez;nextgentactics;nextgenwalkthroughs;ngtzombies;nick fury;nick;nickelodeon;niichts;nintendo;nintendocaprisun;nintendowiimovies;nipple;nislt;nobodyepic;node;noobfromua;northbrabant;northernlion;norunine;nosmoking;notch;nsa;obama;obey;officialclashofclans;officialnerdcubed;oficialmundocanibal;olafvids;omfgcata;onlyvgvids;opticnade;osu;ouch;outsidexbox;p3rvduxa;packattack04082;palau;paluten;pandaexpress;paulsoaresjr;pauseunpause;pazudoraya;pdkfilms;peanutbuttergamer;pedo;pedobear;peinto1008;peka;penguin;penguinz0;pepe;pepsi;perpetuumworld;pewdiepie;pi;pietsmittie;pig;piggy;pika;pimpnite;pinkfloyd;pinkstylist;pirate;piratebay;pizza;pizzaa;plagasrz;plantsvszombies;playclashofclans;playcomedyclub;playscopetrailers;playstation;playstation3gaminghd;pockysweets;poketlwewt;pooh;poop;popularmmos;potato;prestonplayz;protatomonster;prowrestlingshibatar;pt;pur3pamaj;quantum leap;question;rageface;rajmangaminghd;retard smile;rewind;rewinside;rezendeevil;reziplaygamesagain;rfm767;riffer333;robbaz;rockalone2k;rockbandprincess1;rockstar;rockstargames;rojov13;rolfharris;roomba;roosterteeth;roviomobile;rspproductionz;rss;rusgametactics;ryukyu;s.h.e.i.l.d;sah4rshow;samoa;sara12031986;sarazarlp;satan;saudi arabia;scream;screwattack;seal;seananners;serbia;serbiangamesbl;sethbling;sharingan;shell;shine;shofu;shrek;shufflelp;shurikworld;shuuya007;sinistar;siphano13;sir;skillgaming;skinspotlights;skkf;skull;skydoesminecraft;skylandersgame;skype;skyrim;slack;slovakia;slovenia;slowpoke;smash;smikesmike05;smoothmcgroove;smoove7182954;smoshgames;snafu;snapchat;snoop dogg;soccer;soliare;solomid;somalia;sp4zie;space ace;space;sparklesproduction;sparkofphoenix;spawn;speedyw03;speirstheamazinghd;spiderman;spongegar;spore;spqr;spy;squareenix;squirtle;ssohpkc;sssniperwolf;ssundee;stalinjr;stampylonghead;star wars rebel;starbucks;starchild;starrynight;staxxcraft;stitch;stupid;summit1g;sunface;superevgexa;superman;superskarmory;swiftor;swimmingbird941;syria;t3ddygames;tackle4826;taco;taltigolt;tasselfoot;tazercraft;tbnrfrags;tctngaming;teamfortress;teamgarrymoviethai;teammojang;terrorgamesbionic;tetraninja;tgn;the8bittheater;thealvaro845;theatlanticcraft;thebajancanadian;thebraindit;thecraftanos;thedanirep;thedeluxe4;thediamondminecart;theescapistmagazine;thefantasio974;thegaminglemon;thegrefg;thejoves;thejwittz;themasterov;themaxmurai;themediacows;themrsark;thepolishpenguinpl;theradbrad;therelaxingend;therpgminx;therunawayguys;thesims;theskylanderboy;thesw1tcher;thesyndicateproject;theuselessmouth;thewillyrex;thnxcya;thor;tintin;tmartn;tmartn2;tobygames;tomo0723sw;tonga;topbestappsforkids;totalhalibut;touchgameplay;transformer;transformers;trickshotting;triforce;trollarchoffice;trollface;trumpsc;tubbymcfatfuck;turkey;tv;tvddotty;tvongamenet;twitch;twitter;twosyncfifa;typicalgamer;uberdanger;uberhaxornova;ubisoft;uguu;ukip;ungespielt;uppercase;uruguay;utorrent;vanossgaming;vatican;venomextreme;venturiantale;videogamedunkey;videogames;vietnam;vikkstar123;vikkstar123hd;vintagebeef;virus;vladnext3;voat;voyager;vsauce3;w1ldc4t43;wakawaka;wales;walrus;wazowski;wewlad;white light;whiteboy7thst;whoyourenemy;wiiriketopray;willyrex;windows;wingsofredemption;wit my woes;woodysgamertag;worldgamingshows;worldoftanks;worldofwarcraft;wowcrendor;wqlfy;wroetoshaw;wwf;wykop;xalexby11;xbox;xboxviewtv;xbulletgtx;xcalizorz;xcvii007r1;xjawz;xmandzio;xpertthief;xrpmx13;xsk;yamimash;yarikpawgames;ycm;yfrosta;yinyang;ylilauta;ylilautaa;yoba;yobaa;yobaaa;yogscast2;yogscastlalna;yogscastsips;yogscastsjin;yoteslaya;youalwayswin;yourheroes;yourmom;youtube;zackscottgames;zangado;zazinombies;zeecrazyatheist;zeon;zerkaahd;zerkaaplays;zexyzek;zimbabwe;zng;zoella;zoidberg;zombey;zoomingames").split(";");