var algorithm = function(check, influence) { // Calculate separation between cell and check var checkPos = check.position; var displacement = new Vector(checkPos.x - cellPos.x, checkPos.y - cellPos.y); // Figure out distance between cells var distance = displacement.length(); if (influence < 0) { // Get edge distance distance -= cell.getSize() + check.getSize(); if (check.cellType == 0) threats.push(check); } // The farther they are the smaller influnce it is if (distance < 1) distance = 1; // Avoid NaN and positive influence with negative distance & attraction influence /= distance; // Produce force vector exerted by this entity on the cell var force = displacement.normalize().scale(influence); // Splitting conditions if (check.cellType == 0 && cell.mass / 2.2 > check.mass && cell.mass / 5 < check.mass && !split && splitCooldown == 0 && cellLength < 6) { // Calculate split distance and check if it is larger than the raw distance var mass = cell.mass; var t = Math.PI * Math.PI; var modifier = 3 + Math.log(1 + mass) / 10; var splitSpeed = cell.owner.gameServer.config.playerSpeed * Math.min(Math.pow(mass, -Math.PI / t / 10) * modifier, 150); var endDist = Math.max(splitSpeed * 6.8, cell.getSize() * 2); // Checked via C#, final distance is near 6.512x splitSpeed if (endDist > distance) { // Set the target to split after every entity in visible nodes has passed splitTarget = check; split = true; } } else if (check.cellType == 0 && check.mass > cell.mass / 2.6 && splitCooldown == 0) { if (distance < cell.getSize() * 3) { splitTarget = check; splitAway = true; split = true; } } else { // Add up forces on the entity result.add(force); } }
BotPlayer.prototype.decide = function (cell) { if (!cell) return; // Cell was eaten, check in the next tick (I'm too lazy) var cellPos = cell.position; var result = new Vector(0, 0); // Splitting var split = false, splitTarget = null, threats = []; for (var i = 0; i < this.viewNodes.length; i++) { var check = this.viewNodes[i]; if (check.owner == this) continue; // Get attraction of the cells - avoid larger cells, viruses and same team cells var influence = 0; if (check.cellType == 0) { // Player cell if (this.gameServer.gameMode.haveTeams && (cell.owner.team == check.owner.team)) { // Same team cell influence = 0; } else if (cell.getSize() > (check.getSize() + 4) * 1.15) { // Can eat it influence = check.getSize() * 2.5; } else if (check.getSize() + 4 > cell.getSize() * 1.15) { // Can eat me influence = -check.getSize(); } else { influence = -(check.getSize() / cell.getSize()) / 3; } } else if (check.cellType == 1) { // Food influence = 1; } else if (check.cellType == 2) { // Virus if (cell.getSize() > check.getSize() * 1.15) { // Can eat it if (this.cells.length == this.gameServer.config.playerMaxCells) { // Won't explode influence = check.getSize() * 2.5; } else { // Can explode influence = -1; } } else if (check.isMotherCell && check.getSize() > cell.getSize() * 1.15) { // can eat me influence = -1; } } else if (check.cellType == 3) { // Ejected mass if (cell.getSize() > check.getSize() * 1.15) // can eat influence = check.getSize(); } else { influence = check.getSize(); // Might be TeamZ } // Apply influence if it isn't 0 or my cell if (influence == 0 || cell.owner == check.owner) continue; // Calculate separation between cell and check var checkPos = check.position; var displacement = new Vector(checkPos.x - cellPos.x, checkPos.y - cellPos.y); // Figure out distance between cells var distance = displacement.length(); if (influence < 0) { // Get edge distance distance -= cell.getSize() + check.getSize(); if (check.cellType == 0) threats.push(check); } // The farther they are the smaller influnce it is if (distance < 1) distance = 1; // Avoid NaN and positive influence with negative distance & attraction influence /= distance; // Produce force vector exerted by this entity on the cell var force = displacement.normalize().scale(influence); // Splitting conditions if (check.cellType == 0 && cell.getSize() > (check.getSize() + 4) * 1.15 && cell.getSize() < check.getSize() * 5 && (!split) && this.splitCooldown == 0 && this.cells.length < 3) { var endDist = 780 + 40 - cell.getSize() / 2 - check.getSize(); if (endDist > 0 && distance < endDist) { splitTarget = check; split = true; } } else { // Add up forces on the entity result.add(force); } } // Normalize the resulting vector result.normalize(); // Check for splitkilling and threats if (split) { // Can be shortened but I'm too lazy if (threats.length > 0) { if (this.largest(threats).getSize() > cell.getSize() * 1.5) { // Splitkill the target this.mouse = { x: splitTarget.position.x, y: splitTarget.position.y }; this.splitCooldown = 16; this.socket.packetHandler.pressSpace = true; //this.gameServer.splitCells(this); return; } } else { // Still splitkill the target this.mouse = { x: splitTarget.position.x, y: splitTarget.position.y }; this.splitCooldown = 16; this.socket.packetHandler.pressSpace = true; //this.gameServer.splitCells(this); return; } } this.mouse = { x: cellPos.x + result.x * 800, y: cellPos.y + result.y * 800 }; };
BotPlayer.prototype.decide = function(cell) { if (!cell) return; // Cell was eaten, check in the next tick (I'm too lazy) var cellPos = cell.position; var result = new Vector(0, 0); // Splitting var cellLength = this.cells.length, splitCooldown = this.splitCooldown, split = false, splitTarget = null, splitAway = false, threats = []; var algorithm = function(check, influence) { // Calculate separation between cell and check var checkPos = check.position; var displacement = new Vector(checkPos.x - cellPos.x, checkPos.y - cellPos.y); // Figure out distance between cells var distance = displacement.length(); if (influence < 0) { // Get edge distance distance -= cell.getSize() + check.getSize(); if (check.cellType == 0) threats.push(check); } // The farther they are the smaller influnce it is if (distance < 1) distance = 1; // Avoid NaN and positive influence with negative distance & attraction influence /= distance; // Produce force vector exerted by this entity on the cell var force = displacement.normalize().scale(influence); // Splitting conditions if (check.cellType == 0 && cell.mass / 2.2 > check.mass && cell.mass / 5 < check.mass && !split && splitCooldown == 0 && cellLength < 6) { // Calculate split distance and check if it is larger than the raw distance var mass = cell.mass; var t = Math.PI * Math.PI; var modifier = 3 + Math.log(1 + mass) / 10; var splitSpeed = cell.owner.gameServer.config.playerSpeed * Math.min(Math.pow(mass, -Math.PI / t / 10) * modifier, 150); var endDist = Math.max(splitSpeed * 6.8, cell.getSize() * 2); // Checked via C#, final distance is near 6.512x splitSpeed if (endDist > distance) { // Set the target to split after every entity in visible nodes has passed splitTarget = check; split = true; } } else if (check.cellType == 0 && check.mass > cell.mass / 2.6 && splitCooldown == 0) { if (distance < cell.getSize() * 3) { splitTarget = check; splitAway = true; split = true; } } else { // Add up forces on the entity result.add(force); } } this.visibleNodes.forEach(function(check) { // Get attraction of the cells - avoid larger cells, viruses and same team cells var influence = 0; if (check.cellType == 0) { // Player cell if (cell.owner.gameServer.gameMode.hasTeams && (cell.owner.team == check.owner.team)) influence = -1; // Same team cell else if (cell.mass / 1.3 > check.mass) influence = check.getSize(); // Can eat it else if (check.mass / 1.3 > cell.mass) influence = -check.getSize(); // Can eat me } else if (check.cellType == 1) { // Food influence = 1; } else if (check.cellType == 2) { // Virus if (cell.mass / 1.3 < check.mass) influence = -1; // Can eat it } else if (check.cellType == 3) { // Ejected mass if (cell.mass / 1.3 > check.mass) influence = check.getSize(); } else if (check.cellType == 4) { // Sticky Cell influence = -1; } else if (check.cellType == 5) { // Beacon Cell influence = 0; } else { influence = check.getSize(); // Might be TeamZ } // Apply influence if it isn't 0 or my cell if (influence != 0 && cell.owner != check.owner) algorithm(check, influence); }); // Normalize the resulting vector result.normalize(); // Check for splitkilling and threats if (split) { if (threats.length > 0) { if (this.largest(threats).mass / 2.6 > cell.mass && !splitAway) { // Splitkill the target this.mouse = { x: splitTarget.position.x, y: splitTarget.position.y }; this.splitCooldown = 16; this.gameServer.splitCells(this); return; } else if (splitAway) { // Find angle of vector between cell and predator var deltaY = splitTarget.position.y - cellPos.y; var deltaX = splitTarget.position.x - cellPos.x; var angle = Math.atan2(deltaX, deltaY); // Now reverse the angle angle = this.reverseAngle(angle); // Direction to move this.mouse = { x: cellPos.x + (750 * Math.cos(angle)), y: cellPos.y + (750 * Math.sin(angle)) }; this.splitCooldown = 7; this.gameServer.splitCells(this); return; } } } if( this.splitCooldown > 0 ) this.splitCooldown--; this.mouse = { x: cellPos.x + result.x * 500, y: cellPos.y + result.y * 500 }; };