Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name botkeys
- // @version 0.1
- // @include http://*.jukejuice.com:*
- // @include http://*.newcompte.fr:*
- // @grant none
- // ==/UserScript==
- MAP_VEL_PX = 100; // scale velocities by this to get pixels/second
- 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();
- }
- }
- }
- function script() {
- var ENABLE = false;
- window.onkeydown = function(e) {ENABLE = (e && e.shiftKey);};
- window.onkeyup = function(e) {ENABLE = (e && e.shiftKey);};
- var ctrl_period = 50;
- var counter = 0;
- // 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;
- tagpro.players[this.player.id].vy = this.m_linearVelocity.y;
- return this.m_linearVelocity;
- };
- function create_controller(PIDconstants){
- var controller = {};
- controller.output = {};
- controller.output.threshold = 0.18;
- controller.output.set = function(u,me){
- this.horz(u.x,me);
- this.vert(u.y,me);
- };
- controller.clear_botkeys = function(me) {
- me.botkeys.up = false;
- me.botkeys.down = false;
- me.botkeys.left = false;
- me.botkeys.right = false;
- }
- controller.output.setkey = function(key, ispressed, me) {
- if (me[key] != ispressed) {
- tagpro.sendKeyPress(key, !ispressed);
- me[key] = ispressed;
- //me.botkeys[key] = ispressed;
- }
- }
- controller.output.presskeys = function(val, keys, me) {
- if (val > this.threshold) {
- this.setkey(keys[0], true, me);
- this.setkey(keys[1], false, me);
- } else if (val < -this.threshold) {
- this.setkey(keys[1], true, me);
- this.setkey(keys[0], false, me);
- } else {
- this.setkey(keys[0], false, me);
- this.setkey(keys[1], false, me);
- }
- }
- controller.output.horz = function(x,me){
- this.presskeys(x, ["right","left"], me);
- }
- controller.output.vert = function(y,me){
- this.presskeys(y, ["up","down"], me);
- }
- controller.execute = function(me,target){
- if (target) {
- var ctrl_vec = this.PID.get_ctrl_vec(me,target);
- this.output.set(ctrl_vec,me);
- }
- }
- function create_PID(constants){
- var PID = {};
- PID.dims = {};
- PID.dims.list = ['x','y'];
- PID.dims.num = PID.dims.list.length;
- PID.constants = {};
- PID.constants.set_constants = function(constants){
- for (var key in constants){
- if (constants.hasOwnProperty(key)) {
- this[key] = constants[key];
- }
- }
- }
- PID.constants.set_constants(constants);
- PID.accum_error = {};
- PID.reset_accum_error = function(){
- PID.accum_error.pos = {'x':0,'y':0};
- PID.accum_error.vel = {'x':0,'y':0};
- };
- PID.reset_accum_error();
- PID.errors = {}; // gets set before its read
- PID.get_ctrl_vec = function(state_current, state_goal){
- this.errors = this.calc_error(state_current,state_goal);
- this.accumulate_error(this.errors);
- var u = {};
- for (var i = 0; i < this.dims.num; i++){
- var dim = this.dims.list[i];
- u[dim] = this.calc_P(dim) + this.calc_I(dim) + this.calc_D(dim);
- }
- return u;
- };
- PID.calc_P = function(axis){
- return this.constants.KP*this.errors.pos[axis];
- }
- PID.calc_I = function(axis){
- return this.constants.KI*this.accum_error.pos[axis];
- };
- PID.calc_D = function(axis){
- return this.constants.KD*this.errors.vel[axis];
- };
- PID.calc_error = function(state_current, state_goal){
- var errors = {};
- errors.pos = {};
- errors.vel = {};
- errors.pos.x = state_goal.x - state_current.x;
- errors.pos.y = state_current.y - state_goal.y;
- errors.vel.x = state_goal.vx - state_current.vx;
- errors.vel.y = state_current.vy - state_goal.vy;
- return errors;
- };
- PID.accumulate_error = function(errors){
- this.accum_error.pos.x += errors.pos.x;
- this.accum_error.pos.y += errors.pos.y;
- if (this.accum_error.pos.x > this.constants.KS) this.accum_error.pos.x = this.constants.KS;
- if (-this.accum_error.pos.x > this.constants.KS) this.accum_error.pos.x = -this.constants.KS;
- if (this.accum_error.pos.y > this.constants.KS) this.accum_error.pos.y = this.constants.KS;
- if (-this.accum_error.pos.y > this.constants.KS) this.accum_error.pos.y = -this.constants.KS;
- };
- return PID;
- }
- controller.PID = create_PID(PIDconstants);
- return controller;
- }
- function create_decision_maker(me){
- var decision_maker = {};
- decision_maker.me = me;
- decision_maker.find_player = function(criterion_fn){
- for (var key in tagpro.players) {
- if (tagpro.players.hasOwnProperty(key)) {
- // criterian_fn must take decision_maker and a player as arguments
- if (criterion_fn(this,tagpro.players[key])) {
- return tagpro.players[key];
- }
- }
- }
- return null;
- }
- decision_maker.create_target = function(){
- var target = {};
- var opponent = this.find_player(function(dm,player){return (player.flag === me.team) || (player.flag === 3);});
- if (opponent) {
- target = opponent;
- var p_thres = 30;
- var v_thres = 30;
- if (Math.abs(opponent.x - me.x) < p_thres && Math.abs(opponent.vx - me.vx) < v_thres) {
- target.vy = Math.sign(opponent.y - me.y) * 1000;
- }
- if (Math.abs(opponent.y - me.y) < p_thres && Math.abs(opponent.vy - me.vy) < v_thres) {
- target.vx = Math.sign(opponent.x - me.x) * 1000;
- }
- }
- else {
- target = me;
- }
- return target;
- }
- return decision_maker;
- }
- function main() {
- var me = tagpro.players[tagpro.playerId];
- me.botkeys = {up: false, down: false, left: false, right: false};
- PID_constants = {};
- PID_constants.KP = 0.018;
- PID_constants.KI = 0.011;
- PID_constants.KD = 3.5;
- PID_constants.KS = 11;
- var controller = create_controller(PID_constants);
- var decision_maker = create_decision_maker(me);
- setInterval(function() {
- if (ENABLE) {
- // determine a target state
- var target = decision_maker.create_target();
- // execute the control to get to the target
- controller.execute(me,target);
- }
- else {
- controller.clear_botkeys(me);
- }
- }, ctrl_period);
- }
- main();
- }
- function startFunction() {
- var keys = {};
- function addArrow(s,p) {
- var a = new PIXI.Graphics();
- s.addChild(a);
- a.beginFill(0x000000);
- a.lineStyle(1, 0x000000);
- a.drawCircle(p[0]*10 + 20, p[1]*10 + 20, 3);
- return a;
- }
- function addArrows(id) {
- var s = tagpro.players[id].sprite;
- var k = {};
- k.down = addArrow(s, [0,1]);
- k.right = addArrow(s, [1,0]);
- k.up = addArrow(s, [0,-1]);
- k.left = addArrow(s, [-1,0]);
- keys[id] = k;
- }
- addArrows(tagpro.playerId);
- (function loop() {
- requestAnimationFrame(loop);
- update();
- })();
- function update() {
- var id = tagpro.playerId;
- var p = tagpro.players[id];
- var dirs = ["up","down","left","right"];
- for (var i = 0; i < dirs.length; i++) {
- var d = dirs[i];
- keys[id][d].visible = p.botkeys[d];
- }
- }
- }
- tagpro.ready(function() {
- waitForId(script);
- setTimeout(startFunction,1000);
- });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement