// ==UserScript==
// @name Nolans Mod
// @version 0.7
// @description Agario Mod ITS BACK
// @author Nolan
// @match http://agar.io
// @match https://agar.io
// @match http://agarserv.com
// @match https://agarserv.com
// @changes 0.1 - Stats now detects viruses being eaten
// 0.2 - Upgraded zoom functions
// 0.3 - Some zoom bug fixes
// 0.4 - protocol breakage fix
// 0.5 - fixed my fuckup
// 0.6 - Click-to-lock added
// 0.7 - Fixed It So I Can Not Be Sued
// @require https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @namespace
// ==/UserScript==
var _version_ = GM_info.script.version;
var debugMonkeyReleaseMessage = "<h3>Protocol Changes and Burnout</h3><p>" +
"Hey guys. I've patched the no-movement issue. Sorry for the inconvenience and for the delay in making a fix. <br><br>" +
"I've been a bit burnt out on Agar.io so I've been taking it easy." +
"You guys are the real MVPs.<br>" +
"<img src='http://i.imgur.com/p4zv6vx.jpg'><br><br>-A1ien";
//if (window.top != window.self) //-- Don't run on frames or iframes
// return;
//https://cdn.rawgit.com/pockata/blackbird-js/1e4c9812f8e6266bf71a25e91cb12a553e7756f4/blackbird.js
//https://raw.githubusercontent.com/pockata/blackbird-js/cc2dc268b89e6345fa99ca6109ddaa6c22143ad0/blackbird.css
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.4.1/canvas.min.js");
$.getScript("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js");
unsafeWindow.connect2 = unsafeWindow.connect;
jQuery("#canvas").remove();
jQuery("#connecting").after('<canvas id="canvas" width="800" height="600"></canvas>');
(function(d, f) {
// Options that will always be reset on reload
var zoomFactor = 10;
var isGrazing = false;
var serverIP = "";
var showVisualCues = true;
// Game State & Info
var highScore = 0;
var timeSpawned = null;
var grazzerTargetResetRequest = false;
var nearestVirusID;
var suspendMouseUpdates = false;
var grazingTargetFixation = false;
var selectedBlobID = null;
// Constants
var Huge = 2.66,
Large = 1.25,
Small = 0.7,
Tiny = 0.375;
var Huge_Color = "#FF3C3C",
Large_Color = "#FFBF3D",
Same_Color = "#FFFF00",
Small_Color = "#00AA00",
Tiny_Color = "#CC66FF",
myColor ="#3371FF",
virusColor ="#666666";
var lastMouseCoords = { x: 0, y: 0 };
var ghostBlobs = [];
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>')
.appendTo(jQuery('body'))
.get(0)
.getContext("2d");
// cobbler is the object that holds all user options. Options that should never be persisted can be defined here.
// If an option setting should be remembered it can
var cobbler = {
set grazingMode(val) {isGrazing = val;},
get grazingMode() {return isGrazing;},
minimapScaleCurrentValue : 1,
"displayMiniMap" : true,
};
// utility function to simplify creation of options whose state should be persisted to disk
function simpleSavedSettings(optionsObject){
_.forEach(optionsObject, function(defaultValue, settingName){
var backingVar = '_' + settingName;
cobbler[backingVar] = GM_getValue(settingName, defaultValue),
Object.defineProperty(cobbler, settingName, {
get: function() { return this[backingVar];},
set: function(val) { this[backingVar] = val; GM_setValue(settingName, val); }
});
});
}
// defines all options that should be persisted along with their default values.
function makeCobbler(){
var optionsAndDefaults = {
"isLiteBrite" : true,
"sfxVol" : 0.5,
"bgmVol" : 0.5,
"drawTail" : false,
"splitGuide" : true,
"rainbowPellets" : true,
"debugLevel" : 1,
"imgurSkins" : true,
"amExtendedSkins" : true,
"amConnectSkins" : true,
"namesUnderBlobs" : false,
"grazerMultiBlob2" : false,
"grazerHybridSwitch": false,
"grazerHybridSwitchMass" : 300,
"gridLines" : true,
"autoRespawn" : false,
"visualizeGrazing" : true,
"msDelayBetweenShots" : 100,
"miniMapScale" : false,
"miniMapScaleValue" : 64,
"enableBlobLock" : false,
'nextOnBlobLock' : false,
'rightClickFires' : false,
'showZcStats' : true,
};
simpleSavedSettings(optionsAndDefaults);
}
makeCobbler();
window.cobbler = cobbler;
// ====================== Property & Var Name Restoration =======================================================
var zeach = {
get connect() {return Aa;}, // Connect
get ctx() {return g;}, // g_context
get webSocket() {return r;}, // g_socket
get myIDs() {return K;}, // g_playerCellIds
get myPoints() {return m;}, // g_playerCells
get allNodes() {return D;}, // g_cellsById
get allItems() {return v;}, // g_cells
get mouseX2() {return fa;}, // g_moveX
get mouseY2() {return ga;}, // g_moveY
get mapLeft() {return oa;}, // g_minX
get mapTop() {return pa;}, // g_minY
get mapRight() {return qa;}, // g_maxX
get mapBottom() {return ra;}, // g_maxY
get isShowSkins() {return fb;}, // g_showSkins
// "g_showNames": "va",
get isNightMode() {return sa;}, // ??
get isShowMass() {return gb;}, // ??
get gameMode() {return O;}, // g_mode
get fireFunction() {return G;}, // SendCmd
get isColors() {return Ka;}, // g_noColors
get defaultSkins() {return jb;}, // g_skinNamesA
get imgCache() {return T;}, // ???
get textFunc() {return ua;}, // CachedCanvas
get textBlobs() {return Bb;}, // g_skinNamesB
get hasNickname() {return va;}, // g_showNames
get scale() {return k;}, //
// Classes
get CachedCanvas() {return ua;}, // CachedCanvas
get Cell() {return aa;}, //
// These never existed before but are useful
get mapWidth() {return ~~(Math.abs(zeach.mapLeft) + zeach.mapRight);},
get mapHeight() {return ~~(Math.abs(zeach.mapTop) + zeach.mapBottom);},
};
function restoreCanvasElementObj(objPrototype){
var canvasElementPropMap = {
'setValue' : 'C', //
'render' : 'L', //
'setScale' : 'ea', //
'setSize' : 'M', //
};
_.forEach(canvasElementPropMap, function(newPropName,oldPropName){
Object.defineProperty(objPrototype, oldPropName, {
get: function() { return this[newPropName];},
set: function(val) { this[newPropName] = val; }
});
});
}
// Cell
function restorePointObj(objPrototype){
var pointPropMap = {
'isVirus' : 'h', //
'nx' : 'J', //
'ny' : 'K', //
'setName' : 'B', //
'nSize' : 'q', //
'ox' : 's', //
'oy' : 't', //
'oSize' : 'r', //
'destroy' : 'X', //
'maxNameSize' : 'l', //
'massText' : 'O', //
'nameCache' : 'o', //
'isAgitated' : 'n'
};
_.forEach(pointPropMap, function(newPropName,oldPropName){
Object.defineProperty(objPrototype, oldPropName, {
get: function() { return this[newPropName];},
set: function(val) { this[newPropName] = val; }
});
});
}
// ====================== Utility code ==================================================================
function isFood(blob){
return (blob.nSize < 15);
}
function getSelectedBlob(){
if(!_.contains(zeach.myIDs, selectedBlobID)){
selectedBlobID = zeach.myPoints[0].id;
//console.log("Had to select new blob. Its id is " + selectedBlobID);
}
return zeach.allNodes[selectedBlobID];
}
function isPlayerAlive(){
return !!zeach.myPoints.length;
}
function sendMouseUpdate(ws, mouseX2, mouseY2, blob) {
lastMouseCoords = {x: mouseX2, y: mouseY2};
if (ws && ws.readyState == ws.OPEN) {
var blobId = blob ? blob.id : 0;
var z0 = new ArrayBuffer(13);
var z1 = new DataView(z0);
z1.setUint8(0, 16);
z1.setInt32(1, mouseX2, true);
z1.setInt32(5, mouseY2, true);
z1.setUint32(9, blobId, true);
ws.send(z0);
}
}
function getMass(x){
return x*x/100;
}
function lineDistance( point1, point2 ){
var xs = point2.nx - point1.nx;
var ys = point2.ny - point1.ny;
return Math.sqrt( xs * xs + ys * ys );
}
function getVirusShotsNeededForSplit(cellSize){
return ~~((149-cellSize)/7);
}
function calcTTR(element){
var totalMass = _.sum(_.pluck(zeach.myPoints, "nSize").map(getMass));
return ~~((((totalMass*0.02)*1000)+30000) / 1000) - ~~((Date.now() - element.splitTime) / 1000);
}
function getBlobShotsAvailable(blob) {
return ~~(Math.max(0, (getMass(blob.nSize)-(35-18))/18));
}
function distanceFromCellZero(blob) {
return isPlayerAlive() ? lineDistance(blob, getSelectedBlob()) :
Math.sqrt((zeach.mapRight - zeach.mapLeft) * (zeach.mapRight - zeach.mapLeft) + (zeach.mapBottom - zeach.mapTop) * (zeach.mapBottom - zeach.mapTop));
}
function getViewport(interpolated) {
var x = _.sum(_.pluck(zeach.myPoints, interpolated ? "x" : "nx")) / zeach.myPoints.length;
var y = _.sum(_.pluck(zeach.myPoints, interpolated ? "y" : "ny")) / zeach.myPoints.length;
var totalRadius = _.sum(_.pluck(zeach.myPoints, interpolated ? "size" : "nSize"));
var zoomFactor = Math.pow(Math.min(64.0 / totalRadius, 1), 0.4);
var deltaX = 1024 / zoomFactor;
var deltaY = 600 / zoomFactor;
return { x: x, y: y, dx: deltaX, dy: deltaY };
}
function getMouseCoordsAsPseudoBlob(){
return {
"x": zeach.mouseX2,
"y": zeach.mouseY2,
"nx": zeach.mouseX2,
"ny": zeach.mouseY2,
};
}
// ====================== Grazing code ==================================================================
function checkCollision(myBlob, targetBlob, potential){
// Calculate distance to target
var dtt = lineDistance(myBlob, targetBlob);
// Slope and normal slope
var sl = (targetBlob.ny-myBlob.ny)/(targetBlob.nx-myBlob.nx);
var ns = -1/sl;
// y-int of ptt
var yint1 = myBlob.ny - myBlob.nx*sl;
if(!(lineDistance(myBlob, potential) < dtt)){
// get second y-int
var yint2 = potential.ny - potential.nx * ns;
var interx = (yint2-yint1)/(sl-ns);
var intery = sl*interx + yint1;
var pseudoblob = {};
pseudoblob.nx = interx;
pseudoblob.ny = intery;
if (((targetBlob.nx < myBlob.nx && targetBlob.nx < interx && interx < myBlob.nx) ||
(targetBlob.nx > myBlob.nx && targetBlob.nx > interx && interx > myBlob.nx)) &&
((targetBlob.ny < myBlob.ny && targetBlob.ny < intery && intery < myBlob.ny) ||
(targetBlob.ny > myBlob.ny && targetBlob.ny > intery && intery > myBlob.ny))){
if(lineDistance(potential, pseudoblob) < potential.size+100){
return true;
}
}
}
return false;
}
function isSafeTarget(myBlob, targetBlob, threats){
var isSafe = true;
// check target against each enemy to make sure no collision is possible
threats.forEach(function (threat){
if(isSafe) {
if(threat.isVirus) {
//todo once we are big enough, our center might still be far enough
// away that it doesn't cross virus but we still pop
if(checkCollision(myBlob, targetBlob, threat) ) {
isSafe = false;
}
}
else {
if ( checkCollision(myBlob, targetBlob, threat) || lineDistance(threat, targetBlob) <= threat.size + 200) {
isSafe = false;
}
}
}
});
return isSafe;
}
// All blobs that aren't mine
function getOtherBlobs(){
return _.omit(zeach.allNodes, zeach.myIDs);
}
// Gets any item which is a threat including bigger players and viruses
function getThreats(blobArray, myMass) {
// start by omitting all my IDs
// then look for viruses smaller than us and blobs substantially bigger than us
return _.filter(getOtherBlobs(), function(possibleThreat){
var possibleThreatMass = getMass(possibleThreat.size);
if(possibleThreat.isVirus) {
// Viruses are only a threat if we are bigger than them
return myMass >= possibleThreatMass;
}
// other blobs are only a threat if they cross the 'Large' threshhold
return possibleThreatMass > myMass * Large;
});
}
var throttledResetGrazingTargetId = null;
function doGrazing() {
var i;
if(!isPlayerAlive()) {
//isGrazing = false;
return;
}
if(null === throttledResetGrazingTargetId){
throttledResetGrazingTargetId = _.throttle(function (){
grazzerTargetResetRequest = 'all';
//console.log(~~(Date.now()/1000));
}, 200);
}
if (grazzerTargetResetRequest == 'all') {
grazzerTargetResetRequest = false;
for(i = 0; i < zeach.myPoints.length; i++) {
zeach.myPoints[i].grazingTargetID = false;
}
} else if (grazzerTargetResetRequest == 'current') {
var pseudoBlob = getMouseCoordsAsPseudoBlob();
pseudoBlob.size = getSelectedBlob().size;
//pseudoBlob.scoreboard = scoreboard;
var newTarget = findFoodToEat_old(pseudoBlob,zeach.allItems);
if(-1 == newTarget){
isGrazing = false;
return;
}
getSelectedBlob().grazingTargetID = newTarget.id;
}
// with target fixation on, target remains until it's eaten by someone or
// otherwise disappears. With it off target is constantly recalculated
// at the expense of CPU
if(!grazingTargetFixation) {
throttledResetGrazingTargetId();
}
var target;
var targets = findFoodToEat(!cobbler.grazerMultiBlob2);
for(i = 0; i < zeach.myPoints.length; i++) {
var point = zeach.myPoints[i];
if (!cobbler.grazerMultiBlob2 && point.id != getSelectedBlob().id) {
continue;
}
point.grazingMode = isGrazing;
if(cobbler.grazerHybridSwitch) {
var mass = getMass(point.nSize);
// switch over to new grazer once we pass the threshhold
if(1 === point.grazingMode && mass > cobbler.grazerHybridSwitchMass){
point.grazingMode = 2; // We gained enough much mass. Use new grazer.
}else if(2 === point.grazingMode && mass < cobbler.grazerHybridSwitchMass ){
point.grazingMode = 1; // We lost too much mass. Use old grazer.
}
}
switch(point.grazingMode) {
case 1: {
if(!zeach.allNodes.hasOwnProperty(point.grazingTargetID)) {
target = findFoodToEat_old(point, zeach.allItems);
if(-1 == target){
point.grazingMode = 2;
return;
}
point.grazingTargetID = target.id;
} else {
target = zeach.allNodes[point.grazingTargetID];
}
if (!cobbler.grazerMultiBlob2) {
sendMouseUpdate(zeach.webSocket, target.x + Math.random(), target.y + Math.random());
} else {
sendMouseUpdate(zeach.webSocket, target.x + Math.random(), target.y + Math.random(), point);
}
break;
}
case 2: {
if (!cobbler.grazerMultiBlob2) {
target = _.max(targets, "v");
sendMouseUpdate(zeach.webSocket, target.x + Math.random(), target.y + Math.random());
} else {
target = targets[point.id];
sendMouseUpdate(zeach.webSocket, target.x + Math.random(), target.y + Math.random(), point);
}
break;
}
}
}
}
function dasMouseSpeedFunction(id, cx, cy, radius, nx, ny) {
this.cx = cx; this.cy = cy; this.radius = radius; this.nx = nx; this.ny = ny;
this.value = function(x, y) {
x -= this.cx; y -= this.cy;
var lensq = x*x + y*y;
var len = Math.sqrt(lensq);
var val = x * this.nx + y * this.ny;
if (len > this.radius) {
return {
id : id,
v: val / len,
dx: y * (this.nx * y - this.ny * x) / (lensq * len),
dy: x * (this.ny * x - this.nx * y) / (lensq * len),
};
} else {
return {id: id, v: val / this.radius, dx: this.nx, dy: this.ny};
}
};
}
function dasBorderFunction(l, t, r, b, w) {
this.l = l;
this.t = t;
this.r = r;
this.b = b;
this.w = w;
this.value = function(x, y) {
var v = 0, dx = 0, dy = 0;
if (x < this.l) {
v += this.l - x;
dx = -this.w;
} else if (x > this.r) {
v += x - this.r;
dx = this.w;
}
if (y < this.t) {
v += this.t - y;
dy = -this.w;
} else if (y > this.b) {
v += y - this.b;
dy = this.w;
}
return {v: v * this.w, dx: dx, dy: dy};
};
}
function dasSumFunction(sumfuncs) {
this.sumfuncs = sumfuncs;
this.value = function(x, y) {
return sumfuncs.map(function(func) {
return func.value(x, y);
}).reduce(function (acc, val) {
acc.v += val.v; acc.dx += val.dx; acc.dy += val.dy;
return acc;
});
};
}
function gradient_ascend(func, step, iters, id, x, y) {
var max_step = step;
var last = func.value(x, y);
while(iters > 0) {
iters -= 1;
x += last.dx * step;
y += last.dy * step;
var tmp = func.value(x, y);
if (tmp.v < last.v) {
step /= 2;
} else {
step = Math.min(2 * step, max_step);
}
//console.log([x, y, tmp[0], step]);
last.v = tmp.v;
last.dx = (last.dx + tmp.dx)/2.0;
last.dy = (last.dy + tmp.dy)/2.0;
}
return {id: id, x: x, y: y, v: last.v};
}
function augmentBlobArray(blobArray) {
blobArray = blobArray.slice();
var curTimestamp = Date.now();
// Outdated blob id set
var ghostSet = [];
blobArray.forEach(function (element) {
ghostSet[element.id] = true;
element.lastTimestamp = curTimestamp;
});
var viewport = getViewport(false);
ghostBlobs = _.filter(ghostBlobs, function (element) {
return !ghostSet[element.id] && // a fresher blob with the same id doesn't exist in blobArray already
(curTimestamp - element.lastTimestamp < 10000) && // last seen no more than 10 seconds ago
(
(Math.abs(viewport.x - element.nx) > (viewport.dx + element.nSize) * 0.9) ||
(Math.abs(viewport.y - element.ny) > (viewport.dy + element.nSize) * 0.9)
); // outside of firmly visible area, otherwise there's no need to remember it
});
ghostBlobs.forEach(function (element) {
blobArray.push(element);
});
ghostBlobs = blobArray;
return blobArray;
}
function findFoodToEat(useGradient) {
blobArray = augmentBlobArray(zeach.allItems);
zeach.myPoints.forEach(function(cell) {
cell.gr_is_mine = true;
});
var accs = zeach.myPoints.map(function (cell) {
var per_food = [], per_threat = [];
var acc = {
id : cell.id,
fx: 0,
fy: 0,
x: cell.nx,
y: cell.ny,
size : cell.nSize,
per_food: per_food,
per_threat: per_threat,
cumulatives: [ { x: 0, y: 0}, { x: 0, y: 0} ],
};
if (!useGradient && cell.grazingMode != 2) {
return acc;
}
var totalMass = _.sum(_.pluck(zeach.myPoints, "nSize").map(getMass));
// Avoid walls too
var wallArray = [];
wallArray.push({id: -2, nx: cell.nx, ny: zeach.mapTop - 1, nSize: cell.nSize * 30});
wallArray.push({id: -3, nx: cell.nx, ny: zeach.mapBottom + 1, nSize: cell.nSize * 30});
wallArray.push({id: -4, ny: cell.ny, nx: zeach.mapLeft - 1, nSize: cell.nSize * 30});
wallArray.push({id: -5, ny: cell.ny, nx: zeach.mapRight + 1, nSize: cell.nSize * 30});
wallArray.forEach(function(el) {
// Calculate repulsion vector
var vec = { id: el.id, gr_type: true, x: cell.nx - el.nx, y: cell.ny - el.ny };
var dist = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
// Normalize it to unit length
vec.x /= dist;
vec.y /= dist;
// Walls have pseudo-size to generate repulsion, but we can move farther.
dist += cell.nSize / 2.0;
dist = Math.max(dist, 0.01);
// Walls. Hate them muchly.
dist /= 10;
// The more we're split and the more we're to lose, the more we should be afraid.
dist /= cell.nSize * Math.sqrt(zeach.myPoints.length);
// The farther they're from us the less repulsive/attractive they are.
vec.x /= dist;
vec.y /= dist;
if(!isFinite(vec.x) || !isFinite(vec.y)) {
return;
}
// Save element-produced force for visualization
per_threat.push(vec);
// Sum forces from all threats
acc.fx += vec.x;
acc.fy += vec.y;
});
blobArray.forEach(function(el) {
var vec = { id: el.id, x: cell.nx - el.nx, y: cell.ny - el.ny };
if(el.gr_is_mine) {
return; //our cell, ignore
} else if( !el.isVirus && (getMass(el.nSize) * 4 <= getMass(cell.nSize) * 3)) {
//if(!el.isVirus && (getMass(el.nSize) <= 9)) {
//vec.gr_type = null; //edible
} else if (!el.isVirus && (getMass(el.nSize) * 3 < (getMass(cell.nSize) * 4))) {
return; //not edible ignorable
// TODO: shouldn't really be so clear-cut. Must generate minor repulsion/attraction depending on size.
} else {
vec.gr_type = true; //threat
}
// Calculate repulsion vector
var dist = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
// Normalize it to unit length
vec.x /= dist;
vec.y /= dist;
if(el.nSize > cell.nSize) {
if(el.isVirus) {
// Viruses are only a threat if they're smaller than us
return;
}
// Distance till consuming
dist -= el.nSize;
dist += cell.nSize / 3.0;
dist -= 11;
dist = Math.max(dist, 0.01);
// Prioritize targets by size
if(!vec.gr_type) {
//Non-threat
dist /= el.nSize;
} else {
var ratio = getMass(el.nSize) / getMass(cell.nSize);
// Cells that 1 to 8 times bigger are the most dangerous.
// Prioritize them by a truncated parabola up to 6 times.
// when we are fractured into small parts, we might underestimate
// how cells a lot bigger than us can be interested in us as a conglomerate of mass.
// So calculate threat index for our total mass too.
var ratio2 = getMass(el.nSize) / totalMass;
if(ratio2 < 4.5 && ratio > 4.5) {
ratio2 = 4.5;
}
ratio = Math.min(5, Math.max(0, - (ratio - 1) * (ratio - 8))) + 1;
ratio2 = Math.min(5, Math.max(0, - (ratio2 - 1) * (ratio2 - 8))) + 1;
ratio = Math.max(ratio, ratio2);
// The more we're split and the more we're to lose, the more we should be afraid.
dist /= ratio * cell.nSize * Math.sqrt(zeach.myPoints.length);
}
} else {
// Distance till consuming
dist += el.nSize * 1 / 3;
dist -= cell.nSize;
dist -= 11;
if(el.isVirus) {
if(zeach.myPoints.length >= 16 ) {
// Can't split anymore so viruses are actually a good food!
delete vec.gr_type; //vec.gr_type = null;
} else {
// Hate them a bit less than same-sized blobs.
dist *= 2;
}
}
dist = Math.max(dist, 0.01);
// Prioritize targets by size
dist /= el.nSize;
}
if(!vec.gr_type) {
//Not a threat. Make it attractive.
dist = -dist;
}
// The farther they're from us the less repulsive/attractive they are.
vec.x /= dist;
vec.y /= dist;
if(!isFinite(vec.x) || !isFinite(vec.y)) {
return;
}
// Save element-produced force for visualization
(vec.gr_type ? per_threat : per_food).push(vec);
// Sum forces per target type
var cumul = acc.cumulatives[!vec.gr_type ? 1 : 0];
cumul.x += vec.x;
cumul.y += vec.y;
});
// Sum forces from all sources
acc.fx += _.sum(_.pluck(acc.cumulatives, "x"));
acc.fy += _.sum(_.pluck(acc.cumulatives, "y"));
// Save resulting info for visualization
cell.grazeInfo = acc;
return acc;
});
if (useGradient) {
var funcs = accs.map(function(acc) {
return new dasMouseSpeedFunction(acc.id, acc.x, acc.y, 200, acc.fx, acc.fy);
});
// Pick gradient ascent step size for better convergence
// so that coord jumps don't exceed ~50 units
var step = _.sum(accs.map(function(acc) {
return Math.sqrt(acc.fx * acc.fx + acc.fy * acc.fy);
}));
step = 50 / step;
if(!isFinite(step)) {
step = 50;
}
var viewport = getViewport(false);
funcs.push(
new dasBorderFunction(
viewport.x - viewport.dx,
viewport.y - viewport.dy,
viewport.x + viewport.dx,
viewport.y + viewport.dy,
-1000
)
);
var func = new dasSumFunction(funcs);
var results = accs.map(function(acc) {
return gradient_ascend(func, step, 100, acc.id, acc.x, acc.y);
});
} else {
results = accs.map(function(acc) {
var norm = Math.sqrt(acc.fx * acc.fx + acc.fy * acc.fy);
return {id: acc.id, x: acc.x + 200 * acc.fx / norm, y: acc.y + 200 * acc.fy / norm };
});
}
var reply = {};
for (var i = 0; i < results.length; i++) {
reply[results[i].id] = {id : -5, x : results[i].x, y : results[i].y, v : results[i].v};
}
return reply;
}
function findFoodToEat_old(cell, blobArray){
var edibles = [];
var densityResults = [];
var threats = getThreats(blobArray, getMass(cell.size));
blobArray.forEach(function (element){
var distance = lineDistance(cell, element);
if (!element.isSafeTarget) {
element.isSafeTarget = {};
}
element.isSafeTarget[cell.id] = null;
if( getMass(element.size) <= (getMass(cell.size) * 0.4) && !element.isVirus){
if(isSafeTarget(cell, element, threats)){
edibles.push({"distance":distance, "id":element.id});
element.isSafeTarget[cell.id] = true;
} else {
element.isSafeTarget[cell.id] = false;
}
}
});
edibles = edibles.sort(function(x,y){return x.distance<y.distance?-1:1;});
edibles.forEach(function (element){
var density = calcFoodDensity(cell, zeach.allNodes[element.id], blobArray)/(element.distance*2);
densityResults.push({"density":density, "id":element.id});
});
if(0 === densityResults.length){
//console.log("No target found");
return avoidThreats(threats, cell);
return -1;
}
var target = densityResults.sort(function(x,y){return x.density>y.density?-1:1;});
//console.log("Choosing blob (" + target[0].id + ") with density of : "+ target[0].isVirusensity);
return zeach.allNodes[target[0].id];
}
function avoidThreats(threats, cell){
// Avoid walls too
threats.push({x: cell.x, y: zeach.mapTop - 1, size: 1});
threats.push({x: cell.x, y: zeach.mapBottom + 1, size: 1});
threats.push({y: cell.y, x: zeach.mapLeft - 1, size: 1});
threats.push({y: cell.y, x: zeach.mapRight + 1, size: 1});
var direction = threats.reduce(function(acc, el) {
// Calculate repulsion vector
var vec = { x: cell.x - el.x, y: cell.y - el.y };
var dist = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
// Normalize it to unit length
vec.x /= dist;
vec.y /= dist;
// Take enemy cell size into account
dist -= el.size;
// The farther they're from us the less repulsive they are
vec.x /= dist;
vec.y /= dist;
// Sum forces from all threats
acc.x += vec.x;
acc.y += vec.y;
return acc;
}, {x: 0, y: 0});
// Normalize force to unit direction vector
var dir_norm = Math.sqrt(direction.x * direction.x + direction.y * direction.y);
direction.x /= dir_norm;
direction.y /= dir_norm;
if(!isFinite(direction.x) || !isFinite(direction.y)) {
return -1;
}
return { id: -5, x: cell.x + direction.x * cell.size * 5, y: cell.y + direction.y * cell.size * 5 };
}
function calcFoodDensity(cell, cell2, blobArray2){
var MaxDistance2 = 250;
var pelletCount = 0;
blobArray2.forEach(function (element2){
var distance2 = lineDistance(cell2, element2);
var cond1 = getMass(element2.size) <= (getMass(cell.size) * 0.4);
var cond2 = distance2 < MaxDistance2;
var cond3 = !element2.isVirus;
//console.log(cond1 + " " + distance2 + " " + cell2.isSafeTarget);
if( cond1 && cond2 && cond3 && cell2.isSafeTarget[cell.id] ){
pelletCount +=1;
}
});
return pelletCount;
}
// ====================== UI stuff ==================================================================
function drawRescaledItems(ctx) {
if (showVisualCues && isPlayerAlive()) {
drawMapBorders(ctx);
drawGrazingLines_old(ctx);
drawGrazingLines(ctx);
if(cobbler.drawTail){
drawTrailTail(ctx);
}
drawSplitGuide(ctx, getSelectedBlob());
drawMiniMap();
}
}
function getScoreBoardExtrasString(F) {
var extras = " ";
if (showVisualCues) {
highScore = Math.max(highScore, ~~(F / 100));
extras += " High: " + highScore.toString();
if (isPlayerAlive()) {
extras += "" + isPlayerAlive() ? " Alive: " + (~~((Date.now() - timeSpawned) / 1000)).toString() : "";
}
}
return extras;
}
function drawCellInfos(noColors, ctx) {
var color = this.color;
if (showVisualCues) {
color = setCellColors(this, zeach.myPoints);
if (this.isVirus) {
if (!zeach.allNodes.hasOwnProperty(nearestVirusID))
nearestVirusID = this.id;
else if (distanceFromCellZero(this) < distanceFromCellZero(zeach.allNodes[nearestVirusID]))
nearestVirusID = this.id;
}
if(noColors) {
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#AAAAAA"
}
else {
ctx.fillStyle = color;
ctx.strokeStyle = (this.id == nearestVirusID) ? "red" : color
}
}
}
function drawMapBorders(ctx) {
if (zeach.isNightMode) {
ctx.strokeStyle = '#FFFFFF';
}
ctx.beginPath();
ctx.moveTo(zeach.mapLeft, zeach.mapTop); // 0
ctx.lineTo(zeach.mapRight, zeach.mapTop); // >
ctx.lineTo(zeach.mapRight, zeach.mapBottom); // V
ctx.lineTo(zeach.mapLeft, zeach.mapBottom); // <
ctx.lineTo(zeach.mapLeft, zeach.mapTop); // ^
ctx.stroke();
}
function drawSplitGuide(ctx, cell) {
if( !isPlayerAlive() || !cobbler.splitGuide){
return;
}
var radius = 660;
var centerX = cell.x;
var centerY = cell.y;
var hold = ctx.globalAlpha;
ctx.beginPath();
ctx.arc(centerX, centerY, radius+cell.size, 0, 2 * Math.PI, false);
ctx.lineWidth = 2;
ctx.strokeStyle = '#FF0000';
ctx.stroke();
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.lineWidth = 2;
ctx.strokeStyle = '#00FF00';
ctx.stroke();
ctx.globalAlpha = hold;
}
function isTeamMode(){
return (zeach.gameMode === ":teams");
}
function setCellColors(cell,myPoints){
if(!showVisualCues){
return cell.color;
}
if(cobbler.rainbowPellets && isFood(cell)){
return cell.color;
}
var color = cell.color;
if (myPoints.length > 0 && !isTeamMode()) {
var size_this = getMass(cell.size);
var size_that = ~~(getSelectedBlob().size * getSelectedBlob().size / 100);
if (cell.isVirus || myPoints.length === 0) {
color = virusColor;
} else if (~myPoints.indexOf(cell)) {
color = myColor;
} else if (size_this > size_that * Huge) {
color = Huge_Color;
} else if (size_this > size_that * Large) {
color = Large_Color;
} else if (size_this > size_that * Small) {
color = Same_Color;
} else if (size_this > size_that * Tiny) {
color = Small_Color;
} else {
color = Tiny_Color;
}
}
return color;
}
function displayDebugText(ctx, agarTextFunction) {
if(0 >= cobbler.debugLevel) {
return;
}
var textSize = 15;
var debugStrings = [];
if(1 <= cobbler.debugLevel) {
debugStrings.push("v " + _version_);
debugStrings.push("Server: " + serverIP);
debugStrings.push("G - grazing: " + (isGrazing ? (1 == isGrazing) ? "Old" : "New" : "Off"));
}
if(2 <= cobbler.debugLevel) {
debugStrings.push("M - suspend mouse: " + (suspendMouseUpdates ? "On" : "Off"));
debugStrings.push("P - grazing target fixation :" + (grazingTargetFixation ? "On" : "Off"));
if(grazingTargetFixation){ debugStrings.push(" (T) to retarget");}
debugStrings.push("O - right click: " + (cobbler.rightClickFires ? "Fires @ virus" : "Default"))
debugStrings.push("Z - zoom: " + zoomFactor.toString());
if (isPlayerAlive()) {
debugStrings.push("Location: " + Math.floor(getSelectedBlob().x) + ", " + Math.floor(getSelectedBlob().y));
}
}
var offsetValue = 20;
var text = new agarTextFunction(textSize, (zeach.isNightMode ? '#F2FBFF' : '#111111'));
for (var i = 0; i < debugStrings.length; i++) {
text.setValue(debugStrings[i]); // setValue
var textRender = text.render();
ctx.drawImage(textRender, 20, offsetValue);
offsetValue += textRender.height;
}
}
// Probably isn't necessary to throttle it ... but what the hell.
var rescaleMinimap = _.throttle(function(){
var minimapScale = cobbler.miniMapScaleValue;
var scaledWidth = ~~(zeach.mapWidth/minimapScale);
var scaledHeight = ~~(zeach.mapHeight/minimapScale);
var minimap = jQuery("#mini-map");
if(minimap.width() != scaledWidth || minimap.height() != scaledHeight || cobbler.minimapScaleCurrentValue != minimapScale){
// rescale the div
minimap.width(scaledWidth);
minimap.height(scaledHeight);
// rescale the canvas element
minimap[0].width = scaledWidth;
minimap[0].height = scaledHeight;
cobbler.minimapScaleCurrentValue = minimapScale;
}
}, 5*1000);
function drawMiniMap() {
rescaleMinimap();
var minimapScale = cobbler.miniMapScaleValue;
miniMapCtx.clearRect(0, 0, ~~(zeach.mapWidth/minimapScale), ~~(zeach.mapHeight/minimapScale));
_.forEach(_.values(getOtherBlobs()), function(blob){
miniMapCtx.strokeStyle = blob.isVirus ? "#33FF33" : 'rgb(52,152,219)' ;
miniMapCtx.beginPath();
miniMapCtx.arc((blob.nx+Math.abs(zeach.mapLeft)) / minimapScale, (blob.ny+Math.abs(zeach.mapTop)) / minimapScale, blob.size / minimapScale, 0, 2 * Math.PI);
miniMapCtx.stroke();
});
_.forEach(zeach.myPoints, function(myBlob){
miniMapCtx.strokeStyle = "#FFFFFF";
miniMapCtx.beginPath();
miniMapCtx.arc((myBlob.nx+Math.abs(zeach.mapLeft)) / minimapScale, (myBlob.ny+Math.abs(zeach.mapTop)) / minimapScale, myBlob.size / minimapScale, 0, 2 * Math.PI);
miniMapCtx.stroke();
});
}
function drawLine(ctx, point1, point2, color){
ctx.strokeStyle = color;
ctx.beginPath();
ctx.moveTo(point1.x, point1.y);
ctx.lineTo(point2.x, point2.y);
ctx.stroke();
}
function drawGrazingLines(ctx) {
if(!isGrazing || !cobbler.visualizeGrazing || !isPlayerAlive())
{
//console.log("returning early");
return;
}
var oldLineWidth = ctx.lineWidth;
var oldColor = ctx.color;
var oldGlobalAlpha = ctx.globalAlpha;
zeach.myPoints.forEach(function(playerBlob) {
if(!playerBlob.grazeInfo || playerBlob.grazingMode != 2) {
return;
}
var grazeInfo = playerBlob.grazeInfo;
var nullVec = { x: 0, y: 0 };
var cumulatives = grazeInfo.cumulatives;
var maxSize = 0.001;
// Render threat forces
grazeInfo.per_threat.forEach(function (grazeVec){
var element = zeach.allNodes[grazeVec.id];
if(!element) return; //Wall or dead or something
//drawLine(ctx,element, playerBlob, "red" );
//drawLine(ctx,element, {x: element.x + grazeVec.x / maxSize, y: element.y + grazeVec.y / maxSize }, "red" );
drawLine(ctx,playerBlob, {x: playerBlob.x + grazeVec.x / maxSize, y: playerBlob.y + grazeVec.y / maxSize }, "red" );
var grazeVecLen = Math.sqrt(grazeVec.x * grazeVec.x + grazeVec.y * grazeVec.y);
ctx.globalAlpha = 0.5 / zeach.myPoints.length;
ctx.beginPath();
ctx.arc(element.x, element.y, grazeVecLen / maxSize / 20, 0, 2 * Math.PI, false);
ctx.fillStyle = 'red';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#FFFFFF';
ctx.stroke();
ctx.globalAlpha = 1;
});
if(zeach.myPoints.length <= 1) {
// If we're not fragmented, render fancy food forces
grazeInfo.per_food.forEach(function (grazeVec){
var element = zeach.allNodes[grazeVec.id];
if(!element) return; //Wall or dead or something
//drawLine(ctx,element, playerBlob, "white" );
drawLine(ctx,element, {x: element.x + grazeVec.x / maxSize, y: element.y + grazeVec.y / maxSize }, "green" );
//drawLine(ctx,playerBlob, {x: playerBlob.x + grazeVec.x / maxSize, y: playerBlob.y + grazeVec.y / maxSize }, "green" );
});
}
// Prepare to render cumulatives
maxSize *= grazeInfo.per_threat.length + grazeInfo.per_food.length;
maxSize /= 10;
ctx.lineWidth = 10;
// Render summary force without special forces, like walls
drawLine(ctx,playerBlob,
{
x: playerBlob.x + (cumulatives[0].x + cumulatives[1].x) / maxSize,
y: playerBlob.y + (cumulatives[0].y + cumulatives[1].y) / maxSize,
}, "gray"
);
// Render foods and threats force cumulatives
drawLine(ctx,playerBlob, {x: playerBlob.x + cumulatives[1].x / maxSize, y: playerBlob.y + cumulatives[1].y / maxSize }, "green" );
drawLine(ctx,playerBlob, {x: playerBlob.x + cumulatives[0].x / maxSize, y: playerBlob.y + cumulatives[0].y / maxSize }, "red" );
// Render summary force with special forces, like walls
ctx.lineWidth = 5;
drawLine(ctx,playerBlob, {x: playerBlob.x + (grazeInfo.fx) / maxSize, y: playerBlob.y + (grazeInfo.fy) / maxSize }, "orange" );
ctx.lineWidth = 1;
drawLine(ctx,playerBlob, {x: playerBlob.x + 300 * (grazeInfo.fx) / maxSize, y: playerBlob.y + 300 * (grazeInfo.fy) / maxSize }, "orange" );
});
var viewport = getViewport(true);
// Render sent mouse coords as a small circle
ctx.globalAlpha = 0.5;
ctx.beginPath();
ctx.arc(lastMouseCoords.x, lastMouseCoords.y, 0.01 * viewport.dx, 0, 2 * Math.PI, false);
ctx.fillStyle = 'red';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = zeach.isNightMode ? '#FFFFFF' : '#000000';
ctx.stroke();
ctx.globalAlpha = 1;
// Render viewport borders, useful for blob lookout and 10-sec-memoization debugging
ctx.strokeStyle = zeach.isNightMode ? '#FFFFFF' : '#000000';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(viewport.x - viewport.dx, viewport.y - viewport.dy);
ctx.lineTo(viewport.x + viewport.dx, viewport.y - viewport.dy);
ctx.lineTo(viewport.x + viewport.dx, viewport.y + viewport.dy);
ctx.lineTo(viewport.x - viewport.dx, viewport.y + viewport.dy);
ctx.lineTo(viewport.x - viewport.dx, viewport.y - viewport.dy);
ctx.stroke();
ctx.globalAlpha = oldGlobalAlpha;
ctx.lineWidth = oldLineWidth;
ctx.color = oldColor;
}
function drawTrailTail(ctx) {
// Render trailing tail that indicates real movement,
// based on the difference between client-interpolated and real coords.
var trailScale = 5;
zeach.myPoints.forEach(function(playerBlob) {
var d = { x: playerBlob.nx - playerBlob.x, y: playerBlob.ny - playerBlob.y };
drawLine(ctx,playerBlob, {x: playerBlob.x - d.x * trailScale, y: playerBlob.y - d.y * trailScale }, myColor );
//drawLine(ctx,{x: playerBlob.ox, y: playerBlob.oy }, {x: playerBlob.nx, y: playerBlob.ny }, "green" );
});
}
function drawGrazingLines_old(ctx) {
if(!isGrazing || !cobbler.visualizeGrazing || !isPlayerAlive())
{
//console.log("returning early");
return;
}
var oldLineWidth = ctx.lineWidth;
var oldColor = ctx.color;
ctx.lineWidth = 10;
for(var i = 0; i < zeach.myPoints.length; i++) {
var point = zeach.myPoints[i];
if (point.grazingMode != 1) {
continue;
}
if(_.has(zeach.allNodes, point.grazingTargetID)){
drawLine(ctx, zeach.allNodes[point.grazingTargetID], point, "green");
}
}
ctx.lineWidth = 2;
for(var i = 0; i < zeach.myPoints.length; i++) {
var point = zeach.myPoints[i];
if (point.grazingMode != 1) {
continue;
}
zeach.allItems.forEach(function (element){
if (!element.isSafeTarget) {
} else if(element.isSafeTarget[point.id] === true) {
drawLine(ctx, element, point, "white" );
} else if (element.isSafeTarget[point.id] === false) {
drawLine(ctx, element, point, "red" );
} else {
//drawLine(ctx,element, getSelectedBlob(), "blue" );
}
})
}
ctx.lineWidth = oldLineWidth;
ctx.color = oldColor;
}
// ====================== Virus Popper ==================================================================
function findNearestVirus(cell, blobArray){
var nearestVirus = _.min(_.filter(blobArray, "isVirus", true), function(element) {
return lineDistance(cell, element);
});
if( Infinity == nearestVirus){
//console.log("No nearby viruses");
return -1;
}
return nearestVirus;
}
function fireAtVirusNearestToBlob(blob, blobArray) {
console.log("fireAtVirusNearestToBlob");
var msDelayBetweenShots = cobbler.msDelayBetweenShots;
nearestVirus = findNearestVirus(blob, blobArray);
if(-1 == nearestVirus){
console.log("No Nearby Virus Found");
console.log(blobArray);
console.log(blob);
return;
}
// TODO: count availableshots and limit shots sent to Math.min(shotsNeeded, ShotsAvailable)
var shotsNeeded = getVirusShotsNeededForSplit(nearestVirus.size);
var shotsFired = 0 / zeach.myPoints.length;
if(shotsNeeded <= 0){
return;
}
suspendMouseUpdates = true;
console.log("Nearest Virus at: ("+ nearestVirus.x + "," + nearestVirus.y + ") requires " + shotsNeeded + " shots.");
// two mouse updates in a row to make sure new position is locked in.
sendMouseUpdate(zeach.webSocket, nearestVirus.x + Math.random(), nearestVirus.y + Math.random());
window.setTimeout(function () { sendMouseUpdate(zeach.webSocket, nearestVirus.x + Math.random(), nearestVirus.y + Math.random()); }, 25);
// schedules all shots needed spaced evenly apart by of 'msDelayBetweenShots'
for ( ; shotsFired < shotsNeeded; shotsFired++){
window.setTimeout(function () {
sendMouseUpdate(zeach.webSocket, nearestVirus.x + Math.random(), nearestVirus.y + Math.random());
zeach.fireFunction(21);
}, msDelayBetweenShots *(shotsFired+1));
}
window.setTimeout(function () { suspendMouseUpdates = false;}, msDelayBetweenShots *(shotsFired+1));
}
function fireAtVirusNearestToCursor(){
fireAtVirusNearestToBlob(getMouseCoordsAsPseudoBlob(), zeach.allItems);
}
// ====================== Skins ==================================================================
/* AgarioMod.com skins have been moved to the very end of the file */
var extendedSkins = {
"billy mays" : "http://i.imgur.com/HavxFJu.jpg",
"stannis": "http://i.imgur.com/JyZr0CI.jpg",
"shrek is love" : "http://i.imgur.com/QDhkr4C.jpg",
"shrek is life" : "http://i.imgur.com/QDhkr4C.jpg",
"blueeyes" : "http://i.imgur.com/wxCfUws.jpg",
"ygritte" : "http://i.imgur.com/lDIFCT1.png",
"lord kience" : "http://i.imgur.com/b2UXk15.png",
}
var skinsSpecial = {
"white light": "https://i.imgur.com/4y8szAE.png",
"tubbymcfatfuck" : "http://tinyurl.com/TubbyMcFatFuck",
"texas doge" : "http://i.imgur.com/MVsLldL.jpg",
"doge helper" : "http://i.imgur.com/FzZebpk.jpg",
"controless " : "https://i.imgur.com/uD5SW8X.jpg",
"sqochit" : "http://i.imgur.com/AnowvFI.jpg",
"drunken" : "http://i.imgur.com/JeKNRss.png",
};
// special skins are defined in this script by me and are never translucent
function isSpecialSkin(targetName){
return skinsSpecial.hasOwnProperty(targetName.toLowerCase());
}
// special skins are defined in this script by me and can be translucent
function isExtendedSkin(targetName){
return _.has(extendedSkins, targetName.toLowerCase());
}
function isAgarioModsSkin(targetName){
if(!cobbler.amExtendedSkins){
return false;
}
return _.includes(agariomodsSkins, targetName)
}
function isImgurSkin(targetName){
if(!cobbler.imgurSkins){
return false;
}
return _.startsWith(targetName, "i/");
}
function isAMConnectSkin(targetName){
if(!cobbler.amConnectSkins){
return false;
}
return _.startsWith(targetName, "*");
}
function customSkins(cell, defaultSkins, imgCache, showSkins, gameMode) {
var retval = null;
var userName = cell.name;
var userNameLowerCase = userName.toLowerCase();
if(":teams" == gameMode)
{
retval = null;
}
else if(!cell.isAgitated && showSkins ){
if(-1 != defaultSkins.indexOf(userNameLowerCase) || isSpecialSkin(userNameLowerCase) || isImgurSkin(userNameLowerCase) ||
isAgarioModsSkin(userNameLowerCase) || isAMConnectSkin(userNameLowerCase) || isExtendedSkin(userNameLowerCase)){
if (!imgCache.hasOwnProperty(userNameLowerCase)){
if(isSpecialSkin(userNameLowerCase)) {
imgCache[userNameLowerCase] = new Image;
imgCache[userNameLowerCase].src = skinsSpecial[userNameLowerCase];
}
else if(isExtendedSkin(userNameLowerCase)) {
imgCache[userNameLowerCase] = new Image;
imgCache[userNameLowerCase].src = extendedSkins[userNameLowerCase];
}
else if(isAgarioModsSkin(userNameLowerCase)) {
imgCache[userNameLowerCase] = new Image;
imgCache[userNameLowerCase].src = "http://skins.agariomods.com/i/" + userNameLowerCase + ".png";
}
else if(isAMConnectSkin(userNameLowerCase)) {
console.log("is AmConnect skin")
imgCache[userNameLowerCase] = new Image;
imgCache[userNameLowerCase].src = "http://connect.agariomods.com/img_" + userNameLowerCase.slice(1) + ".png";
}
else if(isImgurSkin(userNameLowerCase)){
imgCache[userNameLowerCase] = new Image;
imgCache[userNameLowerCase].src = "http://i.imgur.com/"+ userName.slice(2) +".png";
}
else{
imgCache[userNameLowerCase] = new Image;
imgCache[userNameLowerCase].src = "skins/" + userNameLowerCase + ".png";
}
}
if(0 != imgCache[userNameLowerCase].width && imgCache[userNameLowerCase].complete) {
retval = imgCache[userNameLowerCase];
} else {
retval = null;
}
}
else {
retval = null;
}
}
else {
retval = null;
}
return retval;
}
// ====================== Draw Functions ==================================================================
function shouldRelocateName(){
if(cobbler.namesUnderBlobs && !this.isVirus) {
return true;
}
return ((isExtendedSkin(this.name)|| isSpecialSkin(this.name) || /*isBitDoSkin(this.name)||*/ isAMConnectSkin(this.name)));
}
function drawCellName(isMyCell, kbIndex, itemToDraw){
var yBasePos;
var nameCache = this.nameCache;
yBasePos = ~~this.y;
// Viruses have empty name caches. If this is a virus with an empty name cache
// then give it a name of the # of shots needed to split it.
if(null == nameCache) {
if (this.isVirus) {
var virusSize = this.nSize;
var shotsNeeded = getVirusShotsNeededForSplit(virusSize).toString();
this.setName(shotsNeeded);
} else if(!isFood(this)) {
this.setName(this.nSize.toString()); // Stupid blank cells. Give them a name.
}
}
if((zeach.hasNickname || isMyCell) && (this.name && (nameCache && (null == itemToDraw || -1 == zeach.textBlobs.indexOf(kbIndex)))) ) {
itemToDraw = nameCache;
itemToDraw.setValue(this.name);
setCellName(this, itemToDraw);
itemToDraw.setSize(this.maxNameSize());
var scale = Math.ceil(10 * zeach.scale) / 10;
itemToDraw.setScale(scale);
setVirusInfo(this, itemToDraw, scale);
itemToDraw = itemToDraw.render();
var xPos = ~~(itemToDraw.width / scale);
var yPos = ~~(itemToDraw.height / scale);
if(shouldRelocateName.call(this)) {
// relocate names to UNDER the cell rather than on top of it
zeach.ctx.drawImage(itemToDraw, ~~this.x - ~~(xPos / 2), yBasePos + ~~(yPos ), xPos, yPos);
yBasePos += itemToDraw.height / 2 / scale + 8;
}
else {
zeach.ctx.drawImage(itemToDraw, ~~this.x - ~~(xPos / 2), yBasePos - ~~(yPos / 2), xPos, yPos);
}
yBasePos += itemToDraw.height / 2 / scale + 4;
}
return yBasePos;
}
function drawCellMass(yBasePos, itemToDraw){
var massValue = (~~(getMass(this.size))).toString();
// Append shots to mass if visual cues are enabled
if(showVisualCues && _.contains(zeach.myIDs, this.id)){
massValue += " (" + getBlobShotsAvailable(this).toString() + ")";
}
if(zeach.isShowMass) {
var scale;
if(itemToDraw || 0 == zeach.myPoints.length && ((!this.isVirus || this.isAgitated) && 20 < this.size)) {
if(null == this.massText) {
this.massText = new zeach.CachedCanvas(this.maxNameSize() / 2, "#FFFFFF", true, "#000000");
}
itemToDraw = this.massText;
itemToDraw.setSize(this.maxNameSize() / 2);
itemToDraw.setValue(massValue); // precalculated & possibly appended
scale = Math.ceil(10 * zeach.scale) / 10;
itemToDraw.setScale(scale);
// Tweak : relocated mass is line is bigger than stock
itemToDraw.setScale(scale * ( shouldRelocateName.call(this) ? 2 : 1));
var e = itemToDraw.render();
var xPos = ~~(e.width / scale);
var yPos = ~~(e.height / scale);
if(shouldRelocateName.call(this)) {
// relocate mass to UNDER the cell rather than on top of it
zeach.ctx.drawImage(e, ~~this.x - ~~(xPos / 2), yBasePos + ~~(yPos), xPos, yPos);
}
else {
zeach.ctx.drawImage(e, ~~this.x - ~~(xPos / 2), yBasePos - ~~(yPos / 2), xPos, yPos);
}
}
}
}
// ====================== Misc ==================================================================
function switchCurrentBlob() {
var myids_sorted = _.pluck(zeach.myPoints, "id").sort(); // sort by id
var indexloc = _.indexOf(myids_sorted, selectedBlobID);
if(-1 === indexloc){
selectedBlobID = zeach.myPoints[0].id;
console.log("Had to select new blob. Its id is " + selectedBlobID);
return zeach.allNodes[selectedBlobID];
}
indexloc += 1;
if(indexloc >= myids_sorted.length){
selectedBlobID = zeach.myPoints[0].id;
console.log("Reached array end. Moving to beginning with id " + selectedBlobID);
return zeach.allNodes[selectedBlobID];
}
selectedBlobID = zeach.myPoints[indexloc].id;
return zeach.allNodes[selectedBlobID];
}
function customKeyDownEvents(d) {
//if('X'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
// jQuery("#overlays").hide();
// jQuery("#ZCOverlay").hide();
// isGrazing = 0;
// showVisualCues = true;
// suspendMouseUpdates = false;
// cobbler.enableBlobLock = false;
//}
if(jQuery("#overlays").is(':visible')){
return;
}
if(9 === d.keyCode && isPlayerAlive()) {
d.preventDefault();
switchCurrentBlob();
}
else if('A'.charCodeAt(0) === d.keyCode && isPlayerAlive()){
cobbler.isAcid = !cobbler.isAcid;
setAcid(cobbler.isAcid);
}
else if('C'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
grazzerTargetResetRequest = "all";
showVisualCues = !showVisualCues;
if(!showVisualCues) {
zoomFactor = 10;
jQuery("#mini-map").hide();
}
else
{
jQuery("#mini-map").show();
}
}
else if('E'.charCodeAt(0) === d.keyCode && isPlayerAlive()){
fireAtVirusNearestToCursor();
}
else if('G'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
if(cobbler.grazerHybridSwitch && isGrazing){
isGrazing = 0;
return;
}
grazzerTargetResetRequest = "all";
isGrazing = (2 == isGrazing) ? false : 2;
}
else if('H'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
if(cobbler.grazerHybridSwitch && isGrazing){
isGrazing = 0;
return;
}
grazzerTargetResetRequest = "all";
isGrazing = (1 == isGrazing) ? false : 1;
}
else if('M'.charCodeAt(0) === d.keyCode && isPlayerAlive()){
suspendMouseUpdates = !suspendMouseUpdates;
}
else if('O'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
cobbler.rightClickFires = !cobbler.rightClickFires;
}
else if('P'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
grazingTargetFixation = !grazingTargetFixation;
}
else if('R'.charCodeAt(0) === d.keyCode && isPlayerAlive()){
fireAtVirusNearestToBlob(getSelectedBlob(),zeach.allItems);
}
else if('T'.charCodeAt(0) === d.keyCode && isPlayerAlive() && (1 == isGrazing)) {
console.log("Retarget requested");
grazzerTargetResetRequest = "current";
}
else if('V'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
cobbler.visualizeGrazing = !cobbler.visualizeGrazing;
}
else if('Z'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
// /*old*/ zoomFactor = (zoomFactor == 10 ? 11 : 10);
/*new*/ zoomFactor = zoomFactor >= 11 ? 10 : +(zoomFactor + 0.1).toFixed(2);
}
else if('1'.charCodeAt(0) <= d.keyCode && '7'.charCodeAt(0) >= d.keyCode && isPlayerAlive()) {
var id = d.keyCode - '1'.charCodeAt(0);
if(id >= _.size(zeach.myPoints)) {return; }
var arr = _.sortBy(zeach.myPoints, "nSize").reverse();
selectedBlobID = arr[id].id;
}
else if('S'.charCodeAt(0) === d.keyCode && isPlayerAlive()) {
for(var i = 0; i < zeach.myPoints.length; i++) {
var point = zeach.myPoints[i];
point.locked = false;
}
}
}
function onAfterUpdatePacket() {
if (!isPlayerAlive()){
timeSpawned = null;
}
if(null == timeSpawned && isPlayerAlive()) {
timeSpawned = Date.now(); // it's been reported we miss some instances of player spawning
}
}
function onBeforeNewPointPacket() {
if (0 == _.size(zeach.myPoints)){
timeSpawned = Date.now();
}
}
function setCellName(cell, d) {
if (showVisualCues) {
var pct;
if (_.size(zeach.myPoints) > 1 && _.contains(zeach.myIDs, cell.id)) {
var oldestSplitTime = _.min(zeach.myPoints, "splitTime");
if(oldestSplitTime.id == cell.id){
d.setValue(cell.name);
} else {
pct = (cell.nSize * cell.nSize) * 100 / (getSelectedBlob().nSize * getSelectedBlob().nSize);
d.setValue(calcTTR(cell) + " ttr" + " " + ~~(pct) + "%");}
} else if (!cell.isVirus && isPlayerAlive()) {
pct = ~~((cell.nSize * cell.nSize) * 100 / (getSelectedBlob().nSize * getSelectedBlob().nSize));
d.setValue(cell.name + " " + pct.toString() + "%");
}
}
}
function setVirusInfo(cell, ctx, c) {
ctx.setScale(c * 1.25);
if (showVisualCues) {
if (cell.isVirus) {
cell.nameCache.setValue(getVirusShotsNeededForSplit(cell.nSize));
var nameSizeMultiplier = 4;
ctx.setScale(c * nameSizeMultiplier);
}
}
if (cell.isVirus && !showVisualCues) {
cell.nameCache.setValue(" ");
}
}
function sendMultyMouseUpdate(send_normal) {
for (var i = 0; i < zeach.myPoints.length; i++) {
var blob = zeach.myPoints[i];
var x = zeach.mouseX2;
var y = zeach.mouseY2;
if (blob.locked) {
blob.last_locked--;
if (blob.last_locked < 0) {
continue;
}
x = blob.locked_x;
y = blob.locked_y;
} else if (!send_normal) {
continue;
}
var z0 = new ArrayBuffer(13);
var z1 = new DataView(z0);
z1.setUint8(0, 16);
z1.setInt32(1, x, true);
z1.setInt32(5, y, true);
z1.setUint32(9, blob.id, true);
zeach.webSocket.send(z0);
}
}
function lockCurrentBlob() {
if(!isPlayerAlive()){
return;
}
var blob = getSelectedBlob();
if (blob.locked) {
blob.locked = false;
} else {
if (cobbler.nextOnBlobLock) {
switchCurrentBlob();
}
blob.locked = true;
blob.last_locked = 10;
blob.locked_x = zeach.mouseX2;
blob.locked_y = zeach.mouseY2;
}
}
// ====================== Start main ==================================================================
function kb() {
wa = true;
La();
setInterval(La, 18E4);
F = xa = document.getElementById("canvas");
g = F.getContext("2d");
// /*old*/ (/*new*/ /remap/) F.onmousewheel = function (e) {zoomFactor = e.wheelDelta > 0 ? 10 : 11;}
/*new*/ F.onmousewheel = function (e) {
if (e.wheelDelta > 0) {
zoomFactor = zoomFactor <= 9.50 ? 9.50 : +(zoomFactor - 0.05).toFixed(2);
} else {
zoomFactor = zoomFactor >= 11 ? 11 : +(zoomFactor + 0.05).toFixed(2);
}
};
F.onmousedown = function(a) {
/*new*/if(cobbler.enableBlobLock) {lockCurrentBlob();}
/*new*/if(isPlayerAlive() && cobbler.rightClickFires){fireAtVirusNearestToCursor();}return;
if (Ma) {
var c = a.clientX - (5 + q / 5 / 2);
var b = a.clientY - (5 + q / 5 / 2);
if (Math.sqrt(c * c + b * b) <= q / 5 / 2) {
U();
G(17);
return;
}
}
ca = a.clientX;
da = a.clientY;
ya();
U();
};
F.onmousemove = function(a) {
ca = a.clientX;
da = a.clientY;
ya();
};
F.onmouseup = function() {
};
if (/firefox/i.test(navigator.userAgent)) {
document.addEventListener("DOMMouseScroll", Na, false);
} else {
document.body.onmousewheel = Na;
}
var a = false;
var c = false;
var b = false;
d.onkeydown = function(e) {
if (!(32 != e.keyCode)) {
if (!a) {
U();
G(17);
a = true;
}
}
if (!(81 != e.keyCode)) {
if (!c) {
G(18);
c = true;
}
}
if (!(87 != e.keyCode)) {
if (!b) {
U();
G(21);
b = true;
}
}
if (27 == e.keyCode) {
Oa(true);
}
/*new*/customKeyDownEvents(e);
};
d.onkeyup = function(e) {
if (32 == e.keyCode) {
a = false;
}
if (87 == e.keyCode) {
b = false;
}
if (81 == e.keyCode) {
if (c) {
G(19);
c = false;
}
}
};
d.onblur = function() {
G(19);
b = c = a = false;
};
d.onresize = Pa;
d.requestAnimationFrame(Qa);
setInterval(U, 40);
if (x) {
f("#region").val(x);
}
Ra();
ea(f("#region").val());
if (0 == za) {
if (x) {
N();
}
}
V = true;
f("#overlays").show();
Pa();
}
function Na(a) {
// /*new*/ H *= Math.pow(0.9, a.wheelDelta / -120 || (a.detail || 0));
if (1 > H) {
H = 1;
}
if (H > 4 / k) {
H = 4 / k;
}
}
function lb() {
if (0.4 > k) {
W = null;
} else {
var a = Number.POSITIVE_INFINITY;
var c = Number.POSITIVE_INFINITY;
var b = Number.NEGATIVE_INFINITY;
var e = Number.NEGATIVE_INFINITY;
var l = 0;
var p = 0;
for (;p < v.length;p++) {
var h = v[p];
if (!!h.N()) {
if (!h.R) {
if (!(20 >= h.size * k)) {
l = Math.max(h.size, l);
a = Math.min(h.x, a);
c = Math.min(h.y, c);
b = Math.max(h.x, b);
e = Math.max(h.y, e);
}
}
}
}
W = mb.ja({
ca : a - (l + 100),
da : c - (l + 100),
ma : b + (l + 100),
na : e + (l + 100),
ka : 2,
la : 4
});
p = 0;
for (;p < v.length;p++) {
if (h = v[p], h.N() && !(20 >= h.size * k)) {
a = 0;
for (;a < h.a.length;++a) {
c = h.a[a].x;
b = h.a[a].y;
if (!(c < t - q / 2 / k)) {
if (!(b < u - s$$0 / 2 / k)) {
if (!(c > t + q / 2 / k)) {
if (!(b > u + s$$0 / 2 / k)) {
W.m(h.a[a]);
}
}
}
}
}
}
}
}
}
function ya() {
fa = (ca - q / 2) / k + t;
ga = (da - s$$0 / 2) / k + u;
}
function La() {
if (null == ha) {
ha = {};
f("#region").children().each(function() {
var a = f(this);
var c = a.val();
if (c) {
ha[c] = a.text();
}
});
}
f.get("https://m.agar.io/info", function(a) {
var c = {};
var b;
for (b in a.regions) {
var e = b.split(":")[0];
c[e] = c[e] || 0;
c[e] += a.regions[b].numPlayers;
}
for (b in c) {
f('#region option[value="' + b + '"]').text(ha[b] + " (" + c[b] + " players)");
}
}, "json");
}
function Sa() {
f("#adsBottom").hide();
f("#overlays").hide();
V = false;
Ra();
if (d.googletag) {
if (d.googletag.pubads && d.googletag.pubads().clear) {
d.googletag.pubads().clear(d.aa);
}
}
}
function ea(a) {
if (a) {
if (a != x) {
if (f("#region").val() != a) {
f("#region").val(a);
}
x = d.localStorage.location = a;
f(".region-message").hide();
f(".region-message." + a).show();
f(".btn-needs-server").prop("disabled", false);
if (wa) {
N();
}
}
}
}
function Oa(a) {
if (!V) {
I = null;
nb();
if (a) {
w = 1;
}
V = true;
f("#overlays").fadeIn(a ? 200 : 3E3);
/*new*//*mikey*/OnShowOverlay(a);
}
}
function ia(a) {
f("#helloContainer").attr("data-gamemode", a);
O = a;
f("#gamemode").val(a);
}
function Ra() {
if (f("#region").val()) {
d.localStorage.location = f("#region").val();
} else {
if (d.localStorage.location) {
f("#region").val(d.localStorage.location);
}
}
if (f("#region").val()) {
f("#locationKnown").append(f("#region"));
} else {
f("#locationUnknown").append(f("#region"));
}
}
function nb() {
if (ja) {
ja = false;
setTimeout(function() {
ja = true;
}, 6E4 * Ta);
if (d.googletag) {
if (d.googletag.pubads && d.googletag.pubads().clear) {
d.googletag.pubads().refresh(d.aa);
}
}
}
}
function X(a) {
return d.i18n[a] || (d.i18n_dict.en[a] || a);
}
function Ua() {
var a = ++za;
console.log("Find " + x + O);
f.ajax("https://m.agar.io/", {
error : function() {
setTimeout(Ua, 1E3);
},
success : function(c) {
if (a == za) {
c = c.split("\n");
if (c[2]) {
alert(c[2]);
}
Aa("ws://" + c[0], c[1]);
/*new*/ serverIP = c[0];
}
},
dataType : "text",
method : "POST",
cache : false,
crossDomain : true,
data : (x + O || "?") + "\n154669603"
});
}
function N() {
if (wa) {
if (x) {
f("#connecting").show();
Ua();
}
}
}
function Aa(a$$0, c) {
if (r) {
r.onopen = null;
r.onmessage = null;
r.onclose = null;
try {
r.close();
} catch (b$$0) {
}
r = null;
}
if (null != J) {
var e = J;
J = function() {
e(c);
};
}
if (ob) {
var l = a$$0.split(":");
a$$0 = l[0] + "s://ip-" + l[1].replace(/\./g, "-").replace(/\//g, "") + ".tech.agar.io:" + (+l[2] + 2E3);
}
K = [];
m = [];
D = {};
v = [];
P = [];
E = [];
y = z = null;
Q = 0;
ka = false;
console.log("Connecting to " + a$$0);
r = new WebSocket(a$$0);
r.binaryType = "arraybuffer";
r.onopen = function() {
var a;
console.log("socket open");
a = L(5);
a.setUint8(0, 254);
a.setUint32(1, 5, true);
M(a);
a = L(5);
a.setUint8(0, 255);
a.setUint32(1, 154669603, true);
M(a);
a = L(1 + c.length);
a.setUint8(0, 80);
var b = 0;
for (;b < c.length;++b) {
a.setUint8(b + 1, c.charCodeAt(b));
}
M(a);
Va();
};
r.onmessage = pb;
r.onclose = qb;
r.onerror = function() {
console.log("socket error");
};
}
function L(a) {
return new DataView(new ArrayBuffer(a));
}
function M(a) {
r.send(a.buffer);
}
function qb() {
if (ka) {
la = 500;
}
console.log("socket close");
setTimeout(N, la);
la *= 2;
}
function pb(a) {
rb(new DataView(a.data));
}
function rb(a) {
function c$$0() {
var c = "";
for (;;) {
var e = a.getUint16(b, true);
b += 2;
if (0 == e) {
break;
}
c += String.fromCharCode(e);
}
return c;
}
var b = 0;
if (240 == a.getUint8(b)) {
b += 5;
}
switch(a.getUint8(b++)) {
case 16:
sb(a, b);
/*new*/onAfterUpdatePacket();
break;
case 17:
Y = a.getFloat32(b, true);
b += 4;
Z = a.getFloat32(b, true);
b += 4;
$ = a.getFloat32(b, true);
b += 4;
break;
case 20:
m = [];
K = [];
break;
case 21:
Ba = a.getInt16(b, true);
b += 2;
Ca = a.getInt16(b, true);
b += 2;
if (!Da) {
Da = true;
ma = Ba;
na = Ca;
}
break;
case 32:
/*new*/onBeforeNewPointPacket();
K.push(a.getUint32(b, true));
b += 4;
break;
case 49:
if (null != z) {
break;
}
var e$$0 = a.getUint32(b, true);
b = b + 4;
E = [];
var l = 0;
for (;l < e$$0;++l) {
var p = a.getUint32(b, true);
b = b + 4;
E.push({
id : p,
name : c$$0()
});
}
Wa();
break;
case 50:
z = [];
e$$0 = a.getUint32(b, true);
b += 4;
l = 0;
for (;l < e$$0;++l) {
z.push(a.getFloat32(b, true));
b += 4;
}
Wa();
break;
case 64:
oa = a.getFloat64(b, true);
b += 8;
pa = a.getFloat64(b, true);
b += 8;
qa = a.getFloat64(b, true);
b += 8;
ra = a.getFloat64(b, true);
b += 8;
Y = (qa + oa) / 2;
Z = (ra + pa) / 2;
$ = 1;
if (0 == m.length) {
t = Y;
u = Z;
k = $;
}
break;
case 81:
var h = a.getUint32(b, true);
b = b + 4;
var d = a.getUint32(b, true);
b = b + 4;
var f = a.getUint32(b, true);
b = b + 4;
setTimeout(function() {
R({
e : h,
f : d,
d : f
});
}, 1200);
}
}
function sb(a, c) {
Xa = A = Date.now();
if (!ka) {
ka = true;
f("#connecting").hide();
Ya();
if (J) {
J();
J = null;
}
}
var b = Math.random();
Ea = false;
var e = a.getUint16(c, true);
c += 2;
var l = 0;
for (;l < e;++l) {
var p = D[a.getUint32(c, true)];
var h = D[a.getUint32(c + 4, true)];
c += 8;
if (p) {
if (h) {
/*new*//*mikey*//*remap*/OnCellEaten(p,h);
/*new*/// Remove from 10-sec-remembered cells list by id
/*new*//*remap*/_.remove(ghostBlobs, {id: h.id});
h.X();
h.s = h.x;
h.t = h.y;
h.r = h.size;
h.J = p.x;
h.K = p.y;
h.q = h.size;
h.Q = A;
}
}
}
l = 0;
for (;;) {
e = a.getUint32(c, true);
c += 4;
if (0 == e) {
break;
}
++l;
var d;
p = a.getInt32(c, true);
c += 4;
h = a.getInt32(c, true);
c += 4;
d = a.getInt16(c, true);
c += 2;
var g = a.getUint8(c++);
var k = a.getUint8(c++);
var q = a.getUint8(c++);
g = (g << 16 | k << 8 | q).toString(16);
for (;6 > g.length;) {
g = "0" + g;
}
g = "#" + g;
k = a.getUint8(c++);
q = !!(k & 1);
var s = !!(k & 16);
if (k & 2) {
c += 4;
}
if (k & 4) {
c += 8;
}
if (k & 8) {
c += 16;
}
var r;
var n = "";
for (;;) {
r = a.getUint16(c, true);
c += 2;
if (0 == r) {
break;
}
n += String.fromCharCode(r);
}
r = n;
n = null;
if (D.hasOwnProperty(e)) {
n = D[e];
n.P();
n.s = n.x;
n.t = n.y;
n.r = n.size;
n.color = g;
} else {
n = new aa(e, p, h, d, g, r);
v.push(n);
D[e] = n;
n.sa = p;
n.ta = h;
}
n.h = q;
n.n = s;
n.J = p;
n.K = h;
n.q = d;
n.qa = b;
n.Q = A;
n.ba = k;
if (r) {
n.B(r);
}
if (-1 != K.indexOf(e)) {
if (-1 == m.indexOf(n)) {
document.getElementById("overlays").style.display = "none";
m.push(n);
if (1 == m.length) {
/*new*//*mikey*/OnGameStart(zeach.myPoints);
t = n.x;
u = n.y;
Za();
}
}
}
}
b = a.getUint32(c, true);
c += 4;
l = 0;
for (;l < b;l++) {
e = a.getUint32(c, true);
c += 4;
n = D[e];
if (null != n) {
n.X();
}
}
if (Ea) {
if (0 == m.length) {
Oa(false);
}
}
}
function U() {
/*new*/if(isGrazing){ doGrazing(); return; }
/*new*/if(suspendMouseUpdates){return;}
var a;
if (S()) {
a = ca - q / 2;
var c = da - s$$0 / 2;
if (!(64 > a * a + c * c)) {
if (!(0.01 > Math.abs($a - fa) && 0.01 > Math.abs(ab - ga))) {
$a = fa;
ab = ga;
a = L(13);
a.setUint8(0, 16);
a.setInt32(1, fa, true);
a.setInt32(5, ga, true);
a.setUint32(9, 0, true);
M(a);
}
}
}
}
function Ya() {
if (S() && null != I) {
var a = L(1 + 2 * I.length);
a.setUint8(0, 0);
var c = 0;
for (;c < I.length;++c) {
a.setUint16(1 + 2 * c, I.charCodeAt(c), true);
}
M(a);
}
}
function S() {
return null != r && r.readyState == r.OPEN;
}
function G(a) {
if (S()) {
var c = L(1);
c.setUint8(0, a);
M(c);
}
}
function Va() {
if (S() && null != B) {
var a = L(1 + B.length);
a.setUint8(0, 81);
var c = 0;
for (;c < B.length;++c) {
a.setUint8(c + 1, B.charCodeAt(c));
}
M(a);
}
}
function Pa() {
q = d.innerWidth;
s$$0 = d.innerHeight;
xa.width = F.width = q;
xa.height = F.height = s$$0;
var a = f("#helloContainer");
a.css("transform", "none");
var c = a.height();
var b = d.innerHeight;
if (c > b / 1.1) {
a.css("transform", "translate(-50%, -50%) scale(" + b / c / 1.1 + ")");
} else {
a.css("transform", "translate(-50%, -50%)");
}
bb();
}
function cb() {
var a;
a = 1 * Math.max(s$$0 / 1080, q / 1920);
return a *= H;
}
function tb() {
if (0 != m.length) {
var a = 0;
var c = 0;
for (;c < m.length;c++) {
a += m[c].size;
}
a = Math.pow(Math.min(64 / a, 1), 0.4) * cb();
//k = (9 * k + a) / 10;
/*new*//*remap*/k = (9 * k + a) / zoomFactor;
}
}
function bb() {
var a$$0;
var c$$0 = Date.now();
++ub;
A = c$$0;
if (0 < m.length) {
tb();
var b = a$$0 = 0;
var e = 0;
for (;e < m.length;e++) {
m[e].P();
a$$0 += m[e].x / m.length;
b += m[e].y / m.length;
}
Y = a$$0;
Z = b;
$ = k;
t = (t + a$$0) / 2;
u = (u + b) / 2;
} else {
t = (29 * t + Y) / 30;
u = (29 * u + Z) / 30;
k = (9 * k + $ * cb()) / 10;
}
lb();
ya();
if (!Fa) {
g.clearRect(0, 0, q, s$$0);
}
if (Fa) {
g.fillStyle = sa ? "#111111" : "#F2FBFF";
g.globalAlpha = 0.05;
g.fillRect(0, 0, q, s$$0);
g.globalAlpha = 1;
} else {
vb();
}
v.sort(function(a, c) {
return a.size == c.size ? a.id - c.id : a.size - c.size;
});
g.save();
g.translate(q / 2, s$$0 / 2);
g.scale(k, k);
g.translate(-t, -u);
e = 0;
for (;e < P.length;e++) {
P[e].w(g);
}
e = 0;
for (;e < v.length;e++) {
v[e].w(g);
}
/*new*/drawRescaledItems(zeach.ctx);
if (Da) {
ma = (3 * ma + Ba) / 4;
na = (3 * na + Ca) / 4;
g.save();
g.strokeStyle = "#FFAAAA";
g.lineWidth = 10;
g.lineCap = "round";
g.lineJoin = "round";
g.globalAlpha = 0.5;
g.beginPath();
e = 0;
for (;e < m.length;e++) {
g.moveTo(m[e].x, m[e].y);
g.lineTo(ma, na);
}
g.stroke();
g.restore();
}
g.restore();
if (y) {
if (y.width) {
g.drawImage(y, q - y.width - 10, 10);
}
}
/*new*//*mikey*/OnDraw(zeach.ctx);
Q = Math.max(Q, wb());
/*new*//*remap*/ var extras = " " + getScoreBoardExtrasString(Q);
if (0 != Q) {
if (null == ta) {
ta = new ua(24, "#FFFFFF");
}
ta.C(X("score") + ": " + ~~(Q / 100));
/*new*/ /*remap*/ ta.setValue("Score: " + ~~(Q / 100) + extras);
b = ta.L();
a$$0 = b.width;
g.globalAlpha = 0.2;
g.fillStyle = "#000000";
g.fillRect(10, s$$0 - 10 - 24 - 10, a$$0 + 10, 34);
g.globalAlpha = 1;
g.drawImage(b, 15, s$$0 - 10 - 24 - 5);
/*new*//*mikey*//*remap*/(zeach.myPoints&&zeach.myPoints[0]&&OnUpdateMass(wb()));
}
xb();
c$$0 = Date.now() - c$$0;
if (c$$0 > 1E3 / 60) {
C -= 0.01;
} else {
if (c$$0 < 1E3 / 65) {
C += 0.01;
}
}
if (0.4 > C) {
C = 0.4;
}
if (1 < C) {
C = 1;
}
c$$0 = A - db;
if (!S() || V) {
w += c$$0 / 2E3;
if (1 < w) {
w = 1;
}
} else {
w -= c$$0 / 300;
if (0 > w) {
w = 0;
}
}
if (0 < w) {
g.fillStyle = "#000000";
g.globalAlpha = 0.5 * w;
g.fillRect(0, 0, q, s$$0);
g.globalAlpha = 1;
}
db = A;
/*new*/displayDebugText(zeach.ctx,zeach.textFunc);
}
function vb() {
g.fillStyle = sa ? "#111111" : "#F2FBFF";
g.fillRect(0, 0, q, s$$0);
/*new*/if(!cobbler.gridLines){return;}
g.save();
g.strokeStyle = sa ? "#AAAAAA" : "#000000";
g.globalAlpha = 0.2 * k;
var a = q / k;
var c = s$$0 / k;
var b = (-t + a / 2) % 50;
for (;b < a;b += 50) {
g.beginPath();
g.moveTo(b * k - 0.5, 0);
g.lineTo(b * k - 0.5, c * k);
g.stroke();
}
b = (-u + c / 2) % 50;
for (;b < c;b += 50) {
g.beginPath();
g.moveTo(0, b * k - 0.5);
g.lineTo(a * k, b * k - 0.5);
g.stroke();
}
g.restore();
}
function xb() {
if (Ma && Ga.width) {
var a = q / 5;
g.drawImage(Ga, 5, 5, a, a);
}
}
function wb() {
var a = 0;
var c = 0;
for (;c < m.length;c++) {
a += m[c].q * m[c].q;
}
return a;
}
function Wa() {
y = null;
if (null != z || 0 != E.length) {
if (null != z || va) {
y = document.createElement("canvas");
var a = y.getContext("2d");
var c = 60;
c = null == z ? c + 24 * E.length : c + 180;
var b = Math.min(200, 0.3 * q) / 200;
y.width = 200 * b;
y.height = c * b;
a.scale(b, b);
a.globalAlpha = 0.4;
a.fillStyle = "#000000";
a.fillRect(0, 0, 200, c);
a.globalAlpha = 1;
a.fillStyle = "#FFFFFF";
b = null;
b = X("leaderboard");
a.font = "30px Ubuntu";
a.fillText(b, 100 - a.measureText(b).width / 2, 40);
if (null == z) {
a.font = "20px Ubuntu";
c = 0;
for (;c < E.length;++c) {
b = E[c].name || X("unnamed_cell");
if (!va) {
b = X("unnamed_cell");
}
if (-1 != K.indexOf(E[c].id)) {
if (m[0].name) {
b = m[0].name;
}
a.fillStyle = "#FFAAAA";
/*new*//*mikey*//*remap*/OnLeaderboard(c+1);
} else {
a.fillStyle = "#FFFFFF";
}
b = c + 1 + ". " + b;
a.fillText(b, 100 - a.measureText(b).width / 2, 70 + 24 * c);
}
} else {
c = b = 0;
for (;c < z.length;++c) {
var e = b + z[c] * Math.PI * 2;
a.fillStyle = yb[c + 1];
a.beginPath();
a.moveTo(100, 140);
a.arc(100, 140, 80, b, e, false);
a.fill();
b = e;
}
}
}
}
}
function Ha(a, c, b, e, l) {
this.V = a;
this.x = c;
this.y = b;
this.i = e;
this.b = l;
}
function aa(a, c, b, e, l, p) {
this.id = a;
this.s = this.x = c;
this.t = this.y = b;
this.r = this.size = e;
this.color = l;
this.a = [];
this.W();
this.B(p);
/*new*/this.splitTime = Date.now();
}
function ua(a, c, b, e) {
if (a) {
this.u = a;
}
if (c) {
this.S = c;
}
this.U = !!b;
if (e) {
this.v = e;
}
}
function R(a, c) {
var b$$0 = "1" == f("#helloContainer").attr("data-has-account-data");
/*new*/var b$$0 = "1" == f("#ZCOverlay").attr("data-has-account-data");
f("#helloContainer").attr("data-has-account-data", "1");
if (null == c && d.localStorage.loginCache) {
var e = JSON.parse(d.localStorage.loginCache);
e.f = a.f;
e.d = a.d;
e.e = a.e;
d.localStorage.loginCache = JSON.stringify(e);
}
if (b$$0) {
var l = +f(".agario-exp-bar .progress-bar-text").text().split("/")[0];
b$$0 = +f(".agario-exp-bar .progress-bar-text").text().split("/")[1].split(" ")[0];
e = f(".agario-profile-panel .progress-bar-star").text();
if (e != a.e) {
R({
f : b$$0,
d : b$$0,
e : e
}, function() {
f(".agario-profile-panel .progress-bar-star").text(a.e);
f(".agario-exp-bar .progress-bar").css("width", "100%");
f(".progress-bar-star").addClass("animated tada").one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend", function() {
f(".progress-bar-star").removeClass("animated tada");
});
setTimeout(function() {
f(".agario-exp-bar .progress-bar-text").text(a.d + "/" + a.d + " XP");
R({
f : 0,
d : a.d,
e : a.e
}, function() {
R(a, c);
});
}, 1E3);
});
} else {
var p = Date.now();
var h = function() {
var b;
b = (Date.now() - p) / 1E3;
b = 0 > b ? 0 : 1 < b ? 1 : b;
b = b * b * (3 - 2 * b);
f(".agario-exp-bar .progress-bar-text").text(~~(l + (a.f - l) * b) + "/" + a.d + " XP");
f(".agario-exp-bar .progress-bar").css("width", (88 * (l + (a.f - l) * b) / a.d).toFixed(2) + "%");
if (1 > b) {
d.requestAnimationFrame(h);
} else {
if (c) {
c();
}
}
};
d.requestAnimationFrame(h);
}
} else {
f(".agario-profile-panel .progress-bar-star").text(a.e);
f(".agario-exp-bar .progress-bar-text").text(a.f + "/" + a.d + " XP");
f(".agario-exp-bar .progress-bar").css("width", (88 * a.f / a.d).toFixed(2) + "%");
if (c) {
c();
}
}
}
function eb(a) {
if ("string" == typeof a) {
a = JSON.parse(a);
}
if (Date.now() + 18E5 > a.ia) {
f("#helloContainer").attr("data-logged-in", "0");
} else {
d.localStorage.loginCache = JSON.stringify(a);
B = a.fa;
f(".agario-profile-name").text(a.name);
Va();
R({
f : a.f,
d : a.d,
e : a.e
});
f("#helloContainer").attr("data-logged-in", "1");
}
}
function zb(a) {
a = a.split("\n");
eb({
name : a[0],
ra : a[1],
fa : a[2],
ia : 1E3 * +a[3],
e : +a[4],
f : +a[5],
d : +a[6]
});
}
function Ia(a$$0) {
if ("connected" == a$$0.status) {
var c = a$$0.authResponse.accessToken;
d.FB.api("/me/picture?width=180&height=180", function(a) {
d.localStorage.fbPictureCache = a.data.url;
f(".agario-profile-picture").attr("src", a.data.url);
});
f("#helloContainer").attr("data-logged-in", "1");
if (null != B) {
f.ajax("https://m.agar.io/checkToken", {
error : function() {
B = null;
Ia(a$$0);
},
success : function(a) {
a = a.split("\n");
R({
e : +a[0],
f : +a[1],
d : +a[2]
});
},
dataType : "text",
method : "POST",
cache : false,
crossDomain : true,
data : B
});
} else {
f.ajax("https://m.agar.io/facebookLogin", {
error : function() {
B = null;
f("#helloContainer").attr("data-logged-in", "0");
},
success : zb,
dataType : "text",
method : "POST",
cache : false,
crossDomain : true,
data : c
});
}
}
}
if (!d.agarioNoInit) {
var Ja = d.location.protocol;
var ob = "https:" == Ja;
var xa;
var g;
var F;
var q;
var s$$0;
var W = null;
var r = null;
var t = 0;
var u = 0;
var K = [];
var m = [];
var D = {};
var v = [];
var P = [];
var E = [];
var ca = 0;
var da = 0;
var fa = -1;
var ga = -1;
var ub = 0;
var A = 0;
var db = 0;
var I = null;
var oa = 0;
var pa = 0;
var qa = 1E4;
var ra = 1E4;
var k = 1;
var x = null;
var fb = true;
var va = true;
var Ka = false;
var Ea = false;
var Q = 0;
var sa = false;
var gb = false;
var Y = t = ~~((oa + qa) / 2);
var Z = u = ~~((pa + ra) / 2);
var $ = 1;
var O = "";
var z = null;
var wa = false;
var Da = false;
var Ba = 0;
var Ca = 0;
var ma = 0;
var na = 0;
var hb = 0;
var yb = ["#333333", "#FF3333", "#33FF33", "#3333FF"];
var Fa = false;
var ka = false;
var Xa = 0;
var B = null;
var H = 1;
var w = 1;
var V = true;
var za = 0;
var Ma = "ontouchstart" in d && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
var Ga = new Image;
Ga.src = "img/split.png";
var ib = document.createElement("canvas");
if ("undefined" == typeof console || ("undefined" == typeof DataView || ("undefined" == typeof WebSocket || (null == ib || (null == ib.getContext || null == d.localStorage))))) {
alert("You browser does not support this game, we recommend you to use Firefox to play this");
} else {
var ha = null;
d.setNick = function(a) {
Sa();
I = a;
Ya();
Q = 0;
/*new*/GM_setValue("nick", a);
/*new*/console.log("Storing '" + a + "' as nick");
};
d.setRegion = ea;
d.setSkins = function(a) {
fb = a;
};
d.setNames = function(a) {
va = a;
};
d.setDarkTheme = function(a) {
sa = a;
};
d.setColors = function(a) {
Ka = a;
};
d.setShowMass = function(a) {
gb = a;
};
d.spectate = function() {
I = null;
G(1);
Sa();
};
d.setGameMode = function(a) {
if (a != O) {
if (":party" == O) {
f("#helloContainer").attr("data-party-state", "0");
}
ia(a);
if (":party" != a) {
N();
}
}
};
d.setAcid = function(a) {
Fa = a;
};
if (null != d.localStorage) {
if (null == d.localStorage.AB9) {
d.localStorage.AB9 = 0 + ~~(100 * Math.random());
}
hb = +d.localStorage.AB9;
d.ABGroup = hb;
}
f.get(Ja + "//gc.agar.io", function(a) {
var c = a.split(" ");
a = c[0];
c = c[1] || "";
if (-1 == ["UA"].indexOf(a)) {
jb.push("ussr");
}
if (-1 != d.navigator.userAgent.indexOf("Android")) {
d.location.href = "market://details?id=com.miniclip.agar.io";
}
if (-1 != d.navigator.userAgent.indexOf("iPhone") || (-1 != d.navigator.userAgent.indexOf("iPad") || -1 != d.navigator.userAgent.indexOf("iPod"))) {
d.location.href = "https://itunes.apple.com/app/agar.io/id995999703";
}
if (ba.hasOwnProperty(a)) {
if ("string" == typeof ba[a]) {
if (!x) {
ea(ba[a]);
}
} else {
if (ba[a].hasOwnProperty(c)) {
if (!x) {
ea(ba[a][c]);
}
}
}
}
}, "text");
var ja = false;
var Ta = 0;
setTimeout(function() {
ja = true;
}, Math.max(6E4 * Ta, 1E4));
var ba = {
AF : "JP-Tokyo",
AX : "EU-London",
AL : "EU-London",
DZ : "EU-London",
AS : "SG-Singapore",
AD : "EU-London",
AO : "EU-London",
AI : "US-Atlanta",
AG : "US-Atlanta",
AR : "BR-Brazil",
AM : "JP-Tokyo",
AW : "US-Atlanta",
AU : "SG-Singapore",
AT : "EU-London",
AZ : "JP-Tokyo",
BS : "US-Atlanta",
BH : "JP-Tokyo",
BD : "JP-Tokyo",
BB : "US-Atlanta",
BY : "EU-London",
BE : "EU-London",
BZ : "US-Atlanta",
BJ : "EU-London",
BM : "US-Atlanta",
BT : "JP-Tokyo",
BO : "BR-Brazil",
BQ : "US-Atlanta",
BA : "EU-London",
BW : "EU-London",
BR : "BR-Brazil",
IO : "JP-Tokyo",
VG : "US-Atlanta",
BN : "JP-Tokyo",
BG : "EU-London",
BF : "EU-London",
BI : "EU-London",
KH : "JP-Tokyo",
CM : "EU-London",
CA : "US-Atlanta",
CV : "EU-London",
KY : "US-Atlanta",
CF : "EU-London",
TD : "EU-London",
CL : "BR-Brazil",
CN : "CN-China",
CX : "JP-Tokyo",
CC : "JP-Tokyo",
CO : "BR-Brazil",
KM : "EU-London",
CD : "EU-London",
CG : "EU-London",
CK : "SG-Singapore",
CR : "US-Atlanta",
CI : "EU-London",
HR : "EU-London",
CU : "US-Atlanta",
CW : "US-Atlanta",
CY : "JP-Tokyo",
CZ : "EU-London",
DK : "EU-London",
DJ : "EU-London",
DM : "US-Atlanta",
DO : "US-Atlanta",
EC : "BR-Brazil",
EG : "EU-London",
SV : "US-Atlanta",
GQ : "EU-London",
ER : "EU-London",
EE : "EU-London",
ET : "EU-London",
FO : "EU-London",
FK : "BR-Brazil",
FJ : "SG-Singapore",
FI : "EU-London",
FR : "EU-London",
GF : "BR-Brazil",
PF : "SG-Singapore",
GA : "EU-London",
GM : "EU-London",
GE : "JP-Tokyo",
DE : "EU-London",
GH : "EU-London",
GI : "EU-London",
GR : "EU-London",
GL : "US-Atlanta",
GD : "US-Atlanta",
GP : "US-Atlanta",
GU : "SG-Singapore",
GT : "US-Atlanta",
GG : "EU-London",
GN : "EU-London",
GW : "EU-London",
GY : "BR-Brazil",
HT : "US-Atlanta",
VA : "EU-London",
HN : "US-Atlanta",
HK : "JP-Tokyo",
HU : "EU-London",
IS : "EU-London",
IN : "JP-Tokyo",
ID : "JP-Tokyo",
IR : "JP-Tokyo",
IQ : "JP-Tokyo",
IE : "EU-London",
IM : "EU-London",
IL : "JP-Tokyo",
IT : "EU-London",
JM : "US-Atlanta",
JP : "JP-Tokyo",
JE : "EU-London",
JO : "JP-Tokyo",
KZ : "JP-Tokyo",
KE : "EU-London",
KI : "SG-Singapore",
KP : "JP-Tokyo",
KR : "JP-Tokyo",
KW : "JP-Tokyo",
KG : "JP-Tokyo",
LA : "JP-Tokyo",
LV : "EU-London",
LB : "JP-Tokyo",
LS : "EU-London",
LR : "EU-London",
LY : "EU-London",
LI : "EU-London",
LT : "EU-London",
LU : "EU-London",
MO : "JP-Tokyo",
MK : "EU-London",
MG : "EU-London",
MW : "EU-London",
MY : "JP-Tokyo",
MV : "JP-Tokyo",
ML : "EU-London",
MT : "EU-London",
MH : "SG-Singapore",
MQ : "US-Atlanta",
MR : "EU-London",
MU : "EU-London",
YT : "EU-London",
MX : "US-Atlanta",
FM : "SG-Singapore",
MD : "EU-London",
MC : "EU-London",
MN : "JP-Tokyo",
ME : "EU-London",
MS : "US-Atlanta",
MA : "EU-London",
MZ : "EU-London",
MM : "JP-Tokyo",
NA : "EU-London",
NR : "SG-Singapore",
NP : "JP-Tokyo",
NL : "EU-London",
NC : "SG-Singapore",
NZ : "SG-Singapore",
NI : "US-Atlanta",
NE : "EU-London",
NG : "EU-London",
NU : "SG-Singapore",
NF : "SG-Singapore",
MP : "SG-Singapore",
NO : "EU-London",
OM : "JP-Tokyo",
PK : "JP-Tokyo",
PW : "SG-Singapore",
PS : "JP-Tokyo",
PA : "US-Atlanta",
PG : "SG-Singapore",
PY : "BR-Brazil",
PE : "BR-Brazil",
PH : "JP-Tokyo",
PN : "SG-Singapore",
PL : "EU-London",
PT : "EU-London",
PR : "US-Atlanta",
QA : "JP-Tokyo",
RE : "EU-London",
RO : "EU-London",
RU : "RU-Russia",
RW : "EU-London",
BL : "US-Atlanta",
SH : "EU-London",
KN : "US-Atlanta",
LC : "US-Atlanta",
MF : "US-Atlanta",
PM : "US-Atlanta",
VC : "US-Atlanta",
WS : "SG-Singapore",
SM : "EU-London",
ST : "EU-London",
SA : "EU-London",
SN : "EU-London",
RS : "EU-London",
SC : "EU-London",
SL : "EU-London",
SG : "JP-Tokyo",
SX : "US-Atlanta",
SK : "EU-London",
SI : "EU-London",
SB : "SG-Singapore",
SO : "EU-London",
ZA : "EU-London",
SS : "EU-London",
ES : "EU-London",
LK : "JP-Tokyo",
SD : "EU-London",
SR : "BR-Brazil",
SJ : "EU-London",
SZ : "EU-London",
SE : "EU-London",
CH : "EU-London",
SY : "EU-London",
TW : "JP-Tokyo",
TJ : "JP-Tokyo",
TZ : "EU-London",
TH : "JP-Tokyo",
TL : "JP-Tokyo",
TG : "EU-London",
TK : "SG-Singapore",
TO : "SG-Singapore",
TT : "US-Atlanta",
TN : "EU-London",
TR : "TK-Turkey",
TM : "JP-Tokyo",
TC : "US-Atlanta",
TV : "SG-Singapore",
UG : "EU-London",
UA : "EU-London",
AE : "EU-London",
GB : "EU-London",
US : "US-Atlanta",
UM : "SG-Singapore",
VI : "US-Atlanta",
UY : "BR-Brazil",
UZ : "JP-Tokyo",
VU : "SG-Singapore",
VE : "BR-Brazil",
VN : "JP-Tokyo",
WF : "SG-Singapore",
EH : "EU-London",
YE : "JP-Tokyo",
ZM : "EU-London",
ZW : "EU-London"
};
/*new*/// Hack to kill an established websocket
/*new*//*remap*/d.connect2 = d.connect;d.connect = zeach.connect;setTimeout(function(){try {d.connect2("Killing_original_websocket","");}catch(err){}} ,1500);
var J = null;
d.connect = Aa;
var la = 500;
var $a = -1;
var ab = -1;
var y = null;
var C = 1;
var ta = null;
var Qa = function() {
var a = Date.now();
var c = 1E3 / 60;
return function() {
d.requestAnimationFrame(Qa);
var b = Date.now();
var e = b - a;
if (e > c) {
a = b - e % c;
if (!S() || 240 > Date.now() - Xa) {
bb();
} else {
/*new*///console.warn("Skipping draw");
}
Ab();
}
};
}();
var T = {};
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(";");
var Bb = ["8", "nasa"];
var Cb = ["m'blob"];
Ha.prototype = {
V : null,
x : 0,
y : 0,
i : 0,
b : 0
};
aa.prototype = {
/*new*/ locked : false,
id : 0,
a : null,
name : null,
o : null,
O : null,
x : 0,
y : 0,
size : 0,
s : 0,
t : 0,
r : 0,
J : 0,
K : 0,
q : 0,
ba : 0,
Q : 0,
qa : 0,
ha : 0,
G : false,
h : false,
n : false,
R : true,
Y : 0,
X : function() {
var a;
a = 0;
for (;a < v.length;a++) {
if (v[a] == this) {
v.splice(a, 1);
break;
}
}
delete D[this.id];
a = m.indexOf(this);
if (-1 != a) {
Ea = true;
m.splice(a, 1);
}
a = K.indexOf(this.id);
if (-1 != a) {
K.splice(a, 1);
}
this.G = true;
if (0 < this.Y) {
P.push(this);
}
},
l : function() {
return Math.max(~~(0.3 * this.size), 24);
},
B : function(a) {
if (this.name = a) {
if (null == this.o) {
this.o = new ua(this.l(), "#FFFFFF", true, "#000000");
} else {
this.o.M(this.l());
}
this.o.C(this.name);
}
},
W : function() {
var a = this.I();
for (;this.a.length > a;) {
var c = ~~(Math.random() * this.a.length);
this.a.splice(c, 1);
}
if (0 == this.a.length) {
if (0 < a) {
this.a.push(new Ha(this, this.x, this.y, this.size, Math.random() - 0.5));
}
}
for (;this.a.length < a;) {
c = ~~(Math.random() * this.a.length);
c = this.a[c];
this.a.push(new Ha(this, c.x, c.y, c.i, c.b));
}
},
I : function() {
var a = 10;
if (20 > this.size) {
a = 0;
}
if (this.h) {
a = 30;
}
var c = this.size;
if (!this.h) {
c *= k;
}
c *= C;
if (this.ba & 32) {
c *= 0.25;
}
return~~Math.max(c, a);
},
oa : function() {
this.W();
var a$$0 = this.a;
var c = a$$0.length;
var b = 0;
for (;b < c;++b) {
var e = a$$0[(b - 1 + c) % c].b;
var l = a$$0[(b + 1) % c].b;
a$$0[b].b += (Math.random() - 0.5) * (this.n ? 3 : 1);
a$$0[b].b *= 0.7;
if (10 < a$$0[b].b) {
a$$0[b].b = 10;
}
if (-10 > a$$0[b].b) {
a$$0[b].b = -10;
}
a$$0[b].b = (e + l + 8 * a$$0[b].b) / 10;
}
var p = this;
var h = this.h ? 0 : (this.id / 1E3 + A / 1E4) % (2 * Math.PI);
b = 0;
for (;b < c;++b) {
var d = a$$0[b].i;
e = a$$0[(b - 1 + c) % c].i;
l = a$$0[(b + 1) % c].i;
if (15 < this.size && (null != W && (20 < this.size * k && 0 < this.id))) {
var f = false;
var g = a$$0[b].x;
var m = a$$0[b].y;
W.pa(g - 5, m - 5, 10, 10, function(a) {
if (a.V != p) {
if (25 > (g - a.x) * (g - a.x) + (m - a.y) * (m - a.y)) {
f = true;
}
}
});
if (!f) {
if (a$$0[b].x < oa || (a$$0[b].y < pa || (a$$0[b].x > qa || a$$0[b].y > ra))) {
f = true;
}
}
if (f) {
if (0 < a$$0[b].b) {
a$$0[b].b = 0;
}
a$$0[b].b -= 1;
}
}
d += a$$0[b].b;
if (0 > d) {
d = 0;
}
d = this.n ? (19 * d + this.size) / 20 : (12 * d + this.size) / 13;
a$$0[b].i = (e + l + 8 * d) / 10;
e = 2 * Math.PI / c;
l = this.a[b].i;
if (this.h) {
if (0 == b % 2) {
l += 5;
}
}
a$$0[b].x = this.x + Math.cos(e * b + h) * l;
a$$0[b].y = this.y + Math.sin(e * b + h) * l;
}
},
P : function() {
if (0 >= this.id) {
return 1;
}
var a;
a = (A - this.Q) / 120;
a = 0 > a ? 0 : 1 < a ? 1 : a;
var c = 0 > a ? 0 : 1 < a ? 1 : a;
this.l();
if (this.G && 1 <= c) {
var b = P.indexOf(this);
if (-1 != b) {
P.splice(b, 1);
}
}
this.x = a * (this.J - this.s) + this.s;
this.y = a * (this.K - this.t) + this.t;
this.size = c * (this.q - this.r) + this.r;
return c;
},
N : function() {
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;
},
w : function(a) {
if (this.N()) {
++this.Y;
var c = 0 < this.id && (!this.h && (!this.n && 0.4 > k));
if (5 > this.I()) {
c = true;
}
if (this.R && !c) {
var b = 0;
for (;b < this.a.length;b++) {
this.a[b].i = this.size;
}
}
this.R = c;
a.save();
this.ha = A;
b = this.P();
if (this.G) {
a.globalAlpha *= 1 - b;
}
a.lineWidth = 10;
a.lineCap = "round";
a.lineJoin = this.h ? "miter" : "round";
if (Ka) {
a.fillStyle = "#FFFFFF";
a.strokeStyle = "#AAAAAA";
} else {
a.fillStyle = this.color;
a.strokeStyle = this.color;
}
/*new*/drawCellInfos.call(this, zeach.isColors, zeach.ctx);
if (c) {
a.beginPath();
a.arc(this.x, this.y, this.size + 5, 0, 2 * Math.PI, false);
} else {
this.oa();
a.beginPath();
var e = this.I();
a.moveTo(this.a[0].x, this.a[0].y);
b = 1;
for (;b <= e;++b) {
var d = b % e;
a.lineTo(this.a[d].x, this.a[d].y);
}
}
a.closePath();
e = this.name.toLowerCase();
//if (!this.n && (fb && ":teams" != O)) {
// if (-1 != jb.indexOf(e)) {
// if (!T.hasOwnProperty(e)) {
// T[e] = new Image;
// T[e].src = "skins/" + e + ".png";
// }
// b = 0 != T[e].width && T[e].complete ? T[e] : null;
// } else {
// b = null;
// }
//} else {
// b = null;
//}
/*new*//*remap*/var b = customSkins(this, zeach.defaultSkins, zeach.imgCache, zeach.isShowSkins, zeach.gameMode);
b = (d = b) ? -1 != Cb.indexOf(e) : false;
/*new*///if (!c) {
a.stroke();
/*new*///}}
/*new*/if(!cobbler.isLiteBrite)
a.fill();
if (!(null == d)) {
if (!b) {
a.save();
/*new*/zeach.ctx.globalAlpha = (isSpecialSkin(this.name.toLowerCase()) || _.contains(zeach.myIDs, this.id)) ? 1 : 0.5;
a.clip();
a.drawImage(d, this.x - this.size, this.y - this.size, 2 * this.size, 2 * this.size);
a.restore();
}
}
if (Ka || 15 < this.size) {
if (!c) {
a.strokeStyle = "#000000";
a.globalAlpha *= 0.1;
a.stroke();
}
}
a.globalAlpha = 1;
if (null != d) {
if (b) {
a.drawImage(d, this.x - 2 * this.size, this.y - 2 * this.size, 4 * this.size, 4 * this.size);
}
}
b = -1 != m.indexOf(this);
c = ~~this.y;
//if (0 != this.id && ((va || b) && (this.name && (this.o && (null == d || -1 == Bb.indexOf(e)))))) {
// d = this.o;
// d.C(this.name);
// d.M(this.l());
// e = 0 >= this.id ? 1 : Math.ceil(10 * k) / 10;
// d.ea(e);
// d = d.L();
// var p = ~~(d.width / e);
// var h = ~~(d.height / e);
// a.drawImage(d, ~~this.x - ~~(p / 2), c - ~~(h / 2), p, h);
// c += d.height / 2 / e + 4;
//}
//if (0 < this.id) {
// if (gb) {
// if (b || 0 == m.length && ((!this.h || this.n) && 20 < this.size)) {
// if (null == this.O) {
// this.O = new ua(this.l() / 2, "#FFFFFF", true, "#000000");
// }
// b = this.O;
// b.M(this.l() / 2);
// b.C(~~(this.size * this.size / 100));
// e = Math.ceil(10 * k) / 10;
// b.ea(e);
// d = b.L();
// p = ~~(d.width / e);
// h = ~~(d.height / e);
// a.drawImage(d, ~~this.x - ~~(p / 2), c - ~~(h / 2), p, h);
// }
// }
//}
/*new*//*remap*/if(0 != this.id) {
/*new*//*remap*/var vertical_offset = drawCellName.call(this,b,e,d);
/*new*//*remap*/ drawCellMass.call(this,vertical_offset,b);
}
a.restore();
}
}
};
/*new*//*remap*/restorePointObj(aa.prototype);
ua.prototype = {
F : "",
S : "#000000",
U : false,
v : "#000000",
u : 16,
p : null,
T : null,
k : false,
D : 1,
M : function(a) {
if (this.u != a) {
this.u = a;
this.k = true;
}
},
ea : function(a) {
if (this.D != a) {
this.D = a;
this.k = true;
}
},
setStrokeColor : function(a) {
if (this.v != a) {
this.v = a;
this.k = true;
}
},
C : function(a) {
if (a != this.F) {
this.F = a;
this.k = true;
}
},
L : function() {
if (null == this.p) {
this.p = document.createElement("canvas");
this.T = this.p.getContext("2d");
}
if (this.k) {
this.k = false;
var a = this.p;
var c = this.T;
var b = this.F;
var e = this.D;
var d = this.u;
var p = d + "px Ubuntu";
c.font = p;
var h = ~~(0.2 * d);
a.width = (c.measureText(b).width + 6) * e;
a.height = (d + h) * e;
c.font = p;
c.scale(e, e);
c.globalAlpha = 1;
c.lineWidth = 3;
c.strokeStyle = this.v;
c.fillStyle = this.S;
if (this.U) {
c.strokeText(b, 3, d - h / 2);
}
c.fillText(b, 3, d - h / 2);
}
return this.p;
}
};
/*new*//*remap*/restoreCanvasElementObj(ua.prototype);
if (!Date.now) {
Date.now = function() {
return(new Date).getTime();
};
}
(function() {
var a$$0 = ["ms", "moz", "webkit", "o"];
var c = 0;
for (;c < a$$0.length && !d.requestAnimationFrame;++c) {
d.requestAnimationFrame = d[a$$0[c] + "RequestAnimationFrame"];
d.cancelAnimationFrame = d[a$$0[c] + "CancelAnimationFrame"] || d[a$$0[c] + "CancelRequestAnimationFrame"];
}
if (!d.requestAnimationFrame) {
d.requestAnimationFrame = function(a) {
return setTimeout(a, 1E3 / 60);
};
d.cancelAnimationFrame = function(a) {
clearTimeout(a);
};
}
})();
var mb = {
ja : function(a$$0) {
function c$$1(a, c, b, d, e) {
this.x = a;
this.y = c;
this.j = b;
this.g = d;
this.depth = e;
this.items = [];
this.c = [];
}
var b$$1 = a$$0.ka || 2;
var e$$0 = a$$0.la || 4;
c$$1.prototype = {
x : 0,
y : 0,
j : 0,
g : 0,
depth : 0,
items : null,
c : null,
H : function(a) {
var c$$0 = 0;
for (;c$$0 < this.items.length;++c$$0) {
var b = this.items[c$$0];
if (b.x >= a.x && (b.y >= a.y && (b.x < a.x + a.j && b.y < a.y + a.g))) {
return true;
}
}
if (0 != this.c.length) {
var d = this;
return this.$(a, function(c) {
return d.c[c].H(a);
});
}
return false;
},
A : function(a, c) {
var b$$0 = 0;
for (;b$$0 < this.items.length;++b$$0) {
c(this.items[b$$0]);
}
if (0 != this.c.length) {
var d = this;
this.$(a, function(b) {
d.c[b].A(a, c);
});
}
},
m : function(a) {
if (0 != this.c.length) {
this.c[this.Z(a)].m(a);
} else {
if (this.items.length >= b$$1 && this.depth < e$$0) {
this.ga();
this.c[this.Z(a)].m(a);
} else {
this.items.push(a);
}
}
},
Z : function(a) {
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;
},
$ : function(a, c) {
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;
},
ga : function() {
var a = this.depth + 1;
var b = this.j / 2;
var d = this.g / 2;
this.c.push(new c$$1(this.x, this.y, b, d, a));
this.c.push(new c$$1(this.x + b, this.y, b, d, a));
this.c.push(new c$$1(this.x, this.y + d, b, d, a));
this.c.push(new c$$1(this.x + b, this.y + d, b, d, a));
a = this.items;
this.items = [];
b = 0;
for (;b < a.length;b++) {
this.m(a[b]);
}
},
clear : function() {
var a = 0;
for (;a < this.c.length;a++) {
this.c[a].clear();
}
this.items.length = 0;
this.c.length = 0;
}
};
var d$$0 = {
x : 0,
y : 0,
j : 0,
g : 0
};
return{
root : new c$$1(a$$0.ca, a$$0.da, a$$0.ma - a$$0.ca, a$$0.na - a$$0.da, 0),
m : function(a) {
this.root.m(a);
},
A : function(a, c) {
this.root.A(a, c);
},
pa : function(a, c, b, e, f) {
d$$0.x = a;
d$$0.y = c;
d$$0.j = b;
d$$0.g = e;
this.root.A(d$$0, f);
},
H : function(a) {
return this.root.H(a);
},
clear : function() {
this.root.clear();
}
};
}
};
var Za = function() {
var a = new aa(0, 0, 0, 32, "#ED1C24", "");
var c = document.createElement("canvas");
c.width = 32;
c.height = 32;
var b = c.getContext("2d");
return function() {
if (0 < m.length) {
a.color = m[0].color;
a.B(m[0].name);
}
b.clearRect(0, 0, 32, 32);
b.save();
b.translate(16, 16);
b.scale(0.4, 0.4);
a.w(b);
b.restore();
var d = document.getElementById("favicon");
var f = d.cloneNode(true);
/*new*/try{
f.setAttribute("href", c.toDataURL("image/png"));
/*new*/}catch(err){}
d.parentNode.replaceChild(f, d);
};
}();
/*new*///kb();
/*new*///f(function() {
/*new*/// Za();
/*new*///});
f(function() {
if (d.localStorage.loginCache) {
eb(d.localStorage.loginCache);
}
if (d.localStorage.fbPictureCache) {
f(".agario-profile-picture").attr("src", d.localStorage.fbPictureCache);
}
});
d.fbAsyncInit = function() {
function a$$0() {
d.FB.login(function(a) {
Ia(a);
}, {
scope : "public_profile, email"
});
}
d.FB.init({
appId : "677505792353827",
cookie : true,
xfbml : true,
status : true,
version : "v2.2"
});
d.FB.Event.subscribe("auth.statusChange", function(c) {
if ("connected" == c.status) {
Ia(c);
} else {
a$$0();
}
});
d.facebookLogin = a$$0;
};
var Ab = function() {
function a$$0(a, c, b, d, e) {
var f = c.getContext("2d");
var g = c.width;
c = c.height;
a.color = e;
a.B(b);
a.size = d;
f.save();
f.translate(g / 2, c / 2);
a.w(f);
f.restore();
}
var c$$0 = new aa(0, 0, 0, 32, "#5bc0de", "");
c$$0.id = -1;
var b$$0 = new aa(0, 0, 0, 32, "#5bc0de", "");
b$$0.id = -1;
var d$$0 = document.createElement("canvas");
d$$0.getContext("2d");
d$$0.width = d$$0.height = 70;
a$$0(b$$0, d$$0, "", 26, "#ebc0de");
return function() {
f(".cell-spinner").filter(":visible").each(function() {
var b = f(this);
var g = Date.now();
var h = this.width;
var k = this.height;
var m = this.getContext("2d");
m.clearRect(0, 0, h, k);
m.save();
m.translate(h / 2, k / 2);
var q = 0;
for (;10 > q;++q) {
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);
}
m.restore();
if (b = b.attr("data-itr")) {
b = X(b);
}
a$$0(c$$0, this, b || "", +f(this).attr("data-size"), "#5bc0de");
/*new*/ });
};
};
d.createParty = function() {
ia(":party");
J = function(a) {
f(".partyToken").val(a);
f("#helloContainer").attr("data-party-state", "1");
};
N();
};
d.joinParty = function(a) {
f("#helloContainer").attr("data-party-state", "4");
f.ajax(Ja + "//m.agar.io/getToken", {
error : function() {
f("#helloContainer").attr("data-party-state", "6");
},
success : function(c) {
c = c.split("\n");
f(".partyToken").val(a);
f("#helloContainer").attr("data-party-state", "5");
ia(":party");
Aa("ws://" + c[0], a);
},
dataType : "text",
method : "POST",
cache : false,
crossDomain : true,
data : a
});
};
d.cancelParty = function() {
f("#helloContainer").attr("data-party-state", "0");
ia("");
N();
};
/*new*///f(function() {
/*new*/// f(kb);
/*new*///});
/*new*/d.onload = kb;
}
}
/*new*/})(unsafeWindow, unsafeWindow.jQuery);
// ====================================== Stats Screen ===========================================================
var __STORAGE_PREFIX = "mikeyk730__";
var chart_update_interval = 10;
jQuery('body').append('<div id="chart-container" style="display:none; position:absolute; height:176px; width:300px; left:10px; bottom:44px"></div>');
var checkbox_div = jQuery('#settings input[type=checkbox]').closest('div');
// make sure player sees ads at least once so Zeach doesn't go medieval on me.
var PlayerHasSeenOfficialAds =_.once(function (){
jQuery("#ZCPlay").show();
jQuery("#ZCClose").text("Close");
});
unsafeWindow.hideZCOverlay = function(){
PlayerHasSeenOfficialAds();
jQuery('#ZCOverlay').fadeOut();
}
unsafeWindow.showZCOverlay = function (){
jQuery('#ZCOverlay').fadeIn();
OnShowOverlay(false);
};
jQuery('body').append('<div id="ZCOverlay" class="bs-example-modal-lg" style="position:relative;z-index: 300;">'+
'<div class="modal-dialog modal-lg">'+
' <div class="modal-content">'+
' <div class="modal-header">'+
' <button type="button" class="close" onclick="hideZCOverlay();")><span>×</span></button>'+
'<h4 class="modal-title">A1iens Agar Mod v' +GM_info.script.version + '</h4>'+
'</div>'+
'<div id="ZCOverlayBody" class="modal-body" style="height:675px;">'+
' </div>'+
' <div class="modal-footer">'+
' <button type="button" id="ZCClose" class="btn btn-default" onclick="hideZCOverlay();">Let\'s Roll</button>'+
' <button type="button" id="ZCPlay" class="btn btn-primary" onclick="hideZCOverlay();setNick(document.getElementById(\'nick\').value); return false;">Play</button>'+
'</div>'+
'</div><!-- /.modal-content -->'+
'</div><!-- /.modal-dialog -->'+
'</div><!-- /.modal -->');
jQuery("#ZCPlay").hide();
jQuery("#agario-main-buttons")
.append('<button type="button" class="btn btn-danger" id="opnZC" onclick="showZCOverlay()" style="margin-top:5px;position:relative;width:100%;">More Options</button>');
jQuery("#agario-main-buttons")
.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>');
jQuery('#ZCOverlayBody').append('<div id="ZCStats" style="position:relative;width:100%; background-color: #FFFFFF; border-radius: 15px; padding: 5px 15px 5px 15px;">'+
'<ul class="nav nav-pills" role="tablist">' +
'<li role="presentation" class="active" > <a href="#page0" id="newsTab" role="tab" data-toggle="tab">News</a></li>' +
'<li role="presentation"> <a href="#page1" id="statsTab" role="tab" data-toggle="tab">Stats</a></li>' +
'<li role="presentation"> <a href="#page2" id="configTab" role="tab" data-toggle="tab">Extended Options</a></li>' +
'<li role="presentation"> <a href="#page3" id="helpTab" role="tab" data-toggle="tab">Help</a></li>' +
//'<li role="presentation"><a href="#page3" role="tab" data-toggle="tab">IP Connect</a></li>' +
'</ul>'+
'<div id="bigbox" class="tab-content">' +
'<div id="page0" role="tabpanel" class="tab-pane active">'+ debugMonkeyReleaseMessage +'</div>' +
'<div id="page1" role="tabpanel" class="tab-pane">' +
'<div class="row">' +
'<div id="statArea" class="col-sm-6" style="vertical-align:top;"></div>' +
'<div id="pieArea" class="col-sm-5" style="vertical-align: top; height:250px;"></div>' +
'<div id="padder" class="col-sm-1"></div>' +
'</div>' +
'<div class="row">' +
'<div id="gainArea" class="col-sm-6" style="vertical-align:top;"></div>' +
'<div id="lossArea" class="col-sm-6" style="vertical-align:top;"></div>' +
'</div>' +
'<div class="row">' +
'<div id="chartArea" class="col-sm-8" ></div>' +
'<div id="XPArea" class="col-sm-4"></div>' +
'</div>' +
'</div>' +
'<div id="page2" role="tabpanel" class="tab-pane">' +
'<div class="row">' +
'<div id="col1" class="col-sm-4 checkbox" style="padding-left: 5%; padding-right: 1%;"></div>' +
'<div id="col2" class="col-sm-4" style="padding-left: 2%; padding-right: 2%;"></div>' +
'<div id="col3" class="col-sm-4" style="padding-left: 2%; padding-right: 5%;"></div>' +
'</div>' +
'</div>'+
'<div id="page3" role="tabpanel" class="tab-pane">' +
'<div class="row">' +
'<div id="col1" class="col-sm-6" style="padding-left: 5%; padding-right: 1%;"><h3>Keys</h3><ul>' +
' <li><B>TAB</B> - When split switches selected blob</li>' +
' <li><B>A</B> - Toggle Acid mode</li>' +
' <li><B>Q</B> - Macro mode (Shots mass out fast)</li>' +
' <li><B>C</B> - Toggle display of visual cues</li>' +
' <li><B>G</B> - Toggle new grazer (better overall)</li>' +
' <li><B>H</B> - Toggle old grazer (slightly better early on)' +
' <li><B>E</B> - Fire at virus near cursor</li>' +
' <li><B>R</B> - Fire at virus near selected blob (virus is highlighted in red)</li>' +
' <li><B>M</B> - Enables/Disables mouse input</li>' +
' <li><B>Z</B> - Zoom in/zoom out</li>' +
' <li><B>1...7</B> - Selecte n-th blob sorted by size</li>' +
' <li><B>Click</B> - Lock currently selected blob (if blob locking enabled)</li>' +
' <li><B>S</B> - Unlock all blobs (if blob locking enabled)</li>' +
'</ul></div>' +
'<div id="col2" class="col-sm-6" style="padding-left: 5%; padding-right: 2%;"><h3></h3></div>' +
'</div>' +
'</div>');
jQuery(".agario-profile-panel").appendTo("#XPArea");
jQuery("#statsTab").click(function(){OnShowOverlay(false);});
function LS_getValue(aKey, aDefault) {
var val = localStorage.getItem(__STORAGE_PREFIX + aKey);
if (null === val && 'undefined' != typeof aDefault) return aDefault;
return val;
}
function LS_setValue(aKey, aVal) {
localStorage.setItem(__STORAGE_PREFIX + aKey, aVal);
}
function GetRgba(hex_color, opacity)
{
var patt = /^#([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})$/;
var matches = patt.exec(hex_color);
return "rgba("+parseInt(matches[1], 16)+","+parseInt(matches[2], 16)+","+parseInt(matches[3], 16)+","+opacity+")";
}
function secondsToHms(d)
{
d = Number(d);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
return ((h > 0 ? h + ":" + (m < 10 ? "0" : "") : "") + m + ":" + (s < 10 ? "0" : "") + s);
}
var chart = null;
var chart_data = [];
var num_cells_data = [];
var chart_counter = 0;
var stat_canvas = null;
var stats = null;
var my_cells = null;
var my_color = "#ff8888";
var pie = null;
var stats_chart;
var display_chart = LS_getValue('display_chart', 'true') === 'true';
var display_stats = LS_getValue('display_stats', 'false') === 'true';
function AppendCheckbox(e, id, label, checked, on_change)
{
e.append('<label><input type="checkbox" id="'+id+'">'+label+'</label><br>');
jQuery('#'+id).attr('checked', checked);
jQuery('#'+id).change(function(){
on_change(!!this.checked);
});
on_change(checked);
}
function AppendCheckboxP(e, id, label, checked, on_change)
{
e.append('<p><input type="checkbox" id="'+id+'">'+label+'</p>');
jQuery('#'+id).attr('checked', checked);
jQuery('#'+id).change(function(){
on_change(!!this.checked);
});
on_change(checked);
}
function OnChangeDisplayChart(display)
{
LS_setValue('display_chart', display ? 'true' : 'false');
display_chart = display;
display ? jQuery('#chart-container').show() : jQuery('#chart-container').hide();
}
function OnChangeDisplayStats(display)
{
LS_setValue('display_stats', display ? 'true' : 'false');
display_stats = display;
RenderStats(false);
}
function ResetChart()
{
chart = null;
chart_data.length = 0;
num_cells_data.length = 0;
chart_counter = 0;
jQuery('#chart-container').empty();
}
function UpdateChartData(mass)
{
chart_counter++;
if (chart_counter%chart_update_interval > 0)
return false;
num_cells_data.push({
x: chart_counter,
y: my_cells.length
});
chart_data.push({
x: chart_counter,
y: mass/100
});
return true;
}
function CreateChart(e, color, interactive)
{
return new CanvasJS.Chart(e,{
interactivityEnabled: false,
title: null,
axisX:{
valueFormatString: " ",
lineThickness: 0,
tickLength: 0
},
axisY:{
lineThickness: 0,
tickLength: 0,
gridThickness: 2,
gridColor: "white",
labelFontColor: "white"
},
backgroundColor: "rgba(0,0,0,0.2)",
data: [{
type: "area",
color: color,
dataPoints: chart_data
}]
});
}
function UpdateChart(mass, color)
{
my_color = color;
if (chart === null)
chart = CreateChart("chart-container", color, false);
if (UpdateChartData(mass) && display_chart)
chart.render();
jQuery('.canvasjs-chart-credit').hide();
}
function ResetStats()
{
stats = {
pellets: {num:0, mass:0},
w: {num:0, mass:0},
cells: {num:0, mass:0},
viruses: {num:0, mass:0},
birthday: Date.now(),
time_of_death: null,
high_score: 0,
top_slot: Number.POSITIVE_INFINITY,
gains: {},
losses: {},
};
}
function OnGainMass(me, other)
{
var mass = other.size * other.size;
if (other.isVirus){
stats.viruses.num++;
stats.viruses.mass += mass; //TODO: shouldn't add if game mode is teams
sfx_event("virushit");
}
else if (Math.floor(mass) <= 400 && !other.name){
stats.pellets.num++;
stats.pellets.mass += mass;
sfx_event("pellet");
}
// heuristic to determine if mass is 'w', not perfect
else if (!other.name && mass <= 1444 && (mass >= 1369 || (other.x == other.ox && other.y == other.oy))){
//console.log('w', mass, other.name, other);
if (other.color != me.color){ //don't count own ejections, again not perfect
stats.w.num++;
stats.w.mass += mass;
}
sfx_event("eat");
}
else {
//console.log('cell', mass, other.name, other);
var key = other.name + ':' + other.color;
stats.cells.num++;
stats.cells.mass += mass;
if (stats.gains[key] == undefined)
stats.gains[key] = {num: 0, mass: 0};
stats.gains[key].num++;
stats.gains[key].mass += mass;
sfx_event("eat");
}
}
function OnLoseMass(me, other)
{
var mass = me.size * me.size;
var key = other.name + ':' + other.color;
if (stats.losses[key] == undefined)
stats.losses[key] = {num: 0, mass: 0};
stats.losses[key].num++;
stats.losses[key].mass += mass;
sfx_event("eat");
}
function DrawPie(pellet, w, cells, viruses)
{
var total = pellet + w + cells + viruses;
pie = new CanvasJS.Chart("pieArea", {
title: null,
animationEnabled: false,
legend:{
verticalAlign: "center",
horizontalAlign: "left",
fontSize: 20,
fontFamily: "Helvetica"
},
theme: "theme2",
data: [{
type: "pie",
startAngle:-20,
showInLegend: true,
toolTipContent:"{legendText} {y}%",
dataPoints: [
{ y: 100*pellet/total, legendText:"pellets"},
{ y: 100*cells/total, legendText:"cells"},
{ y: 100*w/total, legendText:"w"},
{ y: 100*viruses/total, legendText:"viruses"},
]
}]
});
pie.render();
}
function GetTopN(n, p){
var r = [];
var a = Object.keys(stats[p]).sort(function(a, b) {return -(stats[p][a].mass - stats[p][b].mass)});
for (var i = 0; i < n && i < a.length; ++i){
var key = a[i];
var mass = stats[p][key].mass;
var name = key.slice(0,key.length-8);
if (!name) name = "An unnamed cell";
var color = key.slice(key.length-7);
r.push({name:name, color:color, mass:Math.floor(mass/100)});
}
return r;
}
function AppendTopN(n, p, list) {
var a = GetTopN(n,p);
for (var i = 0; i < a.length; ++i){
var text = a[i].name + ' (' + (p == 'gains' ? '+' : '-') + a[i].mass + ' mass)';
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>');
};
return a.length > 0;
}
function ShowZCStats(){
if(cobbler.showZcStats){
jQuery("#ZCOverlay").fadeIn();
jQuery('#statsTab').tab('show');
}
}
function DrawStats(game_over) {
if (!stats) return;
jQuery('#statArea').empty();
jQuery('#pieArea').empty();
jQuery('#gainArea').empty();
jQuery('#lossArea').empty();
jQuery('#chartArea').empty();
//jQuery('#statsTab').tab('show');
if (game_over){
stats.time_of_death = Date.now();
sfx_play(1);
StopBGM();
ShowZCStats();
if(window.cobbler.autoRespawn && window.cobbler.grazingMode){setTimeout(function(){jQuery(".btn-play-guest").click();},3000);}
}
var time = stats.time_of_death ? stats.time_of_death : Date.now();
var seconds = (time - stats.birthday)/1000;
var list = jQuery('<ul>');
list.append('<li style="font-size: 16px; ">Game time: ' + secondsToHms(seconds) + '</li>');
list.append('<li style="font-size: 16px; ">High score: ' + ~~(stats.high_score/100) + '</li>');
if (stats.top_slot == Number.POSITIVE_INFINITY){
list.append('<li style="font-size: 16px; ">You didn\'t make the leaderboard</li>');
}
else {
list.append('<li style="font-size: 16px; ">Leaderboard max: ' + stats.top_slot + '</li>');
}
list.append('<li style="font-size: 16px; padding-top: 15px">' + stats.pellets.num + " pellets eaten (" + ~~(stats.pellets.mass/100) + ' mass)</li>');
list.append('<li style="font-size: 16px; ">' + stats.cells.num + " cells eaten (" + ~~(stats.cells.mass/100) + ' mass)</li>');
list.append('<li style="font-size: 16px; ">' + stats.w.num + " masses eaten (" + ~~(stats.w.mass/100) + ' mass)</li>');
list.append('<li style="font-size: 16px; ">' + stats.viruses.num + " viruses eaten (" + ~~(stats.viruses.mass/100) + ' mass)</li>');
jQuery('#statArea').append('<h2>Game Summary</h2>');
jQuery('#statArea').append(list);
DrawPie(stats.pellets.mass, stats.w.mass, stats.cells.mass, stats.viruses.mass);
jQuery('#gainArea').append('<h3>Top Gains</h3>');
list = jQuery('<ol>');
if (AppendTopN(5, 'gains', list))
jQuery('#gainArea').append(list);
else
jQuery('#gainArea').append('<ul><li style="font-size: 16px; ">You have not eaten anybody</li></ul>');
jQuery('#lossArea').append('<h3>Top Losses</h3>');
list = jQuery('<ol>');
if (AppendTopN(5, 'losses', list))
jQuery('#lossArea').append(list);
else
jQuery('#lossArea').append('<ul><li style="font-size: 16px; ">Nobody has eaten you</li></ul>');
if (stats.time_of_death !== null){
jQuery('#chartArea').height(200);
jQuery('#chartArea')[0].height=200;
stat_chart = CreateChart('chartArea', my_color, true);
var scale = Math.max.apply(Math,chart_data.map(function(o){return o.y;}))/16;
var scaled_data = num_cells_data.map(function(a){return {x:a.x, y:a.y*scale};});
stat_chart.options.data.push({type: "line", dataPoints: scaled_data, toolTipContent:" "});
stat_chart.render();
}
else {
jQuery('#chartArea').height(200);
jQuery('#chartArea')[0].height=200;
}
}
var styles = {
heading: {font:"30px Ubuntu", spacing: 41, alpha: 1},
subheading: {font:"25px Ubuntu", spacing: 31, alpha: 1},
normal: {font:"17px Ubuntu", spacing: 21, alpha: 0.6}
};
var g_stat_spacing = 0;
var g_display_width = 220;
var g_layout_width = g_display_width;
function AppendText(text, context, style) {
context.globalAlpha = styles[style].alpha;
context.font = styles[style].font;
g_stat_spacing += styles[style].spacing;
var width = context.measureText(text).width;
g_layout_width = Math.max(g_layout_width, width);
context.fillText(text, g_layout_width/2 - width/2, g_stat_spacing);
}
function RenderStats(reset) {
if (reset) g_layout_width = g_display_width;
if (!display_stats || !stats) return;
g_stat_spacing = 0;
var gains = GetTopN(3, 'gains');
var losses = GetTopN(3, 'losses');
var height = 30 + styles['heading'].spacing + styles['subheading'].spacing * 2 + styles['normal'].spacing * (4 + gains.length + losses.length);
stat_canvas = document.createElement("canvas");
var scale = Math.min(g_display_width, .3 * window.innerWidth) / g_layout_width;
stat_canvas.width = g_layout_width * scale;
stat_canvas.height = height * scale;
var context = stat_canvas.getContext("2d");
context.scale(scale, scale);
context.globalAlpha = .4;
context.fillStyle = "#000000";
context.fillRect(0, 0, g_layout_width, height);
context.fillStyle = "#FFFFFF";
AppendText("Stats", context, 'heading');
var text = stats.pellets.num + " pellets eaten (" + ~~(stats.pellets.mass/100) + ")";
AppendText(text, context,'normal');
text = stats.w.num + " mass eaten (" + ~~(stats.w.mass/100) + ")";
AppendText(text, context,'normal');
text = stats.cells.num + " cells eaten (" + ~~(stats.cells.mass/100) + ")";
AppendText(text, context,'normal');
text = stats.viruses.num + " viruses eaten (" + ~~(stats.viruses.mass/100) + ")";
AppendText(text, context,'normal');
AppendText("Top Gains",context,'subheading');
for (var j = 0; j < gains.length; ++j){
text = (j+1) + ". " + gains[j].name + " (" + gains[j].mass + ")";
context.fillStyle = gains[j].color;
AppendText(text, context,'normal');
}
context.fillStyle = "#FFFFFF";
AppendText("Top Losses",context,'subheading');
for (var j = 0; j < losses.length; ++j){
text = (j+1) + ". " + losses[j].name + " (" + losses[j].mass + ")";
context.fillStyle = losses[j].color;
AppendText(text, context,'normal');
}
}
jQuery(unsafeWindow).resize(function() {
RenderStats(false);
});
unsafeWindow.OnGameStart = function(cells) {
my_cells = cells;
ResetChart();
ResetStats();
RenderStats(true);
StartBGM();
sfx_play(0);
};
unsafeWindow.OnShowOverlay = function(game_in_progress) {
DrawStats(!game_in_progress);
};
unsafeWindow.OnUpdateMass = function(mass) {
stats.high_score = Math.max(stats.high_score, mass);
UpdateChart(mass, GetRgba(my_cells[0].color,0.4));
};
unsafeWindow.OnCellEaten = function(predator, prey) {
if (!my_cells) return;
if (my_cells.indexOf(predator) != -1){
OnGainMass(predator, prey);
RenderStats(false);
}
if (my_cells.indexOf(prey) != -1){
OnLoseMass(prey, predator);
RenderStats(false);
}
};
unsafeWindow.OnLeaderboard = function(position) {
stats.top_slot = Math.min(stats.top_slot, position);
};
unsafeWindow.OnDraw = function(context) {
display_stats && stat_canvas && context.drawImage(stat_canvas, 10, 10);
};
//wspam
(function() {
var amount = 2;
var duration = 50; //ms
var overwriting = function(evt) {
if (evt.keyCode === 81) { // 81=KEY_Q <<<------------- set key for W spam 86 means W just works, but after long press starts spamming
for (var i = 0; i < amount; ++i) {
setTimeout(function() {
window.onkeydown({keyCode: 87}); // KEY_W
window.onkeyup({keyCode: 87});
}, i * duration);
}
}
};
window.addEventListener('keydown', overwriting);
})();
// ====================== Music & SFX System ==============================================================
//sfx play on event (only one of each sfx can play - for sfx that won't overlap with itself)
var ssfxlist = [
'spawn',
'gameover'
];
var ssfxs = [];
for (i=0;i<ssfxlist.length;i++) {
var newsfx = new Audio("http://skins.agariomods.com/botb/sfx/" + ssfxlist[i] + ".mp3");
newsfx.loop = false;
ssfxs.push(newsfx);
}
function sfx_play(id) {
if (document.getElementById("sfx").value==0) return;
var event = ssfxs[id];
event.volume = document.getElementById("sfx").value;
event.play();
}
//sfx insertion on event (multiple of same sfx can be played simultaneously)
var sfxlist = [
'pellet',
'split',
'eat',
'bounce',
'merge',
'virusfeed',
'virusshoot',
'virushit'
];
var sfxs = {};
for (i=0;i<sfxlist.length;i++) {
var newsfx = new Audio("//skins.agariomods.com/botb/sfx/" + sfxlist[i] + ".mp3");
newsfx.loop = false;
newsfx.onended = function() {
$(this).remove();
};
sfxs[sfxlist[i]] = newsfx;
}
function sfx_event(id) {
if (document.getElementById("sfx").value==0) return;
var event = jQuery.clone(sfxs[id]);
event.volume = document.getElementById("sfx").value;
event.play();
}
var StartBGM = function () {
if (document.getElementById("bgm").value==0) return;
if (bgmusic.src == ""){
bgmusic.src = _.sample(tracks, 1);
bgmusic.load()
}
bgmusic.volume = document.getElementById("bgm").value;
bgmusic.play();
};
var StopBGM = function () {
bgmusic.pause();
if (document.getElementById("bgm").value==0) return;
bgmusic.src = _.sample(tracks, 1);
bgmusic.load()
};
volBGM = function (vol) {
console.log(vol.toString() + " - " + document.getElementById("bgm").value)
bgmusic.volume = document.getElementById("bgm").value;
window.cobbler.bgmVol = document.getElementById("bgm").value;
};
volSFX = function (vol) {
window.cobbler.sfxVol = vol;
};
var tracks = ['http://incompetech.com/music/royalty-free/mp3-preview2/Frost%20Waltz.mp3',
'http://incompetech.com/music/royalty-free/mp3-preview2/Frozen%20Star.mp3',
'http://incompetech.com/music/royalty-free/mp3-preview2/Groove%20Grove.mp3',
'http://incompetech.com/music/royalty-free/mp3-preview2/Dreamy%20Flashback.mp3',
'http://incompetech.com/music/royalty-free/mp3-preview2/Impact%20Lento.mp3',
'http://incompetech.com/music/royalty-free/mp3-preview2/Wizardtorium.mp3'];
/*sfx*/
var nodeAudio = document.createElement("audio");
nodeAudio.id = 'audiotemplate';
nodeAudio.preload = "auto";
jQuery(".agario-panel").get(0).appendChild(nodeAudio);
var bgmusic = $('#audiotemplate').clone()[0];
bgmusic.src = tracks[Math.floor(Math.random() * tracks.length)];
bgmusic.load();
bgmusic.loop = false;
bgmusic.onended = function() {
var track = tracks[Math.floor(Math.random() * tracks.length)];
bgmusic.src = track;
bgmusic.play();
};
function uiOnLoadTweaks(){
$("label:contains('Dark theme') input").prop('checked', true);
setDarkTheme(true);
$("label:contains('Show mass') input").prop('checked', true);
setShowMass(true);
$('#nick').val(GM_getValue("nick", ""));
}
//================================ AgarioMods Private Servers ========================================================
unsafeWindow.openServerbrowser = function (a) {
var b = unsafeWindow.openServerbrowser.loading;
if(b) {
return;
}
b = true;
jQuery("#rsb")
.prop("disabled", true);
if(!a) {
jQuery("#serverBrowser")
.fadeIn();
}
getServers();
};
function serverinfo(list, index) {
if(index >= list.length) {
unsafeWindow.openServerbrowser.loading = false;
jQuery("#rsb")
.prop("disabled", false);
return;
}
value = list[index];
started = Date.now();
statsurl = "http://" + value[0] + ".iomods.com:" + (8080 + value[1]);
jQuery.ajax({
url: statsurl,
dataType: "json",
success: function (data) {
$("#" + (value[0] + value[1]) + " #player")
.text(data.current_players + "/" + data.max_players);
latency = Date.now() - started;
if(latency < 100) {
jQuery("#" + (value[0] + value[1]) + " #latency")
.css("color", "#19A652");
} else {
if(latency < 250) {
jQuery("#" + (value[0] + value[1]) + " #latency")
.css("color", "#E1BD2C");
} else {
jQuery("#" + (value[0] + value[1]) + " #latency")
.css("color", "#F00");
}
}
jQuery("#" + (value[0] + value[1]) + " #latencyres")
.text(latency + "ms");
},
error: function (data) {
jQuery("#" + (value[0] + value[1]) + " #player")
.text("No information");
jQuery("#" + (value[0] + value[1]) + " #latency")
.css("color", "#f00");
jQuery("#" + (value[0] + value[1]) + " #latency")
.text("Failed");
},
complete: function (data) {
if(!(document.getElementById("serverBrowser")
.style.display == "none")) {
serverinfo(list, index + 1);
}
}
});
}
unsafeWindow.connectPrivate = function (location, i) {
var ip = location.toLowerCase()
.replace(" ", "") + ".iomods.com";
var port = 1500 + parseInt(i);
//server.ip = ip;
//server.i = i;
//server.location = location;
connect("ws://" + ip + ":" + port, "");
//openChat();
};
var st = document.createElement("style");
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}";
document.head.appendChild(st);
unsafeWindow.closeServerbrowser = function () {
jQuery("#serverBrowser")
.fadeOut();
};
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");
locations.sort();
locations[0] = [locations[1], locations[1] = locations[0]][0];
function getServers() {
jQuery("#serverlist1")
.empty();
jQuery("#serverlist2")
.empty();
var latencylist = Array();
jQuery.each(locations, function (index, value) {
var i = 1;
for(; i <= 2; i++) {
serverid = value.toLowerCase()
.replace(" ", "") + i;
$("#serverlist" + i)
.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>');
latencylist.push(new Array(value.toLowerCase()
.replace(" ", ""), i));
}
});
serverinfo(latencylist, 0);
}
jQuery(document)
.ready(function () {
jQuery("body")
.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>');
jQuery("body")
.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>');
});
// ===============================================================================================================
uiOnLoadTweaks();
var col1 = $("#col1");
col1.append("<h4>Options</h4>");
AppendCheckbox(col1, 'showZcStats-checkbox', ' Show ZC Stats On Death', window.cobbler.showZcStats, function(val){window.cobbler.showZcStats = val;});
col1.append("<h4>Modes</h4>");
AppendCheckbox(col1, 'litebrite-checkbox', ' Enable Lite Brite Mode', window.cobbler.isLiteBrite, function(val){window.cobbler.isLiteBrite = val;});
col1.append("<h4>Visual</h4>");
AppendCheckbox(col1, 'trailingtail-checkbox', ' Draw Trailing Tail', window.cobbler.drawTail, function(val){window.cobbler.drawTail = val;});
AppendCheckbox(col1, 'splitguide-checkbox', ' Draw Split Guide', window.cobbler.splitGuide, function(val){window.cobbler.splitGuide = val;});
AppendCheckbox(col1, 'rainbow-checkbox', ' Rainbow Pellets', window.cobbler.rainbowPellets, function(val){window.cobbler.rainbowPellets = val;});
AppendCheckbox(col1, 'namesunder-checkbox', ' Names under blobs', window.cobbler.namesUnderBlobs, function(val){window.cobbler.namesUnderBlobs = val;});
AppendCheckbox(col1, 'gridlines-checkbox', ' Show Gridlines', window.cobbler.gridLines, function(val){window.cobbler.gridLines = val;});
col1.append("<h4>Stats</h4>");
AppendCheckbox(col1, 'chart-checkbox', ' Show in-game chart', display_chart, OnChangeDisplayChart);
AppendCheckbox(col1, 'stats-checkbox', ' Show in-game stats', display_stats, OnChangeDisplayStats);
col1.append("<h4>Features</h4>");
AppendCheckbox(col1, 'feature-click-fire', ' Click to fire @ virus', window.cobbler.rightClickFires, function(val) {window.cobbler.rightClickFires = val;});
AppendCheckbox(col1, 'feature-blob-lock', ' Click to lock blob', window.cobbler.enableBlobLock, function(val) {window.cobbler.enableBlobLock = val;});
AppendCheckbox(col1, 'feature-blob-lock-next', ' Switch blob on lock', window.cobbler.nextOnBlobLock, function(val) {window.cobbler.nextOnBlobLock = val;});
var col2 = $("#col2");
col2.append('<h4>Debug Level</h4><div class="btn-group-sm" role="group" data-toggle="buttons">' +
'<label class="btn btn-primary"><input type="radio" name="DebugLevel" id="DebugNone" autocomplete="off" value=0>None</label>' +
'<label class="btn btn-primary"><input type="radio" name="DebugLevel" id="DebugLow" autocomplete="off" value=1>Low</label>' +
'<label class="btn btn-primary"><input type="radio" name="DebugLevel" id="DebugHigh" autocomplete="off" value=2>High</label>' +
'</div>');
$('input[name="DebugLevel"]:radio[value='+window.cobbler.debugLevel +']').parent().addClass("active");
$('input[name="DebugLevel"]').change( function() {window.cobbler.debugLevel = $(this).val();});
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)"' +
'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>');
$('#mspershot-textbox').on('input propertychange paste', function() {
var newval = parseInt(this.value);
if(!_.isNaN(newval) && newval > 0 && newval <= 2000) {
$("#mspershot-group").removeClass('has-error');
cobbler.msDelayBetweenShots = newval;
}
else{
$("#mspershot-group").addClass('has-error');
}
});
col2.append('<h4>Minimap Scale</h4>' +
'<div id="minimap-group" class="input-group input-group-sm"><span class="input-group-addon"><input id="minimap-checkbox" type="checkbox"></span>' +
'<input id="minimap-textbox" type="text" placeholder="64 = 1/64 scale" class="form-control" value='+ cobbler.miniMapScaleValue +'></div>');
$('#minimap-checkbox').change(function(){
if(!!this.checked){
$('#minimap-textbox').removeAttr("disabled");
} else {
$('#minimap-textbox').attr({disabled:"disabled"})
}
cobbler.miniMapScale = !!this.checked;
});
if(cobbler.miniMapScale){$('#minimap-checkbox').prop('checked', true);}else{ $('#minimap-textbox').attr({disabled:"disabled"})}
$('#minimap-textbox').on('input propertychange paste', function() {
var newval = parseInt(this.value);
if(!_.isNaN(newval) && newval > 1 && newval < 999) {
$("#minimap-group").removeClass('has-error');
cobbler.miniMapScaleValue = newval;
}
else{
$("#minimap-group").addClass('has-error');
}
});
col2.append('<h4>Grazer</h4><div id="grazer-checks" class="checkbox" ></div>');
var grazerChecks = $("#grazer-checks");
AppendCheckbox(grazerChecks, 'autorespawn-checkbox', ' Grazer Auto-Respawns', window.cobbler.autoRespawn, function(val){window.cobbler.autoRespawn = val;});
AppendCheckbox(grazerChecks, 'option5', ' Visualize Grazer', window.cobbler.visualizeGrazing, function(val){window.cobbler.visualizeGrazing = val;});
AppendCheckbox(grazerChecks, 'grazer-multiBlob-checkbox', ' Grazer MultiBlob', window.cobbler.grazerMultiBlob2, function(val){window.cobbler.grazerMultiBlob2 = val;});
col2.append('<h5>Hybrid Grazer</h5>' +
'<div id="hybrid-group" class="input-group input-group-sm"><span class="input-group-addon"><input id="hybrid-checkbox" type="checkbox"></span>' +
'<input id="hybrid-textbox" type="text" class="form-control" value='+ cobbler.grazerHybridSwitchMass +' placeholder="Default: 300"></div>' +
'<h6>Starts with old grazer and at specified mass switches to new grazer</h6>');
$('#hybrid-checkbox').change(function(){
if(!!this.checked){
$('#hybrid-textbox').removeAttr("disabled");
} else {
$('#hybrid-textbox').attr({disabled:"disabled"})
}
cobbler.grazerHybridSwitch = !!this.checked;
});
if(cobbler.grazerHybridSwitch){$('#hybrid-checkbox').prop('checked', true);}else{ $('#hybrid-textbox').attr({disabled:"disabled"})}
$('#hybrid-textbox').on('input propertychange paste', function() {
var newval = parseInt(this.value);
if(!_.isNaN(newval)) {
$("#hybrid-group").removeClass('has-error');
cobbler.grazerHybridSwitchMass = newval;
}
else{
$("#hybrid-group").addClass('has-error');
}
});
var col3 = $("#col3");
col3.append("<h4>Music/Sound</h4>");
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>');
col3.append('<p>Music<input type="range" id="bgm" value=' + window.cobbler.bgmVol + ' step=".1" min="0" max="1" oninput="volBGM(this.value);"></p>');
col3.append('<h4>Skins Support</h4>');
AppendCheckboxP(col3, 'amConnect-checkbox', ' AgarioMods Connect *skins', window.cobbler.amConnectSkins, function(val){window.cobbler.amConnectSkins = val;});
AppendCheckboxP(col3, 'amExtended-checkbox', ' AgarioMods Extended skins', window.cobbler.amExtendedSkins, function(val){window.cobbler.amExtendedSkins = val;});
AppendCheckboxP(col3, 'imgur-checkbox', ' Imgur.com i/skins', window.cobbler.imgurSkins, function(val){window.cobbler.imgurSkins = val;});
// ---- Tooltips
$("#rainbow-checkbox").attr({"data-toggle": "tooltip", "data-placement": "right",
"title": "Allow food pellets to be rainbow colored rather than purple. Combines well with Lite Brite Mode"});
$("#litebrite-checkbox").attr({"data-toggle": "tooltip", "data-placement": "right",
"title": "Leaves blob centers empty except for skins."});
setTimeout(function(){$(function () { $('[data-toggle="tooltip"]').tooltip()})}, 5000); // turn on all tooltips.
// Ugly ass hack to fix effects of official code loading before mod
//$("#canvas").remove();
//$("body").prepend('<canvas id="canvas" width="800" height="600"></canvas>');
//================================ Skins from skins.AgarioMods.com ===================================================
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(";");