<commit_before>// HUBCAVE
// window.onbeforeunload = function (e) {
//   return "Quit game?";
// };

// Disable the chat window initially
$('#chat_input').width($('.chat-panel').width() - 50);

socket = io.connect("/game", {
                        transports: ['websocket',
                                     'flashsocket',
                                     'polling']
                    });
socket.on('connect', function () {
              socket.emit('join', [game_id, user_id]);
          });

socket.on('loading', function (data) {
              hubcave_data = data.map;
              for (var i = data.messages.length - 1; i >= 0; --i){
                  var msg = data.messages[i];
                  $("#room_chat ul").prepend(
                      '<li>[' + msg.when + '] ' +
                          '<a href=/profile/' + msg.user_id + '>' +
                          msg.user_name + ' </a><span> ' +
                          msg.text + ' </span>' +
                          '</li>');
              }
              run_game();
          });

// Let us kick off the show

function run_game() {
    // create an new instance of a pixi stage
    var stage = new PIXI.Stage(0x000000);

    var render_size = Math.min($('#game_panel').width() - 50,
                               $('#game_panel').width());

    var renderer = PIXI.autoDetectRenderer(render_size,
                                           render_size);

    // Define textures
    var wallTexture = PIXI.Texture.fromImage("/static/img/wall.png");
    var floorTexture = PIXI.Texture.fromImage("/static/img/floortile.png");
    var projectileTexture = PIXI.Texture.fromImage("/static/img/arrow.png");
    var charTexture = PIXI.Texture.fromImage("/static/img/ghlogo.png");
    var vignetteTexture = PIXI.Texture.fromImage("/static/img/vignette.png");

    for (i=0; i < hubcave_data.blockdata.length; ++i) {
        var block = hubcave_data.blockdata[i];
    }

    // PIXI.Texture.addTextureToCache(wallTexture, 'walltex');
    var blocksize = 50;

    renderer.view.className = "rendererView";
    $('.canvas-panel').append(renderer.view);

    //
    // Build out the map sprites according to blockdata
    //

    scrollArea = new PIXI.DisplayObjectContainer();
    scrollArea.interactive = true;
    scrollArea.buttonMode = true;
    scrollArea.defaultCursor = "crosshair";

    var max_width = 0,
    max_height = 0;
    var terrain = {};
    projectiles = {};

    for (i=0; i < hubcave_data.blockdata.length; ++i) {
        var block = hubcave_data.blockdata[i];
        terrain[block.x] = terrain[block.x] ? terrain[block.x] : {};
        terrain[block.x][block.y] = block.blktype;
        if (!block.blktype) {
            wall_sprite = new PIXI.Sprite(wallTexture);
            wall_sprite.width = blocksize;
            wall_sprite.height = blocksize;
            wall_sprite.position.y = block.x * blocksize;
            wall_sprite.position.x = block.y * blocksize;
            scrollArea.addChild(wall_sprite);
        } else {
            floor_sprite = new PIXI.Sprite(floorTexture);
            floor_sprite.width = blocksize;
            floor_sprite.height = blocksize;
            floor_sprite.position.y = block.x * blocksize;
            floor_sprite.position.x = block.y * blocksize;
            scrollArea.addChild(floor_sprite);
        }
        max_width = Math.max(max_width, block.x);
        max_height = Math.max(max_height, block.y);
    }

    scrollArea.scale.x = render_size / blocksize / 5;
    scrollArea.scale.y = scrollArea.scale.x;

    users = {};

    // Bow is default item at '1'
    // Items/keys -> map 2-0 keys to select
    // HP/ammo

    // DECLARE PLAYER OBJECT

    player_sprite = new PIXI.Sprite(charTexture);
    player_sprite.velocity_x = 0
    player_sprite.velocity_y = 0
    player_sprite.width = blocksize / 2;
    player_sprite.height = blocksize / 2;
    function reset_player() {
        if(typeof hubcave_data.starting_x === 'undefined' ||
           typeof hubcave_data.starting_y === 'undefined') {
            player_sprite.position.y = player_sprite.height;
            player_sprite.position.x = blocksize + player_sprite.width;
        } else {
            player_sprite.position.y = parseInt(hubcave_data.starting_x * blocksize +
                                                player_sprite.width);
            player_sprite.position.x = parseInt(hubcave_data.starting_y * blocksize +
                                                player_sprite.height);
        }
        player_hp = 100;
        player_ammo = 500;
        player_items = {};
    }; reset_player();

    player_sprite.pivot.x = player_sprite.width;
    player_sprite.pivot.y = player_sprite.height;

    var nick = new PIXI.Text(user_name,
                             {
                                 font: 'bold 12px Arial'
                             });
    player_sprite.addChild(nick);

    enemies = [];

    scrollArea.addChild(player_sprite);

    stage.addChild(scrollArea);

    // Define our items
    // Location is 2D vector
    function Item (type, location) {
        this.type = type;
        this.sprite.location = location;
        this.sprite.pivot.x = this.sprite.width;
        this.sprite.pivot.y = this.sprite.height;
        // Add a random rotation, why not
        this.sprite.rotation = Math.random() * Math.pi * 2;
        // Inheriting classes can override this anyway
    }

    function Item__Gold(location, opts){
        Item.apply(this, 'item__gold', location);
    }
    Item__Gold.prototype.sprite = PIXI.Texture.fromImage("/static/img/items/gold.png");

    function Item__Arrow(location, opts){
        Item.apply(this, 'item__arrow', location);
    }
    Item__Arrow.prototype.sprite = projectileTexture;

    // Add ui overlay
    ui_show = true;

    ui = new PIXI.DisplayObjectContainer();
    ui.position.x = 0;
    ui.position.y = 0;
    ui.width = render_size;
    ui.height = blocksize;
    ui.interactive = true;
    ui.buttonMode = true;
    stage.addChild(ui);

    inventory = new PIXI.Graphics();
    // inventory.x = 5;
    // inventory.y = 5;
    // inventory.width = render_size - 5;
    // inventory.height = 40;

    ui.addChild(inventory);

    inventory.beginFill(0xFFFFFF, 0.3);
    inventory.drawRect(5,5, render_size - 10, 40);
    inventory.endFill();

    hitpoints_counter = new PIXI.Text("HP: " + player_hp.toString(),
                                      { fill: 'white' });
    hitpoints_counter.x = 15;
    hitpoints_counter.y = 15;

    ui.addChild(hitpoints_counter);

    ammo_counter = new PIXI.Text("Ammo: " + player_ammo.toString(),
                                      { fill: 'white' });
    ammo_counter.x = 30 + hitpoints_counter.width;
    ammo_counter.y = 15;

    ui.addChild(ammo_counter);

    ui.mousedown = function(idata) {
        console.log(idata.originalEvent.layerX, idata.originalEvent.layerY);
    };

    // var ui_panel = new PIXI.DisplayObjectContainer();
    // ui_panel.position.x = 15;
    // ui_panel.position.y = 15;
    // ui_panel.width = render_size - 15;
    // ui_panel.height = blocksize - 15;
    // ui_panel.interactive = true;
    // ui_panel.alpha = 0.5;

    // ui_panel.buttonMode = true;
    // ui.addChild(ui_panel);

    // hitpoints_counter = new PIXI.Text("HP: " + player_hp.toString(),
    //                                   { fill: 'white' });

    // ui_panel.addChild(hitpoints_counter);
    // stage.addChild(ui);

    function update_ui(){
        if (ui_show){
            // ui.removeChild(hitpoints_counter);
            hitpoints_counter.setText("HP: " + player_hp.toString());
            ammo_counter.setText("Ammo: " + player_ammo.toString());
            // ui.addChild(hitpoints_counter);
        }
    }

    update_ui();

    movespeed = blocksize / 20;
    var max_abs_velocity = movespeed;
    var player_friction_coefficient = 0.95;
    var player_acceleration = 1;
    shootspeed = blocksize / 10;
    rotatespeed = Math.PI / 50;
    edge_buffer = render_size / 3;

    scrollArea.position.x = -(player_sprite.position.x * scrollArea.scale.x);
    scrollArea.position.y = -(player_sprite.position.y * scrollArea.scale.y);

    function update_active_users() {
        var active_users_panel = $("#active_users ul");
        active_users_panel.empty();
        for (var id in users) {
            var uname = users[id].username;
            active_users_panel.append(
                '<li><a href=/profile/' + id + '>' +
                    uname + ' </a></li>');
        }
        active_users_panel.append(
            '<li><a href=/profile/' + user_id + '>' +
                user_name + ' </a></li>');
    } update_active_users();

    // Update world on state event
    socket.on('pstate', function (data) {
                  var user_sprite = null;
                  if (users[data.data.id]) {
                      user_sprite = users[data.data.id].sprite;
                      user_sprite.position.x = data.data.x;
                      user_sprite.position.y = data.data.y;
                      user_sprite.rotation = data.data.rot;
                  } else {
                      // New sprite must be drawn
                      user_sprite = new PIXI.Sprite(charTexture);
                      user_sprite.width = blocksize / 2;
                      user_sprite.height = blocksize / 2;
                      user_sprite.pivot.x = user_sprite.width;
                      user_sprite.pivot.y = user_sprite.height;
                      user_sprite.position.x = data.data.x;
                      user_sprite.position.y = data.data.y;
                      user_sprite.rotation = data.data.rot;

                      var nick = new PIXI.Text(data.data.user_name,
                                               {
                                                   font: 'bold 12px Arial'
                                               });
                      user_sprite.addChild(nick);

                      console.log("Adding new sprite for " + data.data.user_name);
                      users[data.data.id] = {
                          username: data.data.user_name,
                          sprite: user_sprite
                      };
                      scrollArea.addChild(user_sprite);
                      update_active_users();
                  }
              });

    function chat_time_format() {
        var d = new Date();
        var hr = d.getHours();
        var min = d.getMinutes();
        if (min < 10) {
            min = "0" + min;
        }
        if (hr < 12) {
            var ampm = " a.m.";
        } else {
            var ampm = " p.m.";
            hr -= 12;
        }
        return "[" + hr + ":" + min + ampm + "] ";
    }

    socket.on('joining', function (data) {
                  $("#room_chat ul").prepend(
                      '<li style="color: #00FF00;">' + chat_time_format() +
                          '<a href=/profile/' + data.data.user_id + '>' +
                          data.data.user_name + ' </a>Joined!</li>');
                  emit_player_data();
              });

    socket.on('leaving', function (data) {
                  $("#room_chat ul").prepend(
                      '<li style="color: #FF0000;">' + chat_time_format() +
                          '<a href=/profile/' + data.user + '>' +
                          data.username + ' </a>Quit</li>');
                  scrollArea.removeChild(users[data.user].sprite);
                  delete users[data.user];
                  update_active_users();
              });

    function update_scroll() {
        // Adjust the viewport if character is past buffer minimum
        if (player_sprite.x * scrollArea.scale.x + edge_buffer >
            -scrollArea.x + render_size)
        {
            // Move the viewport to the right
            scrollArea.position.x += (-scrollArea.x + render_size) -
                (player_sprite.x * scrollArea.scale.x + edge_buffer);
        } else if (player_sprite.x * scrollArea.scale.x - edge_buffer <
                   -scrollArea.x){
            // Move it left
            scrollArea.position.x += (-scrollArea.x) -
                (player_sprite.x * scrollArea.scale.x - edge_buffer);
        }
        if (player_sprite.y * scrollArea.scale.y + edge_buffer >
            -scrollArea.y + render_size) {
            // Move it down
            scrollArea.position.y += (-scrollArea.y + render_size) -
                (player_sprite.y * scrollArea.scale.y + edge_buffer);
        } else if (player_sprite.y * scrollArea.scale.y - edge_buffer <
                   -scrollArea.y){
            // Move it up
            scrollArea.position.y += (-scrollArea.y) -
                (player_sprite.y * scrollArea.scale.y - edge_buffer);
        }
    }

    emit_player_data();

    scrollArea.mousemove = function(idata) {
        player_sprite.mouse_x = idata.originalEvent.layerX
        player_sprite.mouse_y = idata.originalEvent.layerY
    };

    function update_player_sprite_rotation(sprite) {
        var dist_x = player_sprite.mouse_x -
            (sprite.getBounds().x + sprite.getBounds().width / 2);
        var dist_y = player_sprite.mouse_y -
            (sprite.getBounds().y + sprite.getBounds().height / 2);

        sprite.rotation = Math.atan2(-dist_x, dist_y);
    };

    function shootProjectile(user, position, rotation) {
        var p = new PIXI.Sprite(projectileTexture);
        p.position.x = position.x;
        p.position.y = position.y;
        p.rotation = rotation;
        p.scale.x = 12 / blocksize;
        p.scale.y = 12 / blocksize;
        p.lifedist = blocksize * 5;
        p.distanceTraveled = 0;
        if (!projectiles[user]) { projectiles[user] = []; };
        projectiles[user].push(p);
        scrollArea.addChild(p);
    };

    socket.on('msg', function (data) {
                  // Received message from someone
                  $("#room_chat ul").prepend(
                      '<li>[' + data.when + '] ' +
                          '<a href=/profile/' + data.user_id + '>' +
                          data.user_name + ' </a><span> ' +
                          data.text + ' </span>' +
                          '</li>');
                  console.log(data.text);
              });
<commit_msg>javascript is funny, but and<NAME> is funnier<commit_after>// HUBCAVE
// window.onbeforeunload = function (e) {
//   return "Quit game?";
// };

// Disable the chat window initially
$('#chat_input').width($('.chat-panel').width() - 50);

socket = io.connect("/game", {
                        transports: ['websocket',
                                     'flashsocket',
                                     'polling']
                    });
socket.on('connect', function () {
              socket.emit('join', [game_id, user_id]);
          });

socket.on('loading', function (data) {
              hubcave_data = data.map;
              for (var i = data.messages.length - 1; i >= 0; --i){
                  var msg = data.messages[i];
                  $("#room_chat ul").prepend(
                      '<li>[' + msg.when + '] ' +
                          '<a href=/profile/' + msg.user_id + '>' +
                          msg.user_name + ' </a><span> ' +
                          msg.text + ' </span>' +
                          '</li>');
              }
              run_game();
          });

// Let us kick off the show

function run_game() {
    // create an new instance of a pixi stage
    var stage = new PIXI.Stage(0x000000);

    var render_size = Math.min($('#game_panel').width() - 50,
                               $('#game_panel').width());

    var renderer = PIXI.autoDetectRenderer(render_size,
                                           render_size);

    // Define textures
    var wallTexture = PIXI.Texture.fromImage("/static/img/wall.png");
    var floorTexture = PIXI.Texture.fromImage("/static/img/floortile.png");
    var projectileTexture = PIXI.Texture.fromImage("/static/img/arrow.png");
    var charTexture = PIXI.Texture.fromImage("/static/img/ghlogo.png");
    var vignetteTexture = PIXI.Texture.fromImage("/static/img/vignette.png");

    for (i=0; i < hubcave_data.blockdata.length; ++i) {
        var block = hubcave_data.blockdata[i];
    }

    // PIXI.Texture.addTextureToCache(wallTexture, 'walltex');
    var blocksize = 50;

    renderer.view.className = "rendererView";
    $('.canvas-panel').append(renderer.view);

    //
    // Build out the map sprites according to blockdata
    //

    scrollArea = new PIXI.DisplayObjectContainer();
    scrollArea.interactive = true;
    scrollArea.buttonMode = true;
    scrollArea.defaultCursor = "crosshair";

    var max_width = 0,
    max_height = 0;
    var terrain = {};
    projectiles = {};

    for (i=0; i < hubcave_data.blockdata.length; ++i) {
        var block = hubcave_data.blockdata[i];
        terrain[block.x] = terrain[block.x] ? terrain[block.x] : {};
        terrain[block.x][block.y] = block.blktype;
        if (!block.blktype) {
            wall_sprite = new PIXI.Sprite(wallTexture);
            wall_sprite.width = blocksize;
            wall_sprite.height = blocksize;
            wall_sprite.position.y = block.x * blocksize;
            wall_sprite.position.x = block.y * blocksize;
            scrollArea.addChild(wall_sprite);
        } else {
            floor_sprite = new PIXI.Sprite(floorTexture);
            floor_sprite.width = blocksize;
            floor_sprite.height = blocksize;
            floor_sprite.position.y = block.x * blocksize;
            floor_sprite.position.x = block.y * blocksize;
            scrollArea.addChild(floor_sprite);
        }
        max_width = Math.max(max_width, block.x);
        max_height = Math.max(max_height, block.y);
    }

    scrollArea.scale.x = render_size / blocksize / 5;
    scrollArea.scale.y = scrollArea.scale.x;

    users = {};

    // Bow is default item at '1'
    // Items/keys -> map 2-0 keys to select
    // HP/ammo

    // DECLARE PLAYER OBJECT

    player_sprite = new PIXI.Sprite(charTexture);
    player_sprite.velocity_x = 0
    player_sprite.velocity_y = 0
    player_sprite.width = blocksize / 2;
    player_sprite.height = blocksize / 2;
    function reset_player() {
        if(typeof hubcave_data.starting_x === 'undefined' ||
           typeof hubcave_data.starting_y === 'undefined') {
            player_sprite.position.y = player_sprite.height;
            player_sprite.position.x = blocksize + player_sprite.width;
        } else {
            player_sprite.position.y = parseInt(hubcave_data.starting_x * blocksize +
                                                player_sprite.width);
            player_sprite.position.x = parseInt(hubcave_data.starting_y * blocksize +
                                                player_sprite.height);
        }
        player_hp = 100;
        player_ammo = 500;
        player_items = {};
    }; reset_player();

    player_sprite.pivot.x = player_sprite.width;
    player_sprite.pivot.y = player_sprite.height;

    var nick = new PIXI.Text(user_name,
                             {
                                 font: 'bold 12px Arial'
                             });
    player_sprite.addChild(nick);

    enemies = [];

    scrollArea.addChild(player_sprite);

    stage.addChild(scrollArea);

    // Define our items
    // Location is 2D vector
    function Item (type, location) {
        this.type = type;
        this.sprite.location = location;
        this.sprite.pivot.x = this.sprite.width;
        this.sprite.pivot.y = this.sprite.height;
        // Add a random rotation, why not
        this.sprite.rotation = Math.random() * Math.pi * 2;
        // Inheriting classes can override this anyway
    }

    function Item__Gold(location, opts){
        Item.apply(this, 'item__gold', location);
    }
    Item__Gold.prototype.sprite = PIXI.Texture.fromImage("/static/img/items/gold.png");

    function Item__Arrow(location, opts){
        Item.apply(this, 'item__arrow', location);
    }
    Item__Arrow.prototype.sprite = projectileTexture;

    // Add ui overlay
    ui_show = true;

    ui = new PIXI.DisplayObjectContainer();
    ui.position.x = 0;
    ui.position.y = 0;
    ui.width = render_size;
    ui.height = blocksize;
    ui.interactive = true;
    ui.buttonMode = true;
    stage.addChild(ui);

    inventory = new PIXI.Graphics();
    // inventory.x = 5;
    // inventory.y = 5;
    // inventory.width = render_size - 5;
    // inventory.height = 40;

    ui.addChild(inventory);

    inventory.beginFill(0xFFFFFF, 0.3);
    inventory.drawRect(5,5, render_size - 10, 40);
    inventory.endFill();

    hitpoints_counter = new PIXI.Text("HP: " + player_hp.toString(),
                                      { fill: 'white' });
    hitpoints_counter.x = 15;
    hitpoints_counter.y = 15;

    ui.addChild(hitpoints_counter);

    ammo_counter = new PIXI.Text("Ammo: " + player_ammo.toString(),
                                      { fill: 'white' });
    ammo_counter.x = 30 + hitpoints_counter.width;
    ammo_counter.y = 15;

    ui.addChild(ammo_counter);

    ui.mousedown = function(idata) {
        console.log(idata.originalEvent.layerX, idata.originalEvent.layerY);
    };

    // var ui_panel = new PIXI.DisplayObjectContainer();
    // ui_panel.position.x = 15;
    // ui_panel.position.y = 15;
    // ui_panel.width = render_size - 15;
    // ui_panel.height = blocksize - 15;
    // ui_panel.interactive = true;
    // ui_panel.alpha = 0.5;

    // ui_panel.buttonMode = true;
    // ui.addChild(ui_panel);

    // hitpoints_counter = new PIXI.Text("HP: " + player_hp.toString(),
    //                                   { fill: 'white' });

    // ui_panel.addChild(hitpoints_counter);
    // stage.addChild(ui);

    function update_ui(){
        if (ui_show){
            // ui.removeChild(hitpoints_counter);
            hitpoints_counter.setText("HP: " + player_hp.toString());
            ammo_counter.setText("Ammo: " + player_ammo.toString());
            // ui.addChild(hitpoints_counter);
        }
    }

    update_ui();

    movespeed = blocksize / 20;
    var max_abs_velocity = movespeed;
    var player_friction_coefficient = 0.95;
    var player_acceleration = 1;
    shootspeed = blocksize / 10;
    rotatespeed = Math.PI / 50;
    edge_buffer = render_size / 3;

    scrollArea.position.x = -(player_sprite.position.x * scrollArea.scale.x);
    scrollArea.position.y = -(player_sprite.position.y * scrollArea.scale.y);

    function update_active_users() {
        var active_users_panel = $("#active_users ul");
        active_users_panel.empty();
        for (var id in users) {
            var uname = users[id].username;
            active_users_panel.append(
                '<li><a href=/profile/' + id + '>' +
                    uname + ' </a></li>');
        }
        active_users_panel.append(
            '<li><a href=/profile/' + user_id + '>' +
                user_name + ' </a></li>');
    } update_active_users();

    // Update world on state event
    socket.on('pstate', function (data) {
                  var user_sprite = null;
                  if (users[data.data.id]) {
                      user_sprite = users[data.data.id].sprite;
                      user_sprite.position.x = data.data.x;
                      user_sprite.position.y = data.data.y;
                      user_sprite.rotation = data.data.rot;
                  } else {
                      // New sprite must be drawn
                      user_sprite = new PIXI.Sprite(charTexture);
                      user_sprite.width = blocksize / 2;
                      user_sprite.height = blocksize / 2;
                      user_sprite.pivot.x = user_sprite.width;
                      user_sprite.pivot.y = user_sprite.height;
                      user_sprite.position.x = data.data.x;
                      user_sprite.position.y = data.data.y;
                      user_sprite.rotation = data.data.rot;

                      var nick = new PIXI.Text(data.data.user_name,
                                               {
                                                   font: 'bold 12px Arial'
                                               });
                      user_sprite.addChild(nick);

                      console.log("Adding new sprite for " + data.data.user_name);
                      users[data.data.id] = {
                          username: data.data.user_name,
                          sprite: user_sprite
                      };
                      scrollArea.addChild(user_sprite);
                      update_active_users();
                  }
              });

    function chat_time_format() {
        var d = new Date();
        var hr = d.getHours();
        var min = d.getMinutes();
        if (min < 10) {
            min = "0" + min;
        }
        if (hr < 12) {
            var ampm = " a.m.";
        } else {
            var ampm = " p.m.";
            hr -= 12;
        }
        return "[" + hr + ":" + min + ampm + "] ";
    }

    socket.on('joining', function (data) {
                  $("#room_chat ul").prepend(
                      '<li style="color: #00FF00;">' + chat_time_format() +
                          '<a href=/profile/' + data.data.user_id + '>' +
                          data.data.user_name + ' </a>Joined!</li>');
                  emit_player_data();
              });

    socket.on('leaving', function (data) {
                  $("#room_chat ul").prepend(
                      '<li style="color: #FF0000;">' + chat_time_format() +
                          '<a href=/profile/' + data.user + '>' +
                          data.username + ' </a>Quit</li>');
                  scrollArea.removeChild(users[data.user].sprite);
                  delete users[data.user];
                  update_active_users();
              });

    function update_scroll() {
        // Adjust the viewport if character is past buffer minimum
        if (player_sprite.x * scrollArea.scale.x + edge_buffer >
            -scrollArea.x + render_size)
        {
            // Move the viewport to the right
            scrollArea.position.x += (-scrollArea.x + render_size) -
                (player_sprite.x * scrollArea.scale.x + edge_buffer);
        } else if (player_sprite.x * scrollArea.scale.x - edge_buffer <
                   -scrollArea.x){
            // Move it left
            scrollArea.position.x += (-scrollArea.x) -
                (player_sprite.x * scrollArea.scale.x - edge_buffer);
        }
        if (player_sprite.y * scrollArea.scale.y + edge_buffer >
            -scrollArea.y + render_size) {
            // Move it down
            scrollArea.position.y += (-scrollArea.y + render_size) -
                (player_sprite.y * scrollArea.scale.y + edge_buffer);
        } else if (player_sprite.y * scrollArea.scale.y - edge_buffer <
                   -scrollArea.y){
            // Move it up
            scrollArea.position.y += (-scrollArea.y) -
                (player_sprite.y * scrollArea.scale.y - edge_buffer);
        }
    }

    emit_player_data();

    scrollArea.mousemove = function(idata) {
        player_sprite.mouse_x = idata.originalEvent.layerX
        player_sprite.mouse_y = idata.originalEvent.layerY
    };

    function update_player_sprite_rotation(sprite) {
        var dist_x = srite.mouse_x -
            (sprite.getBounds().x + sprite.getBounds().width / 2);
        var dist_y = sprite.mouse_y -
            (sprite.getBounds().y + sprite.getBounds().height / 2);

        sprite.rotation = Math.atan2(-dist_x, dist_y);
    };

    function shootProjectile(user, position, rotation) {
        var p = new PIXI.Sprite(projectileTexture);
        p.position.x = position.x;
        p.position.y = position.y;
        p.rotation = rotation;
        p.scale.x = 12 / blocksize;
        p.scale.y = 12 / blocksize;
        p.lifedist = blocksize * 5;
        p.distanceTraveled = 0;
        if (!projectiles[user]) { projectiles[user] = []; };
        projectiles[user].push(p);
        scrollArea.addChild(p);
    };

    socket.on('msg', function (data) {
                  // Received message from someone
                  $("#room_chat ul").prepend(
                      '<li>[' + data.when + '] ' +
                          '<a href=/profile/' + data.user_id + '>' +
                          data.user_name + ' </a><span> ' +
                          data.text + ' </span>' +
                          '</li>');
                  console.log(data.text);
              });

{'fraction_non_alphanumeric': 0.12716217632875562, 'fraction_numerical': 0.007687738057797812, 'mean_word_length': 1.6147099132023754, 'pattern_counts': {'":': 2, '<': 72, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 38, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6790337', 'n_tokens_mistral': 8844, 'n_tokens_neox': 8438, 'n_words': 1538}