Skip to content

Instantly share code, notes, and snippets.

@chrahunt
Created January 29, 2015 20:18
Show Gist options
  • Save chrahunt/90d1c4aab5ad81ec4812 to your computer and use it in GitHub Desktop.
Save chrahunt/90d1c4aab5ad81ec4812 to your computer and use it in GitHub Desktop.
A userscript-based starter bot for the game TagPro.
// ==UserScript==
// @name TagPro Example Bot
// @description Limited example bot for TagPro.
// @version 0.1
// @grant none
// @include http://tagpro-maptest.koalabeast.com:*
// @include http://tangent.jukejuice.com:*
// @include http://*.newcompte.fr:*
// @author Cflakes, snaps_
// @namespace http://www.reddit.com/user/snaps_
// @license 2015
// ==/UserScript==
/*
* This function will execute the provided function after tagpro.playerId
* has been assigned.
*/
function waitForId(fn) {
// Don't execute the function until tagpro.playerId has been assigned.
if (!tagpro || !tagpro.playerId) {
return setTimeout(function() {
waitForId(fn)
}, 100);
} else {
// Only run the script if we are not spectating.
if (!tagpro.spectator) {
fn();
}
}
}
// We define everything relevant to our bot inside this function.
function script() {
// Assign our own player object to `self` for readability.
var self = tagpro.players[tagpro.playerId];
// Sends key events to move to a destination.
function move(destination) {
if (destination.x > 1) {
tagpro.sendKeyPress("left", true);
tagpro.sendKeyPress("right", false);
} else if (destination.x < -1) {
tagpro.sendKeyPress("right", true);
tagpro.sendKeyPress("left", false);
} else {
tagpro.sendKeyPress("right", true);
tagpro.sendKeyPress("left", true);
}
if (destination.y > 1) {
tagpro.sendKeyPress("up", true);
tagpro.sendKeyPress("down", false);
} else if (destination.y < -1) {
tagpro.sendKeyPress("down", true);
tagpro.sendKeyPress("up", false);
} else {
tagpro.sendKeyPress("up", true);
tagpro.sendKeyPress("down", true);
}
}
// Overriding this function to get a more accurate velocity of players.
// Velocity is saved in player.vx and vy.
Box2D.Dynamics.b2Body.prototype.GetLinearVelocity = function() {
tagpro.players[this.player.id].vx = this.m_linearVelocity.x * 55;
tagpro.players[this.player.id].vy = this.m_linearVelocity.y * 55;
return this.m_linearVelocity;
};
// Returns the position (in pixels) of the flag.
// Color is a string, one of either: 'red', 'blue', or 'yellow'.
function findFlag(color) {
for (var x = 0, xl = tagpro.map.length, yl = tagpro.map[0].length; x < xl; x++) {
for (var y = 0; y < yl; y++) {
switch (Math.floor(tagpro.map[x][y])) {
case 3:
if (color === 'red')
return {x: x * 40, y: y * 40};
break;
case 4:
if (color === 'blue')
return {x: x * 40, y: y * 40};
break;
case 16:
if (color === 'yellow')
return {x: x * 40, y: y * 40};
break;
}
}
}
}
// Returns the enemy FC if in view.
function enemyFC() {
for (var id in tagpro.players) {
if (!tagpro.players.hasOwnProperty(id))
continue;
var player = tagpro.players[id];
if (player.team === self.team || player.dead || !player.draw)
continue;
if (player.flag)
return player;
}
}
/*
* The logic/flowchart.
* If team flag is home, sit on flag.
* If team flag is gone, go to enemy team flag.
* If an enemy FC is spotted at any time, chase.
*
* Note: There is NO pathfinding.
*/
function main() {
requestAnimationFrame(main);
var seek = {},
enemy = enemyFC(),
flag = null;
if (enemy) {
seek.x = (enemy.x + enemy.vx) - (self.x + self.vx);
seek.y = (enemy.y + enemy.vy) - (self.y + self.vy);
} else {
if ((self.team === 1 && tagpro.ui.redFlagTaken) || (self.team === 2 && !tagpro.ui.blueFlagTaken)) {
flag = findFlag('blue');
} else {
flag = findFlag('red');
}
if (!flag) {
flag = findFlag('yellow');
}
seek.x = flag.x - (self.x + self.vx);
seek.y = flag.y - (self.y + self.vy);
}
move(seek);
}
main();
}
// Initialize the script when tagpro is ready, and additionally wait
// for the playerId property to be assigned.
tagpro.ready(function() {
waitForId(script);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment