diff --git a/app/Game/Channel/Channel.js b/app/Game/Channel/Channel.js index 39b4113..c4d6287 100755 --- a/app/Game/Channel/Channel.js +++ b/app/Game/Channel/Channel.js @@ -9,6 +9,8 @@ function (GameController, Nc, User, ProtocolHelper, Options, Settings) { + "use strict"; + function Channel (pipeToServer, options) { var self = this; @@ -17,6 +19,7 @@ this.users = {}; this.pipeToServer = pipeToServer; this.levelListIndex = -1; + this.gameController = null; this.options = options = Options.merge(options, { levelUids: Settings.CHANNEL_DEFAULT_LEVELS @@ -34,7 +37,7 @@ this.beginRound(); - console.checkpoint('channel ' + this.name + ' created'); + console.checkpoint("channel " + this.name + " created"); setTimeout(function() { if(Object.keys(self.users).length < 1) { @@ -53,7 +56,7 @@ if(this.gameController) { this.gameController.destroy(); - delete this.gameController; + this.gameController = null; } var gameControllerOptions = { @@ -108,14 +111,14 @@ this.sendJoinSuccess(options); this.users[options.id].sendControlCommand("beginRound", clientGameControllerOptions); } - } + }; Channel.prototype.sendJoinSuccess = function(options) { var user = new User(options.id, options); var joinedUsers = []; for(var userId in this.users) { - joinedUsers.push(this.users[userId].options) + joinedUsers.push(this.users[userId].options); } var levelUid = null; @@ -125,13 +128,13 @@ this.users[user.id] = user; - var options = { + options = { user: user.options, joinedUsers: joinedUsers, levelUid: levelUid }; - //Nc.trigger('user/' + user.id + "/joinSuccess", options); + //Nc.trigger("user/" + user.id + "/joinSuccess", options); user.sendControlCommand("joinSuccess", options); Nc.trigger(Nc.ns.channel.events.user.joined, user); @@ -140,7 +143,6 @@ Channel.prototype.onReleaseUser = function (userId) { var self = this; - var user = this.users[userId]; Nc.trigger(Nc.ns.channel.events.user.left, userId); delete this.users[userId]; @@ -158,7 +160,7 @@ } }, Settings.CHANNEL_DESTRUCTION_TIME * 1000); } - } + }; Channel.prototype.destroy = function() { console.checkpoint("channel (" + this.name + ") destroyed"); @@ -172,7 +174,7 @@ for(var id in this.users) { this.users[id].sendControlCommand(command, options); } - } + }; Channel.prototype.broadcastControlCommandExcept = function (command, options, exceptUser) { for(var id in this.users) { @@ -180,13 +182,13 @@ this.users[id].sendControlCommand(command, options); } } - } + }; Channel.prototype.broadcastGameCommand = function (command, options) { for(var id in this.users) { this.users[id].sendGameCommand(command, options); } - } + }; Channel.prototype.broadcastGameCommandExcept = function (command, options, exceptUser) { for(var id in this.users) { @@ -194,7 +196,7 @@ this.users[id].sendGameCommand(command, options); } } - } + }; return Channel; diff --git a/app/Game/Channel/Control/PlayerController.js b/app/Game/Channel/Control/PlayerController.js index c1f657f..cf7a306 100755 --- a/app/Game/Channel/Control/PlayerController.js +++ b/app/Game/Channel/Control/PlayerController.js @@ -6,6 +6,8 @@ define([ ], function(Parent, Nc, Parser, Settings) { + + "use strict"; function PlayerController(player) { @@ -33,6 +35,9 @@ function(Parent, Nc, Parser, Settings) { }; PlayerController.prototype.handActionRequest = function(options) { + options.x = parseFloat(options.x) || 0; + options.y = parseFloat(options.y) || 0; + options.av = parseFloat(options.av) || 0; if (options) this.player.handActionRequest(options); }; @@ -42,22 +47,22 @@ function(Parent, Nc, Parser, Settings) { PlayerController.prototype.mePositionStateUpdate = function(update) { - if(!this.player.doll) { - console.warn('me state update, even though doll does not exist'); - return; + if(!this.player.isSpawned()) { + // if someone still falls but is dead on the server already + return; } var difference = { x: Math.abs(update.p.x - this.player.doll.body.GetPosition().x), y: Math.abs(update.p.y - this.player.doll.body.GetPosition().y) - } + }; - if(difference.x < Settings.PUNKBUSTER_DIFFERENCE_METERS - && difference.y < Settings.PUNKBUSTER_DIFFERENCE_METERS) { + if(true || difference.x < Settings.PUNKBUSTER_DIFFERENCE_METERS && + difference.y < Settings.PUNKBUSTER_DIFFERENCE_METERS) { this.player.doll.updatePositionState(update); } else { // HARD UPDATE FOR SELF - console.log(this.player.user.options.nickname + ' is cheating.') + console.log(this.player.user.options.nickname + " is cheating."); var body = this.player.doll.body; @@ -66,7 +71,7 @@ function(Parent, Nc, Parser, Settings) { lv: body.GetLinearVelocity() }; - Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + this.player.id, 'positionStateReset', options); + Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + this.player.id, "positionStateReset", options); } }; diff --git a/app/Game/Channel/GameController.js b/app/Game/Channel/GameController.js index 66a6b74..d990025 100755 --- a/app/Game/Channel/GameController.js +++ b/app/Game/Channel/GameController.js @@ -107,11 +107,11 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N var update = this.getWorldUpdateObject(false); if(Object.getOwnPropertyNames(update).length > 0) { - Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, 'worldUpdate', update); + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "worldUpdate", update); } this.worldUpdateTimeout = setTimeout(this.updateWorld.bind(this), Settings.NETWORK_UPDATE_INTERVAL); - } + }; GameController.prototype.getWorldUpdateObject = function(getSleeping) { getSleeping = getSleeping || false; @@ -149,7 +149,7 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N var spawnedPlayers = []; for(var id in this.players) { var player = this.players[id]; - if(player.isSpawned) { + if(player.isSpawned()) { var options = { id: id, @@ -169,7 +169,7 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N }; GameController.prototype.getRuntimeItems = function() { - var objects = [] + var objects = []; for (var i = 0; i < this.gameObjects.animated.length; i++) { if(this.gameObjects.animated[i] instanceof RagDoll) { @@ -182,7 +182,7 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N options: object.options }); } - }; + } return objects; }; @@ -195,7 +195,7 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N worldUpdate: this.getWorldUpdateObject(true), runtimeItems: this.getRuntimeItems(), userId: userId - } + }; Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + userId, "clientReadyResponse", options); diff --git a/app/Game/Channel/GameObjects/Doll.js b/app/Game/Channel/GameObjects/Doll.js index 26461f6..390ab9c 100755 --- a/app/Game/Channel/GameObjects/Doll.js +++ b/app/Game/Channel/GameObjects/Doll.js @@ -2,10 +2,11 @@ define([ "Game/Core/GameObjects/Doll", "Game/Channel/GameObjects/Item", "Lib/Vendor/Box2D", - "Lib/Utilities/NotificationCenter" + "Lib/Utilities/NotificationCenter", + "Lib/Utilities/Assert" ], -function (Parent, Item, Box2D, Nc) { +function (Parent, Item, Box2D, Nc, Assert) { "use strict"; @@ -15,7 +16,7 @@ function (Parent, Item, Box2D, Nc) { Doll.prototype = Object.create(Parent.prototype); - Doll.prototype.findCloseItem = function(x, y) { + Doll.prototype.findCloseItem = function(x) { var self = this; @@ -33,7 +34,7 @@ function (Parent, Item, Box2D, Nc) { } else { return findItem(this.reachableItems.right); } - } + }; Doll.prototype.onImpact = function(isColliding, fixture) { var self = this; @@ -52,7 +53,7 @@ function (Parent, Item, Box2D, Nc) { var b2Math = Box2D.Common.Math.b2Math; - var absItemVelocity = b2Math.AbsV(itemVelocity) + var absItemVelocity = b2Math.AbsV(itemVelocity); var max = 1; if(absItemVelocity.x > max || absItemVelocity.y > max) { @@ -71,9 +72,9 @@ function (Parent, Item, Box2D, Nc) { var callback = function() { self.player.addDamage(damage, player, item); - } + }; - Nc.trigger(Nc.ns.channel.engine.worldQueue.add, callback) + Nc.trigger(Nc.ns.channel.engine.worldQueue.add, callback); } } @@ -81,10 +82,12 @@ function (Parent, Item, Box2D, Nc) { } } } - } + }; Doll.prototype.updatePositionState = function(update) { if(!this.isAnotherPlayerNearby()) { + Assert.number(update.p.x, update.p.y); + Assert.number(update.lv.x, update.lv.y); this.body.SetAwake(true); this.body.SetPosition(update.p); this.body.SetLinearVelocity(update.lv); diff --git a/app/Game/Channel/GameObjects/Item.js b/app/Game/Channel/GameObjects/Item.js index 0102d49..ce30779 100755 --- a/app/Game/Channel/GameObjects/Item.js +++ b/app/Game/Channel/GameObjects/Item.js @@ -21,14 +21,14 @@ function (Parent) { this.lastMoved = { player: player, timestamp: new Date() - } + }; } else { this.lastMoved = null; } }; - Item.prototype.isGrabbingAllowed = function(player) { - return this.heldByPlayers.length == 0; + Item.prototype.isGrabbingAllowed = function(player) { // jshint unused:false + return this.heldByPlayers.length === 0; }; Item.prototype.beingGrabbed = function(player) { @@ -40,7 +40,7 @@ function (Parent) { } }; - Item.prototype.isReleasingAllowed = function(player) { + Item.prototype.isReleasingAllowed = function(player) { // jshint unused:false return true; }; @@ -81,8 +81,7 @@ function (Parent) { } } } - } - + }; return Item; diff --git a/app/Game/Channel/PipeToServer.js b/app/Game/Channel/PipeToServer.js index 43044f1..760a08b 100755 --- a/app/Game/Channel/PipeToServer.js +++ b/app/Game/Channel/PipeToServer.js @@ -1,46 +1,87 @@ define([ "Lib/Utilities/NotificationCenter", - "Game/Channel/Channel" + "Game/Channel/Channel", + "Game/Config/Settings", + "fs" ], -function (Nc, Channel) { +function (Nc, Channel, Settings, fs) { "use strict"; function PipeToServer (process) { - - var self = this; - this.channel = null; this.process = process; + this.recordingFileName = null; Nc.on(Nc.ns.channel.to.server.controlCommand.send, this.send, this); - process.on('message', function (message, handle) { + process.on("message", this.onProcessMessage.bind(this)); + } - if(message.data.hasOwnProperty('CREATE')) { - self.channel = new Channel(self, message.data.options); - } else if (message.data.hasOwnProperty('KILL')) { - self.channel.destroy(); - } else { - self.onMessage(message); + PipeToServer.prototype.onProcessMessage = function (message, handle) { // jshint unused:false + + if(message.data.hasOwnProperty("CREATE")) { + this.channel = new Channel(this, message.data.options); + + message.data.options.playingFileName = Settings.CHANNEL_PLAY_RECORDING; + + if(message.data.options.playingFileName) { + var self = this; + setTimeout(function() { + console.log(message.data.options.playingFileName); + self.play(message.data.options.playingFileName); + }, 2000); // giving channel time to set everything up + } + + if(Settings.CHANNEL_RECORD_SESSION) { + + this.recordingFileName = Settings.CHANNEL_RECORDING_PATH + + this.channel.name + + "-" + + (new Date()).toISOString() + + "-" + + message.data.options.levelUids.join("_") + + ".log"; + + if(!fs.existsSync(Settings.CHANNEL_RECORDING_PATH)) { + fs.mkdirSync(Settings.CHANNEL_RECORDING_PATH); + } + + setInterval(this.recordWorldUpdate.bind(this), 1000); + console.checkpoint("Started recording to: " + this.recordingFileName); } - }); - } + } else if (message.data.hasOwnProperty("KILL")) { + this.channel.destroy(); + } else { + this.onMessage(message); + + if(Settings.CHANNEL_RECORD_SESSION && this.channel && this.channel.name) { + var m = JSON.stringify(message); + var timestamp = Date.now(); + var line = "m" + timestamp + m + "\n"; + + fs.appendFile(this.recordingFileName, line, function (err) { + if (err) throw err; + }); + } + } + + }; PipeToServer.prototype.send = function (recipient, data) { var message = { recipient: recipient, data: data - } + }; this.process.send(message); }; PipeToServer.prototype.onMessage = function (message) { switch(message.recipient) { - case 'channel': + case "channel": Nc.trigger(Nc.ns.channel.events.controlCommand.channel, message); break; default: @@ -48,10 +89,59 @@ function (Nc, Channel) { break; } - } + }; + + PipeToServer.prototype.play = function(playingFileName) { + var self = this; + var data = fs.readFileSync(Settings.CHANNEL_RECORDING_PATH + playingFileName); + var lines = data.toString().split("\n"); + var start = 0; + for (var i = 0; i < lines.length; i++) { + // bind message variable + (function() { + var line = lines[i]; + if(line.length > 0) { + var type = line.substring(0, 1); + var time = parseInt(line.substring(1, Date.now().toString().length + 1), 10); + if(i === 0) { + start = time; + } + time -= start; + + var jsonString = line.substring(Date.now().toString().length + 1); + var message = JSON.parse(jsonString); + + setTimeout(function() { + console.log(line); + + if(type == "m") { + self.onProcessMessage(message, null); + } else if(type == "w") { + if(self.channel.gameController) { + self.channel.gameController.onWorldUpdate(message); + } + } + }, time); + } + })(); + } + }; + + PipeToServer.prototype.recordWorldUpdate = function() { + if(this.channel.gameController) { + var update = this.channel.gameController.getWorldUpdateObject(true); + var worldUpdate = JSON.stringify(update); + var timestamp = Date.now(); + var line = "w" + timestamp + worldUpdate + "\n"; + + fs.appendFile(this.recordingFileName, line, function (err) { + if (err) throw err; + }); + } + }; PipeToServer.prototype.destroy = function() { - this.send('coordinator', {destroy:this.channel.name}); + this.send("coordinator", {destroy:this.channel.name}); this.process.exit(0); }; diff --git a/app/Game/Channel/Player.js b/app/Game/Channel/Player.js index d7d09cf..06c8b56 100755 --- a/app/Game/Channel/Player.js +++ b/app/Game/Channel/Player.js @@ -22,13 +22,13 @@ function (Parent, Nc) { if (isHolding) { item = this.holdingItem; } else { - item = this.doll.findCloseItem(options.x, options.y); + item = this.doll.findCloseItem(options.x); } if(item) { this.handAction(options, isHolding, item); } - } + }; Player.prototype.handAction = function(options, isHolding, item) { @@ -110,8 +110,7 @@ function (Parent, Nc) { stats: this.stats }); }; - - + return Player; diff --git a/app/Game/Client/Control/Inputs/KeyboardAndMouse.js b/app/Game/Client/Control/Inputs/KeyboardAndMouse.js index 515f288..998e94f 100644 --- a/app/Game/Client/Control/Inputs/KeyboardAndMouse.js +++ b/app/Game/Client/Control/Inputs/KeyboardAndMouse.js @@ -7,6 +7,8 @@ define([ ], function (Parent, KeyboardInput, DomController, Settings, Swiper) { + + "use strict"; function KeyboardAndMouse(playerController) { Parent.call(this); @@ -42,7 +44,7 @@ function (Parent, KeyboardInput, DomController, Settings, Swiper) { minus: 189, minusfx: 173, zero: 48 - } + }; this.playerController = playerController; this.keyboardInit(); @@ -87,7 +89,7 @@ function (Parent, KeyboardInput, DomController, Settings, Swiper) { this.lastLookDirection = -1; this.onXyChange(this.lastLookDirection * Settings.VIEWPORT_LOOK_AHEAD, 0); } - this.playerController.moveLeft() + this.playerController.moveLeft(); }; KeyboardAndMouse.prototype.moveRight = function() { @@ -129,7 +131,8 @@ function (Parent, KeyboardInput, DomController, Settings, Swiper) { if(!self.playerController.player.isHoldingSomething()) { var options = { x: self.x, - y: self.y + y: self.y, + av: 0 }; self.playerController.handActionRequest(options); } else { diff --git a/app/Game/Client/GameController.js b/app/Game/Client/GameController.js index c239aa0..741cec6 100755 --- a/app/Game/Client/GameController.js +++ b/app/Game/Client/GameController.js @@ -13,10 +13,11 @@ define([ "Lib/Utilities/Protocol/Helper", "Game/Client/Me", "Game/Client/AudioPlayer", - "Game/Client/PointerLockManager" + "Game/Client/PointerLockManager", + "Lib/Utilities/Assert" ], -function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, requestAnimFrame, Settings, GameObject, Doll, DomController, ProtocolHelper, Me, AudioPlayer, PointerLockManager) { +function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, requestAnimFrame, Settings, GameObject, Doll, DomController, ProtocolHelper, Me, AudioPlayer, PointerLockManager, Assert) { "use strict"; @@ -39,7 +40,7 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque GameController.prototype.getMe = function () { return this.me; - } + }; GameController.prototype.update = function () { @@ -59,7 +60,7 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque this.view.render(); DomController.fpsStep(); - } + }; GameController.prototype.mePositionStateUpdate = function() { if(this.me.isPositionStateUpdateNeeded()) { @@ -68,27 +69,28 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque }; GameController.prototype.onClientReadyResponse = function(options) { - + var i; + if (options.worldUpdate) { this.onWorldUpdate(options.worldUpdate); } if (options.runtimeItems) { - for (var i = 0; i < options.runtimeItems.length; i++) { + for (i = 0; i < options.runtimeItems.length; i++) { var itemDef = options.runtimeItems[i]; var alreadyExists = false; - for (var i = 0; i < this.gameObjects.animated.length; i++) { - if(this.gameObjects.animated[i].uid == itemDef.uid) { + for (var j = 0; j < this.gameObjects.animated.length; j++) { + if(this.gameObjects.animated[j].uid == itemDef.uid) { alreadyExists = true; break; } - }; + } if(!alreadyExists) { - var item = this.level.createItem(itemDef.uid, itemDef.options); + this.level.createItem(itemDef.uid, itemDef.options); } - }; + } } this.setMe(); @@ -96,7 +98,7 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque this.clientIsReady = true; // needs to stay before onSpawnPlayer if (options.spawnedPlayers) { - for(var i = 0; i < options.spawnedPlayers.length; i++) { + for(i = 0; i < options.spawnedPlayers.length; i++) { this.onSpawnPlayer(options.spawnedPlayers[i]); } } @@ -105,38 +107,16 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque this.audioPlayer.play(); }; - GameController.prototype.onWorldUpdate = function (updateData) { - - var body = this.physicsEngine.world.GetBodyList(); - do { - var userData = body.GetUserData(); - if (userData instanceof GameObject) { - var gameObject = userData; - if(updateData[gameObject.uid]) { - var update = updateData[gameObject.uid]; - - if (gameObject instanceof Doll) { - if(gameObject === this.me.doll) { - this.me.setLastServerPositionState(update); - if(!this.me.acceptPositionStateUpdateFromServer()) { - continue; // this is to ignore own doll updates from world update - } - } - gameObject.setActionState(update.as); - gameObject.lookAt(update.laxy.x, update.laxy.y); - } - - body.SetAwake(true); - body.SetPosition(update.p); - body.SetAngle(update.a); - body.SetLinearVelocity(update.lv); - body.SetAngularVelocity(update.av); - } + GameController.prototype.onWorldUpdateGameObject = function(body, gameObject, update) { + if(gameObject === this.me.doll) { + this.me.setLastServerPositionState(update); + if(!this.me.acceptPositionStateUpdateFromServer()) { + return; // this is to ignore own doll updates from world update } - - } while (body = body.GetNext()); + } - } + Parent.prototype.onWorldUpdateGameObject.call(this, body, gameObject, update); + }; GameController.prototype.createMe = function(user) { this.me = new Me(user.id, this.physicsEngine, user); @@ -146,7 +126,7 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque GameController.prototype.setMe = function() { this.me.setPlayerController(new PlayerController(this.me)); this.view.setMe(this.me); - } + }; GameController.prototype.onGameCommand = function(message) { ProtocolHelper.applyCommand(message, this); @@ -172,7 +152,7 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque playerId: playerId }); } - } + }; GameController.prototype.onHandActionResponse = function(options) { var player = this.players[options.playerId]; @@ -184,7 +164,7 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque item = currentItem; break; } - }; + } if(item) { if(options.action == "throw") { @@ -193,7 +173,7 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque player.grab(item); } } else { - console.warn("Item for joint can not be found locally. " + options.itemUid) + console.warn("Item for joint can not be found locally. " + options.itemUid); } }; @@ -243,18 +223,18 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque GameController.prototype.loadLevel = function (path) { Parent.prototype.loadLevel.call(this, path); - } + }; GameController.prototype.onLevelLoaded = function () { PointerLockManager.update(null, {start:true}); - } + }; GameController.prototype.toggleGameStats = function(show) { var playersArray = []; for (var key in this.players) { playersArray.push(this.players[key]); - }; + } var sortedPlayers = playersArray.sort(function(a,b) { if(a.stats.score > b.stats.score) return -1; diff --git a/app/Game/Client/Me.js b/app/Game/Client/Me.js index 31436a9..047befd 100644 --- a/app/Game/Client/Me.js +++ b/app/Game/Client/Me.js @@ -1,10 +1,11 @@ define([ "Game/Client/Player", "Game/Config/Settings", - "Lib/Utilities/NotificationCenter" + "Lib/Utilities/NotificationCenter", + "Lib/Utilities/Assert" ], -function (Parent, Settings, Nc) { +function (Parent, Settings, Nc, Assert) { "use strict"; @@ -15,7 +16,7 @@ function (Parent, Settings, Nc) { this.lookAtXY = { x: Settings.VIEWPORT_LOOK_AHEAD, y: 0 - } + }; this.lastServerPositionState = { p: { @@ -34,7 +35,7 @@ function (Parent, Settings, Nc) { this.lookAtXY = { x: x, y: y - } + }; Parent.prototype.lookAt.call(this, x, y); }; @@ -63,10 +64,10 @@ function (Parent, Settings, Nc) { var difference = { x: Math.abs(this.lastServerPositionState.p.x - this.doll.body.GetPosition().x), y: Math.abs(this.lastServerPositionState.p.y - this.doll.body.GetPosition().y) - } + }; - if(difference.x > Settings.ME_STATE_MAX_DIFFERENCE_METERS - || difference.y > Settings.ME_STATE_MAX_DIFFERENCE_METERS) { + if(difference.x > Settings.ME_STATE_MAX_DIFFERENCE_METERS || + difference.y > Settings.ME_STATE_MAX_DIFFERENCE_METERS) { return true; } return false; @@ -76,7 +77,7 @@ function (Parent, Settings, Nc) { return { p: this.doll.body.GetPosition().Copy(), lv: this.doll.body.GetLinearVelocity().Copy() - } + }; }; Me.prototype.acceptPositionStateUpdateFromServer = function() { @@ -85,11 +86,13 @@ function (Parent, Settings, Nc) { }; Me.prototype.resetPositionState = function(options) { + Assert.number(options.p.x, options.p.y); + Assert.number(options.lv.x, options.lv.y); this.doll.body.SetPosition(options.p); this.doll.body.SetLinearVelocity(options.lv); }; - Me.prototype.createAndAddArrow = function(visible) { + Me.prototype.createAndAddArrow = function() { var self = this; var position = this.getPosition(); @@ -101,7 +104,7 @@ function (Parent, Settings, Nc) { var callback = function(arrowMesh) { self.arrowMesh = arrowMesh; - } + }; Nc.trigger(Nc.ns.client.view.playerArrow.createAndAdd, callback, options); }; @@ -113,7 +116,7 @@ function (Parent, Settings, Nc) { var options = { x: position.x * Settings.RATIO, y: position.y * Settings.RATIO, - } + }; Nc.trigger(Nc.ns.client.view.playerArrow.update, this.arrowMesh, options); }; diff --git a/app/Game/Config/ItemSettings.js b/app/Game/Config/ItemSettings.js index 5da7ff2..5706819 100644 --- a/app/Game/Config/ItemSettings.js +++ b/app/Game/Config/ItemSettings.js @@ -2,6 +2,8 @@ define([ ], function () { + + "use strict"; var ItemSettings = { diff --git a/app/Game/Config/Settings.js b/app/Game/Config/Settings.js index b2ad33e..ec80eba 100755 --- a/app/Game/Config/Settings.js +++ b/app/Game/Config/Settings.js @@ -3,6 +3,8 @@ define([ function () { + "use strict"; + var Settings = { STAGE_WIDTH: 600, STAGE_HEIGHT: 400, @@ -19,12 +21,14 @@ function () { BOX2D_TIME_STEP: 1 / 60, // PATHS - GRAPHICS_PATH: 'static/img/', - GRAPHICS_SUBPATH_ITEMS: 'Items/', - GRAPHICS_SUBPATH_CHARACTERS: 'Characters/', - GRAPHICS_SUBPATH_TILES: 'Tiles/', - MAPS_PATH: 'static/maps/tiled/', - AUDIO_PATH: 'static/sounds/', + GRAPHICS_PATH: "static/img/", + GRAPHICS_SUBPATH_ITEMS: "Items/", + GRAPHICS_SUBPATH_CHARACTERS: "Characters/", + GRAPHICS_SUBPATH_TILES: "Tiles/", + MAPS_PATH: "static/maps/tiled/", + AUDIO_PATH: "static/sounds/", + CHANNEL_RECORDING_PATH: "recordings/", + CHANNEL_PLAY_RECORDING: false, //"Quickstart-2015-03-15T19:00:28.545Z-debug_residence_stones.log", RATIO: 21, //35 // original tile size is 25 but we want it to resize to 20 @@ -32,7 +36,7 @@ function () { TILE_SIZE: 20, CAMERA_IS_ORTHOGRAPHIC: true, CAMERA_GLIDE: 12, // % of the way per frame - VIEW_CONTROLLER: 0 ? 'Three' : 'Pixi', + VIEW_CONTROLLER: 0 ? "Three" : "Pixi", ARROW_GLIDE: 30, // % of the way per frame SHOW_LAYER_INFO: false, @@ -48,7 +52,7 @@ function () { RESPAWN_TIME: 5, HEALTH_DISPLAY_TIME: 2, CRITICAL_HEALTH_THRESHOLD: 0.3, - RAGDOLL_DESTRUCTION_TIME: 20, + RAGDOLL_DESTRUCTION_TIME: 20000, VIEWPORT_SPEED_FACTOR: 640, VIEWPORT_LOOK_AHEAD: 0.1, @@ -68,28 +72,29 @@ function () { ITEM_LINEAR_DAMPING: 0.02, // BROWSER - CANVAS_DOM_ID: 'canvasContainer', - IS_BROWSER_ENVIRONMENT: typeof window !== 'undefined', + CANVAS_DOM_ID: "canvasContainer", + IS_BROWSER_ENVIRONMENT: typeof window !== "undefined", USE_WEBGL: true, // NETWORKING NETWORK_UPDATE_INTERVAL: 70, // in milliseconds NETWORK_LOG_INCOMING: false, NETWORK_LOG_OUTGOING: false, - NETWORK_LOG_FILTER: ['ping', 'pong', 'worldUpdate', 'lookAt'], + NETWORK_LOG_FILTER: ["ping", "pong", "worldUpdate", "lookAt"], // CHANNEL CHANNEL_MAX_USERS: 20, - CHANNEL_DESTRUCTION_TIME: 5 * 60, + CHANNEL_DESTRUCTION_TIME: 0.5 * 60, CHANNEL_END_ROUND_TIME: 4, //10, CHANNEL_DEFAULT_MAX_USERS: 40, CHANNEL_DEFAULT_SCORE_LIMIT: 10, - CHANNEL_DEFAULT_LEVELS: ['debug'], + CHANNEL_DEFAULT_LEVELS: ["debug"], + CHANNEL_RECORD_SESSION: true, // ME STATE ME_STATE_MAX_DIFFERENCE_METERS: 1, PUNKBUSTER_DIFFERENCE_METERS: 1 - } + }; Settings.TILE_RATIO = Settings.ORIGINAL_TILE_SIZE / Settings.TILE_SIZE; diff --git a/app/Game/Core/GameController.js b/app/Game/Core/GameController.js index f09479b..4c4bf71 100755 --- a/app/Game/Core/GameController.js +++ b/app/Game/Core/GameController.js @@ -4,9 +4,11 @@ define([ "Game/" + GLOBALS.context + "/Player", "Lib/Utilities/NotificationCenter", "Game/" + GLOBALS.context + "/GameObjects/Doll", + "Game/" + GLOBALS.context + "/GameObjects/GameObject", + "Lib/Utilities/Assert" ], -function (PhysicsEngine, TiledLevel, Player, Nc, Doll) { +function (PhysicsEngine, TiledLevel, Player, Nc, Doll, GameObject, Assert) { "use strict"; @@ -53,7 +55,7 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll) { GameController.prototype.getPhysicsEngine = function () { return this.physicsEngine; - } + }; GameController.prototype.loadLevel = function (levelUid) { @@ -63,7 +65,50 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll) { } this.level = new TiledLevel(levelUid, this.physicsEngine, this.gameObjects); - } + }; + + GameController.prototype.onWorldUpdate = function (updateData) { + + var body = this.physicsEngine.world.GetBodyList(); + do { + var userData = body.GetUserData(); + if (userData instanceof GameObject) { + var gameObject = userData; + if(updateData[gameObject.uid]) { + var update = updateData[gameObject.uid]; + this.onWorldUpdateGameObject(body, gameObject, update); + } + } + + } while (body = body.GetNext()); + + }; + + GameController.prototype.onWorldUpdateGameObject = function(body, gameObject, update) { + if (gameObject instanceof Doll) { + /* + if(gameObject === this.me.doll) { + this.me.setLastServerPositionState(update); + if(!this.me.acceptPositionStateUpdateFromServer()) { + return; // this is to ignore own doll updates from world update + } + } + */ + gameObject.setActionState(update.as); + gameObject.lookAt(update.laxy.x, update.laxy.y); + } + + Assert.number(update.p.x, update.p.y); + Assert.number(update.a); + Assert.number(update.lv.x, update.lv.y); + Assert.number(update.av); + + body.SetAwake(true); + body.SetPosition(update.p); + body.SetAngle(update.a); + body.SetLinearVelocity(update.lv); + body.SetAngularVelocity(update.av); + }; GameController.prototype.onResetLevel = function() { this.loadLevel(this.level.uid); @@ -84,7 +129,7 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll) { player.destroy(); delete this.players[userId]; - } + }; GameController.prototype.createPlayer = function(user) { var player = new Player(user.id, this.physicsEngine, user); @@ -93,17 +138,21 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll) { }; GameController.prototype.destroy = function () { + var i = 0; + + /* for(var player in this.players) { // this.players[player].destroy(); // FIXME: // commented out for now, because players are in gameObjects array. // try using a real gameobject for the health bar - } + }*/ - for (var i = 0; i < this.ncTokens.length; i++) { + + for (i = 0; i < this.ncTokens.length; i++) { Nc.off(this.ncTokens[i]); - }; + } /* * Contents of gameObject: Players, Items, Tiles, RagDolls @@ -111,12 +160,12 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll) { */ for (var key in this.gameObjects) { - for (var i = 0; i < this.gameObjects[key].length; i++) { + for (i = 0; i < this.gameObjects[key].length; i++) { var gameObject = this.gameObjects[key][i]; gameObject.destroy(); - }; - }; + } + } this.gameObjects = { fixed: [], @@ -124,7 +173,7 @@ function (PhysicsEngine, TiledLevel, Player, Nc, Doll) { }; this.physicsEngine.destroy(); - } + }; return GameController; }); diff --git a/app/Game/Core/GameObjects/Doll.js b/app/Game/Core/GameObjects/Doll.js index fdc356d..8090fb8 100755 --- a/app/Game/Core/GameObjects/Doll.js +++ b/app/Game/Core/GameObjects/Doll.js @@ -5,10 +5,11 @@ define([ "Game/Config/Settings", "Game/" + GLOBALS.context + "/Collision/Detector", "Game/" + GLOBALS.context + "/GameObjects/Item", - "Lib/Utilities/NotificationCenter" + "Lib/Utilities/NotificationCenter", + "Lib/Utilities/Assert" ], -function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { +function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc, Assert) { "use strict"; @@ -27,8 +28,8 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { this.standing = false; this.moveDirection = 0; this.lookDirection = 0; - this.legs; - this.footSensor; + this.legs = null; + this.footSensor = null; this.actionState = null; this.lookAtXY = { x:0, y:0 }; this.reachableItems = { @@ -59,6 +60,10 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { }; Doll.prototype.createFixtures = function () { + Assert.number(this.width, this.height); + Assert.number(this.reachDistance); + Assert.number(this.areaSize); + var self = this; var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); @@ -67,13 +72,15 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { fixtureDef.restitution = Settings.PLAYER_RESTITUTION; var headShape = new Box2D.Collision.Shapes.b2CircleShape(); - headShape.SetRadius(this.width / 2 / Settings.RATIO); + var radius = this.width / 2 / Settings.RATIO; + headShape.SetRadius(radius); + headShape.SetLocalPosition(new Box2D.Common.Math.b2Vec2(0, -(this.height - (this.width / 2)) / Settings.RATIO)); fixtureDef.shape = headShape; fixtureDef.isSensor = false; fixtureDef.userData = { onCollisionChange: this.onImpact.bind(this) - } + }; this.body.CreateFixture(fixtureDef); @@ -106,7 +113,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { fixtureDef.userData = { onCollisionChange: this.onFootSensorDetection.bind(this) - } + }; this.footSensor = this.body.CreateFixture(fixtureDef); @@ -125,7 +132,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { onCollisionChange: function(isColliding, fixture) { self.onFixtureWithinReach(isColliding, "left", fixture); } - } + }; this.body.CreateFixture(fixtureDef); var grabSensorRightShape = new Box2D.Collision.Shapes.b2PolygonShape(); @@ -144,7 +151,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { onCollisionChange: function(isColliding, fixture) { self.onFixtureWithinReach(isColliding, "right", fixture); } - } + }; this.body.CreateFixture(fixtureDef); @@ -163,7 +170,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { fixtureDef.userData = { onCollisionChange: function(isColliding, fixture) { - var userData = fixture.GetBody().GetUserData() + var userData = fixture.GetBody().GetUserData(); if(userData instanceof Doll) { var doll = userData; var i = self.nearbyDolls.indexOf(doll); @@ -178,28 +185,29 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { } } } - } + }; this.body.CreateFixture(fixtureDef); - } + }; Doll.prototype.setActionState = function(state) { this.actionState = state; - } + }; Doll.prototype.getActionState = function() { return this.actionState; - } + }; Doll.prototype.isWalking = function() { return ["walk", "walkback", "run"].indexOf(this.actionState) >= 0; - } + }; Doll.prototype.spawn = function (x, y) { + Assert.number(x, y); this.body.SetPosition(new Box2D.Common.Math.b2Vec2(x / Settings.RATIO, y / Settings.RATIO)); this.body.SetActive(true); this.setActionState("fall"); - } + }; Doll.prototype.getHeadPosition = function() { var pos = this.body.GetPosition(); @@ -212,10 +220,12 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { Doll.prototype.setFriction = function (friction) { if(!friction) friction = -1; + Assert.number(friction); + if (this.legs.GetFriction() != friction) { this.legs.SetFriction(friction); } - } + }; Doll.prototype.move = function (direction) { @@ -245,6 +255,8 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { this.setFriction(Settings.PLAYER_MOTION_FRICTION); this.body.SetAwake(true); + + Assert.number(speed, direction); var vector = new Box2D.Common.Math.b2Vec2(speed * direction, this.body.GetLinearVelocity().y); this.body.SetLinearVelocity(vector); @@ -261,7 +273,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { this.setActionState("walkback"); } } - } + }; Doll.prototype.stop = function () { this.moveDirection = 0; @@ -273,23 +285,20 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { vector.x *= Settings.JUMP_STOP_DAMPING_FACTOR; this.body.SetLinearVelocity(vector); } - } + }; Doll.prototype.jump = function () { if (this.isStanding()) { this.body.SetAwake(true); - var jumpSpeed = Settings.JUMP_SPEED; - - var vector = new Box2D.Common.Math.b2Vec2(0, -jumpSpeed); + var vector = new Box2D.Common.Math.b2Vec2(0, -Settings.JUMP_SPEED); this.body.SetLinearVelocity(vector); this.setStanding(false); - this.setActionState("jump"); } - } + }; Doll.prototype.jumpStop = function () { if (!this.isStanding() ) { @@ -300,17 +309,17 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { this.body.SetLinearVelocity(vector); } } - } + }; Doll.prototype.setStanding = function (isStanding) { if (this.standing == isStanding) return; this.standing = isStanding; if(isStanding) this.setActionState("stand"); - } + }; Doll.prototype.isStanding = function () { return this.standing; - } + }; Doll.prototype.lookAt = function(x, y) { var oldLookDirection = this.lookDirection; @@ -344,6 +353,9 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { } var bodyPosition = this.body.GetPosition(); + + Assert.number(this.width, this.height); + Assert.number(this.lookDirection); var handPosition = new Box2D.Common.Math.b2Vec2( bodyPosition.x + ((this.width / 2 / Settings.RATIO) * this.lookDirection), bodyPosition.y - this.height / 4 * 2 / Settings.RATIO // 2/3 of the body height @@ -382,7 +394,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { return this.nearbyDolls.length > 0; }; - Doll.prototype.onFootSensorDetection = function(isColliding, fixture) { + Doll.prototype.onFootSensorDetection = function(isColliding, fixture) { // jshint unused:false var self = this; @@ -419,9 +431,9 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { self.setStanding(false); } } - } + }; - Doll.prototype.onImpact = function(isColliding, fixture) { + Doll.prototype.onImpact = function(isColliding, fixture) { // jshint unused:false // overwrite if necessary }; @@ -439,7 +451,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { this.reachableItems[side].splice(i, 1); } } - } + }; Doll.prototype.getVelocities = function() { return { @@ -450,7 +462,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, Nc) { Doll.prototype.update = function() { - if (this.body.GetLinearVelocity().x == 0 && this.isWalking()) { + if (this.body.GetLinearVelocity().x === 0 && this.isWalking()) { this.stop(); } diff --git a/app/Game/Core/GameObjects/Item.js b/app/Game/Core/GameObjects/Item.js index 6109010..d848fa3 100644 --- a/app/Game/Core/GameObjects/Item.js +++ b/app/Game/Core/GameObjects/Item.js @@ -4,10 +4,11 @@ define([ "Lib/Utilities/Options", "Game/Config/Settings", "Lib/Utilities/Exception", - "Lib/Utilities/NotificationCenter" + "Lib/Utilities/NotificationCenter", + "Lib/Utilities/Assert" ], -function (Parent, Box2D, Options, Settings, Exception, Nc) { +function (Parent, Box2D, Options, Settings, Exception, Nc, Assert) { "use strict"; @@ -37,13 +38,13 @@ function (Parent, Box2D, Options, Settings, Exception, Nc) { this.body.ResetMassData(); this.flipDirection = 1; - Nc.trigger(Nc.ns.core.game.gameObject.add, 'animated', this); + Nc.trigger(Nc.ns.core.game.gameObject.add, "animated", this); } Item.prototype = Object.create(Parent.prototype); Item.prototype.getBodyDef = function() { - + Assert.number(this.options.x, this.options.y); var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.position.x = this.options.x / Settings.RATIO; @@ -51,14 +52,18 @@ function (Parent, Box2D, Options, Settings, Exception, Nc) { bodyDef.angle = 0; return bodyDef; - } + }; Item.prototype.getFixtureDef = function() { + Assert.number(this.options.width, this.options.height); + Assert.number(this.options.weight); + Assert.number(this.options.bounce); + var itemShape; var w = this.options.width / Settings.RATIO; var h = this.options.height / Settings.RATIO; - if(this.options.type == 'circle'){ + if(this.options.type == "circle") { var r = (w + h) / 4 ; itemShape = new Box2D.Collision.Shapes.b2CircleShape(); itemShape.SetRadius(r); @@ -68,22 +73,19 @@ function (Parent, Box2D, Options, Settings, Exception, Nc) { itemShape.SetAsOrientedBox(w / 2, h / 2, new Box2D.Common.Math.b2Vec2(0, -(h/2))); } - var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); fixtureDef.shape = itemShape; fixtureDef.density = this.options.weight; fixtureDef.friction = Settings.ITEM_FRICTION; - fixtureDef.restitution = this.options.bounce - ? this.options.bounce / 10 - : Settings.ITEM_RESTITUTION; + fixtureDef.restitution = this.options.bounce ? this.options.bounce / 10 : Settings.ITEM_RESTITUTION; fixtureDef.isSensor = false; fixtureDef.userData = { onCollisionChange: this.onCollisionChange.bind(this) - } + }; return fixtureDef; }; @@ -91,7 +93,7 @@ function (Parent, Box2D, Options, Settings, Exception, Nc) { Item.prototype.createFixture = function () { var fixtureDef = this.getFixtureDef(); this.body.CreateFixture(fixtureDef); - } + }; Item.prototype.flip = function(direction) { this.flipDirection = direction; @@ -99,24 +101,29 @@ function (Parent, Box2D, Options, Settings, Exception, Nc) { // FIXME: implement body flip if necessary }; - Item.prototype.beingGrabbed = function(player) { + Item.prototype.beingGrabbed = function(player) { // jshint unused:false // overwrite if necessary }; - Item.prototype.beingReleased = function(player) { + Item.prototype.beingReleased = function(player) { // jshint unused:false // overwrite if necessary }; - Item.prototype.onCollisionChange = function(isColliding, fixture, info) { + Item.prototype.onCollisionChange = function(isColliding, fixture, info) { // jshint unused:false // overwrite if necessary }; Item.prototype.reposition = function(handPosition, direction) { + Assert.number(handPosition.x, handPosition.y); + Assert.number(direction); + Assert.number(this.options.width); + Assert.number(this.options.grabAngle); + this.body.SetAwake(true); var position = new Box2D.Common.Math.b2Vec2( handPosition.x + ((this.options.width / Settings.RATIO / 2) * direction), handPosition.y - ) + ); this.body.SetPosition(position); this.flip(direction); this.body.SetAngle((this.options.grabAngle || 0) * direction); @@ -131,20 +138,24 @@ function (Parent, Box2D, Options, Settings, Exception, Nc) { }; Item.prototype.accelerateBody = function(body, options, carrierVelocity) { + Assert.number(this.options.weight); + Assert.number(carrierVelocity.x, carrierVelocity.y); + Assert.number(options.x, options.y); + Assert.number(options.av); body.SetAwake(true); - var vector = new Box2D.Common.Math.b2Vec2( - options.x * Settings.MAX_THROW_FORCE / this.options.weight + carrierVelocity.x, - -options.y * Settings.MAX_THROW_FORCE / this.options.weight + carrierVelocity.y - ); - + var x = options.x * Settings.MAX_THROW_FORCE / this.options.weight + carrierVelocity.x; + var y = -options.y * Settings.MAX_THROW_FORCE / this.options.weight + carrierVelocity.y; + var vector = new Box2D.Common.Math.b2Vec2(x, y); body.SetLinearVelocity(vector); - body.SetAngularVelocity(-options.av * Settings.MAX_THROW_ANGULAR_VELOCITY); + + var av = -options.av * Settings.MAX_THROW_ANGULAR_VELOCITY; + body.SetAngularVelocity(av); }; Item.prototype.destroy = function() { - Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this); + Nc.trigger(Nc.ns.core.game.gameObject.remove, "animated", this); Parent.prototype.destroy.call(this); }; diff --git a/app/Game/Core/GameObjects/Items/RagDoll.js b/app/Game/Core/GameObjects/Items/RagDoll.js index fa2bdd0..ef753e6 100644 --- a/app/Game/Core/GameObjects/Items/RagDoll.js +++ b/app/Game/Core/GameObjects/Items/RagDoll.js @@ -2,10 +2,13 @@ define([ "Game/" + GLOBALS.context + "/GameObjects/Item", "Lib/Vendor/Box2D", "Game/Config/Settings", - "Lib/Utilities/NotificationCenter" + "Lib/Utilities/NotificationCenter", + "Lib/Utilities/Assert", + "Lib/Utilities/Options", + "Game/Config/ItemSettings", ], -function (Parent, Box2D, Settings, Nc) { +function (Parent, Box2D, Settings, Nc, Assert, Options, ItemSettings) { "use strict"; @@ -92,10 +95,9 @@ function (Parent, Box2D, Settings, Nc) { - - - - + // FIXME + var ragdollOptions = Options.merge(ItemSettings.RagDoll, ItemSettings.Default); + options = Options.merge(options, ragdollOptions); Parent.call(this, physicsEngine, uid, options); //this.createSensor(); @@ -187,6 +189,8 @@ function (Parent, Box2D, Settings, Nc) { }; RagDoll.prototype.getFixtureDef = function() { + Assert.number(this.options.limbs.chest.width, this.options.limbs.chest.height); + var fixtureDef = Parent.prototype.getFixtureDef.call(this); fixtureDef.density = Settings.PLAYER_DENSITY; fixtureDef.friction = Settings.PLAYER_FRICTION; @@ -206,6 +210,8 @@ function (Parent, Box2D, Settings, Nc) { }; RagDoll.prototype.createSensor = function() { + Assert.number(this.options.width, this.options.height); + var w = this.options.width / Settings.RATIO; var h = this.options.height / Settings.RATIO; @@ -218,12 +224,16 @@ function (Parent, Box2D, Settings, Nc) { fixtureDef.userData = { onCollisionChange: this.onCollisionChange.bind(this) - } + }; this.body.CreateFixture(fixtureDef); }; RagDoll.prototype.addHead = function() { + Assert.number(this.options.x, this.options.y); + Assert.number(this.options.limbs.head.x, this.options.limbs.head.y); + Assert.number(this.options.limbs.head.width); + var x = this.options.x + this.options.limbs.head.x, y = this.options.y + this.options.limbs.head.y; @@ -270,6 +280,11 @@ function (Parent, Box2D, Settings, Nc) { }; RagDoll.prototype.addLimb = function(name, connectTo, xOffset, yOffset) { + Assert.number(xOffset, yOffset); + Assert.number(this.options.x, this.options.y); + Assert.number(this.options.limbs[name].x, this.options.limbs[name].y); + Assert.number(this.options.limbs[name].width, this.options.limbs[name].height); + var x = this.options.x + this.options.limbs[name].x, y = this.options.y + this.options.limbs[name].y; @@ -322,6 +337,10 @@ function (Parent, Box2D, Settings, Nc) { }; RagDoll.prototype.reposition = function(handPosition, direction) { + Assert.number(this.options.limbs.head.x, this.options.limbs.head.y); + Assert.number(this.options.grabAngle); + Assert.number(direction); + Parent.prototype.reposition.call(this, handPosition, direction); var chestPosition = this.body.GetPosition(); @@ -329,7 +348,7 @@ function (Parent, Box2D, Settings, Nc) { var position = new Box2D.Common.Math.b2Vec2( chestPosition.x + this.options.limbs.head.x / Settings.RATIO, chestPosition.y + this.options.limbs.head.y / Settings.RATIO - ) + ); this.limbs.head.SetPosition(position); this.limbs.head.SetAngle((this.options.grabAngle || 0) * direction); }; @@ -345,6 +364,9 @@ function (Parent, Box2D, Settings, Nc) { }; RagDoll.prototype.setVelocities = function(options) { + Assert.number(options.linearVelocity.x, options.linearVelocity.y); + Assert.number(options.angularVelocity); + this.body.SetLinearVelocity(options.linearVelocity); this.body.SetAngularVelocity(options.angularVelocity); for(var name in this.limbs) { @@ -354,7 +376,7 @@ function (Parent, Box2D, Settings, Nc) { RagDoll.prototype.destroy = function() { - Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this); + Nc.trigger(Nc.ns.core.game.gameObject.remove, "animated", this); var world = this.body.GetWorld(); for (var name in this.limbs) { diff --git a/app/Game/Core/GameObjects/Items/Rube.js b/app/Game/Core/GameObjects/Items/Rube.js index 2a5c179..ccc06a6 100644 --- a/app/Game/Core/GameObjects/Items/Rube.js +++ b/app/Game/Core/GameObjects/Items/Rube.js @@ -2,10 +2,11 @@ define([ "Game/" + GLOBALS.context + "/GameObjects/Item", "Lib/Vendor/RubeLoader", "Lib/Vendor/Box2D", - "Game/Config/Settings" + "Game/Config/Settings", + "Lib/Utilities/Assert" ], -function (Parent, RubeLoader, Box2D, Settings ) { +function (Parent, RubeLoader, Box2D, Settings, Assert) { "use strict"; @@ -13,6 +14,7 @@ function (Parent, RubeLoader, Box2D, Settings ) { var __ragdollJson; function Rube(physicsEngine, uid, options) { + Assert.number(options.x, options.y); this.rubeLoader = null; this.body = null; @@ -1398,7 +1400,7 @@ function (Parent, RubeLoader, Box2D, Settings ) { "subStepping" : false, "velocityIterations" : 8, "warmStarting" : true -} +}; diff --git a/app/Game/Core/GameObjects/Items/Skateboard.js b/app/Game/Core/GameObjects/Items/Skateboard.js index 0be6e76..311f01e 100755 --- a/app/Game/Core/GameObjects/Items/Skateboard.js +++ b/app/Game/Core/GameObjects/Items/Skateboard.js @@ -1,10 +1,11 @@ define([ "Game/" + GLOBALS.context + "/GameObjects/Item", "Lib/Vendor/Box2D", - "Game/Config/Settings" + "Game/Config/Settings", + "Lib/Utilities/Assert" ], -function (Parent, Box2D, Settings) { +function (Parent, Box2D, Settings, Assert) { "use strict"; @@ -27,6 +28,8 @@ function (Parent, Box2D, Settings) { Skateboard.prototype = Object.create(Parent.prototype); Skateboard.prototype.createFixture = function () { + Assert.number(this.options.width, this.options.height); + Assert.number(this.options.weight); var deckShape = new Box2D.Collision.Shapes.b2PolygonShape(); var w = this.options.width / Settings.RATIO; @@ -45,10 +48,12 @@ function (Parent, Box2D, Settings) { fixtureDef.isSensor = false; this.body.CreateFixture(fixtureDef); - } + }; Skateboard.prototype.addWheel = function(x, y) { + Assert.number(x, y); + var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.position.x = x / Settings.RATIO; diff --git a/app/Game/Core/GameObjects/Tile.js b/app/Game/Core/GameObjects/Tile.js index 45d67eb..8a46fce 100755 --- a/app/Game/Core/GameObjects/Tile.js +++ b/app/Game/Core/GameObjects/Tile.js @@ -3,10 +3,11 @@ define([ "Lib/Vendor/Box2D", "Game/Config/Settings", "Lib/Utilities/Exception", - "Lib/Utilities/NotificationCenter" + "Lib/Utilities/NotificationCenter", + "Lib/Utilities/Assert" ], -function (Parent, Box2D, Settings, Exception, Nc) { +function (Parent, Box2D, Settings, Exception, Nc, Assert) { "use strict"; @@ -15,12 +16,14 @@ function (Parent, Box2D, Settings, Exception, Nc) { Parent.call(this, physicsEngine, uid); this.createPhysicTile(this.options); - Nc.trigger(Nc.ns.core.game.gameObject.add, 'fixed', this); + Nc.trigger(Nc.ns.core.game.gameObject.add, "fixed", this); } Tile.prototype = Object.create(Parent.prototype); Tile.prototype.getBodyDef = function() { + Assert.number(this.options.x, this.options.y); + Assert.number(this.options.r); var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_staticBody; @@ -29,7 +32,7 @@ function (Parent, Box2D, Settings, Exception, Nc) { bodyDef.angle = (this.options.r || 0) * 90 * Math.PI / 180; return bodyDef; - } + }; Tile.prototype.createPhysicTile = function (tile) { var vertices = this.createVertices(tile); @@ -43,7 +46,7 @@ function (Parent, Box2D, Settings, Exception, Nc) { fixtureDef.restitution = Settings.TILE_RESTITUTION; fixtureDef.isSensor = false; this.body.CreateFixture(fixtureDef); - } + }; Tile.prototype.createVertices = function (tile) { var vs = []; @@ -104,22 +107,21 @@ function (Parent, Box2D, Settings, Exception, Nc) { default: throw new Exception("Tile Creation - no shape given"); - break; } return vs; - } + }; Tile.prototype.mkArg = function (multiplier) { return Settings.TILE_SIZE / 2 / Settings.RATIO * multiplier; - } + }; Tile.prototype.addVec = function (vs, m1, m2) { return vs.push(new Box2D.Common.Math.b2Vec2(this.mkArg(m1), this.mkArg(m2))); - } + }; Tile.prototype.destroy = function() { - Nc.trigger(Nc.ns.core.game.gameObject.remove, 'fixed', this); + Nc.trigger(Nc.ns.core.game.gameObject.remove, "fixed", this); }; return Tile; diff --git a/app/Game/Core/Loader/Level.js b/app/Game/Core/Loader/Level.js index ee029d5..a599bb3 100755 --- a/app/Game/Core/Loader/Level.js +++ b/app/Game/Core/Loader/Level.js @@ -12,6 +12,8 @@ define([ ], function (Settings, Box2D, Nc, Abstract, CollisionDetector, Tile, Item, Skateboard, RagDoll, Rube) { + "use strict"; + function Level (uid, engine) { this.uid = uid; this.engine = engine; diff --git a/app/Game/Core/Loader/TiledLevel.js b/app/Game/Core/Loader/TiledLevel.js index 50cc5d0..85ff92d 100755 --- a/app/Game/Core/Loader/TiledLevel.js +++ b/app/Game/Core/Loader/TiledLevel.js @@ -14,6 +14,8 @@ define([ ], function (Parent, Settings, ItemSettings, Box2D, Options, Exception, Nc, AbstractLayer, CollisionDetector, Tile, Item, Skateboard) { + "use strict"; + function TiledLevel (path, engine) { this.layerMapping = { @@ -109,7 +111,7 @@ define([ } lastLayerId = layerOptions.layerId; - }; + } Parent.prototype.setup.call(this, levelData); @@ -137,21 +139,21 @@ define([ t: imagePath, x: i % options.width, y: parseInt(i / options.width , 10) - } + }; tilesOptions.push(tileOptions); } Parent.prototype.createTiles.call(this, tilesOptions); - } + }; TiledLevel.prototype.createItems = function(options) { var objects = options.objects; - var itemsOptions = [] + var itemsOptions = []; for (var i = 0; i < objects.length; i++) { - var options = this.gatherOptions(objects[i]); + options = this.gatherOptions(objects[i]); itemsOptions.push(options); - }; + } Parent.prototype.createItems.call(this, itemsOptions); }; @@ -188,18 +190,14 @@ define([ TiledLevel.prototype.getDefaultItemSettingsByName = function(name) { if(!name) { - throw new Exception('Item name cannot be be empty'); + throw new Exception("Item name cannot be be empty"); } if(ItemSettings[name] === undefined) { - throw new Exception('Item name (' + name + ') cannot be found in item list'); + throw new Exception("Item name (" + name + ") cannot be found in item list"); } - var options = ItemSettings.Default; - - options = Options.merge(ItemSettings[name], options); - - return options; + return Options.merge(ItemSettings[name], ItemSettings.Default); }; TiledLevel.prototype.getTileImagePath = function(gid) { @@ -210,7 +208,7 @@ define([ return tileset.tiles["" + (gid - offset)].image; } } - } + }; return TiledLevel; }); \ No newline at end of file diff --git a/app/Game/Core/Player.js b/app/Game/Core/Player.js index 3a5ac6d..e9a818a 100755 --- a/app/Game/Core/Player.js +++ b/app/Game/Core/Player.js @@ -23,7 +23,7 @@ function (Doll, Settings, Nc, Exception, SpectatorDoll, RagDoll) { this.playerController = null; this.doll; this.id = id; - this.isSpawned = false; + this.spawned = false; this.holdingItem = null; this.spectatorDoll = new SpectatorDoll(this.physicsEngine, "spectatorDoll-" + this.id, this); @@ -31,7 +31,7 @@ function (Doll, Settings, Nc, Exception, SpectatorDoll, RagDoll) { } Player.prototype.getActiveDoll = function() { - if(this.isSpawned) { + if(this.spawned) { return this.doll; } else if (this.ragDoll) { return this.ragDoll; @@ -42,9 +42,13 @@ function (Doll, Settings, Nc, Exception, SpectatorDoll, RagDoll) { Player.prototype.spawn = function (x, y) { this.doll = new Doll(this.physicsEngine, "doll-" + this.id, this); this.doll.spawn(x, y); - this.isSpawned = true; + this.spawned = true; } + Player.prototype.isSpawned = function() { + return this.spawned; + }; + Player.prototype.getPosition = function () { return this.getActiveDoll().getPosition(); } @@ -55,47 +59,47 @@ function (Doll, Settings, Nc, Exception, SpectatorDoll, RagDoll) { Player.prototype.move = function (direction) { - if(!this.isSpawned) return false; + if(!this.spawned) return false; this.doll.move(direction); } Player.prototype.stop = function () { - if(!this.isSpawned) return false; + if(!this.spawned) return false; this.doll.stop(); } Player.prototype.jump = function () { - if(!this.isSpawned) return false; + if(!this.spawned) return false; this.doll.jump(); } Player.prototype.jumpStop = function () { - if(!this.isSpawned) return false; + if(!this.spawned) return false; this.doll.jumpStop(); } Player.prototype.lookAt = function (x, y) { - if(!this.isSpawned) return false; + if(!this.spawned) return false; // FIXME implement spectator movement here this.doll.lookAt(x, y); } Player.prototype.grab = function(item) { - if(!this.isSpawned) return false; + if(!this.spawned) return false; this.doll.grab(item); item.beingGrabbed(this); this.holdingItem = item; }; Player.prototype.throw = function(options, item) { - if(!this.isSpawned) return false; + if(!this.spawned) return false; this.doll.throw(item, options); item.beingReleased(this); this.holdingItem = null; }; Player.prototype.kill = function(killedByPlayer, ragDollId) { - if(!this.isSpawned) return false; + if(!this.spawned) return false; // FIXME: do something better then just respawn in GameController if(this.holdingItem) { @@ -125,7 +129,7 @@ function (Doll, Settings, Nc, Exception, SpectatorDoll, RagDoll) { var ragDoll = new RagDoll(this.physicsEngine, "ragDoll-" + this.id + "-" + ragDollId, options); ragDoll.setVelocities(this.doll.getVelocities()); - this.isSpawned = false; + this.spawned = false; this.doll.destroy(); this.doll = null; diff --git a/app/Lib/Utilities/Assert.js b/app/Lib/Utilities/Assert.js new file mode 100644 index 0000000..0a89ed7 --- /dev/null +++ b/app/Lib/Utilities/Assert.js @@ -0,0 +1,21 @@ +define([ + "Lib/Utilities/Exception" +], + +function (Exception) { + + "use strict"; + + var Assert = {}; + + Assert.number = function() { + for (var i = 0; i < arguments.length; i++) { + if(isNaN(parseFloat(arguments[i]))) { + throw new Exception("Assert: not a number ", JSON.stringify(arguments)); + } + } + }; + + return Assert; + +}); \ No newline at end of file diff --git a/app/Lib/Utilities/NotificationCenter.js b/app/Lib/Utilities/NotificationCenter.js index c751836..dcabf3e 100755 --- a/app/Lib/Utilities/NotificationCenter.js +++ b/app/Lib/Utilities/NotificationCenter.js @@ -204,7 +204,7 @@ function (Exception) { this.validate(topic); if (!this.topics[topic]) { - console.warn("No such topic " + topic + ". Could not trigger. arguments: " + arguments.join); + //console.warn("No such topic " + topic + ". Could not trigger. arguments: " + arguments.join); } var args = Array.prototype.slice.call(arguments, 1); diff --git a/recordings/Quickstart-2015-03-15T19:00:28.545Z-debug_residence_stones.rec b/recordings/Quickstart-2015-03-15T19:00:28.545Z-debug_residence_stones.rec new file mode 100644 index 0000000..f10b78b --- /dev/null +++ b/recordings/Quickstart-2015-03-15T19:00:28.545Z-debug_residence_stones.rec @@ -0,0 +1,98 @@ +m1426446028547{"recipient":"channel","data":{"addUser":{"id":"7389285181034131943","nickname":"Jeena"}}} +m1426446029119{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"clientReady\\\":null}\"}"} +w1426446029547{"doll-7389285181034131943":{"p":{"x":26.757009396292265,"y":2.8537988666369247},"a":0,"lv":{"x":0,"y":3.686287386450715e-18},"av":0,"as":"stand","laxy":{"x":0,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":20.68034223796989,"y":14.27172409912905},"a":0.05645956288623199,"lv":{"x":-0.3822032971313994,"y":0.10581586623357915},"av":-0.9131901027366345},"item-4":{"p":{"x":20.210667860242594,"y":14.23713937029844},"a":0.2172662762511257,"lv":{"x":-0.4539838684349691,"y":0.056447865910879066},"av":-0.8171646189887583},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":9.013612698412686,"y":18.087738095238098},"a":0,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.14632479802086,"y":14.27055244283271},"a":-0.030402669209750526,"lv":{"x":0.36764627338079947,"y":0.11541986576858798},"av":0.6858739292935763}} +w1426446030548{"doll-7389285181034131943":{"p":{"x":26.757009396292265,"y":2.8537988666369247},"a":0,"lv":{"x":0,"y":0},"av":0,"as":"stand","laxy":{"x":0,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":20.676956793943322,"y":14.27693273489722},"a":-0.006893630787064592,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200040618322713,"y":14.276203443653712},"a":-0.0004911852214511643,"lv":{"x":-0.0017410956075321858,"y":8.552005003579723e-7},"av":3.946495907847236e-17},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":9.013612698412686,"y":18.087738095238098},"a":0,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446031024{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":-0.1,\\\"y\\\":0}}\"}"} +m1426446031024{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveLeft\\\":null}\"}"} +w1426446031550{"doll-7389285181034131943":{"p":{"x":23.369073130763105,"y":5.155903892632974},"a":0,"lv":{"x":-6.2,"y":10.122520758193609},"av":0,"as":"run","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":20.676956793943322,"y":14.27693273489722},"a":-0.006893630787064592,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":9.013612698412686,"y":18.087738095238098},"a":0,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446031695{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":22.546741092148903,\\\"y\\\":6.945440200409302},\\\"lv\\\":{\\\"x\\\":-6.2,\\\"y\\\":13.302715397413536}}}\"}"} +m1426446031704{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":22.484989092148904,\\\"y\\\":7.080524845767541},\\\"lv\\\":{\\\"x\\\":-6.2,\\\"y\\\":13.508464535823881}}}\"}"} +m1426446031782{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446031912{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":21.73476374575245,\\\"y\\\":10.32390717922336},\\\"lv\\\":{\\\"x\\\":-2.3463161980324543,\\\"y\\\":17.55729589350694}}}\"}"} +m1426446032042{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":21.44100843193758,\\\"y\\\":12.7671303982799},\\\"lv\\\":{\\\"x\\\":-2.227842551800874,\\\"y\\\":19.92590130886559}}}\"}"} +m1426446032126{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":21.2807959597357,\\\"y\\\":14.271291852124465},\\\"lv\\\":{\\\"x\\\":0,\\\"y\\\":-2.133620078919897}}}\"}"} +m1426446032164{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"handActionRequest\\\":{\\\"x\\\":-0.1,\\\"y\\\":0,\\\"av\\\":0}}\"}"} +w1426446032551{"doll-7389285181034131943":{"p":{"x":21.2807959597357,"y":14.2827540733478},"a":0,"lv":{"x":0,"y":2.0808241610672144e-17},"av":0,"as":"stand","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":20.92365310259284,"y":13.401801692395418},"a":-0.3,"lv":{"x":1.1578834351175484e-60,"y":1.9012546152460842e-16},"av":6.564623608182231e-48},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":9.013612698412686,"y":18.087738095238098},"a":0,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446032607{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jump\\\":null}\"}"} +m1426446032783{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":-0.1,\\\"y\\\":0}}\"}"} +m1426446032783{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveLeft\\\":null}\"}"} +m1426446033408{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"handActionRequest\\\":{\\\"x\\\":-2,\\\"y\\\":1.1616379503624417,\\\"av\\\":-0.33531939942689776}}\"}"} +w1426446033552{"doll-7389285181034131943":{"p":{"x":16.557991085576948,"y":12.476641521631196},"a":0,"lv":{"x":-6.2,"y":9.458269369609303},"av":0,"as":"jump","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":12.048335711507379,"y":9.27107894546859},"a":-0.15313010305101882,"lv":{"x":-34.2,"y":-6.332771923395663},"av":1.0059581982806933},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":9.013612698412686,"y":18.087738095238098},"a":0,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446033620{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jumpStop\\\":null}\"}"} +m1426446033708{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446033764{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":15.545509158762231,\\\"y\\\":14.939529946319917},\\\"lv\\\":{\\\"x\\\":-2.411280442117325,\\\"y\\\":13.851923076171733}}}\"}"} +m1426446033823{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":15.407720608611541,\\\"y\\\":15.786375605059586},\\\"lv\\\":{\\\"x\\\":-2.355804291795286,\\\"y\\\":15.018971297630832}}}\"}"} +m1426446033890{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":15.252508070805703,\\\"y\\\":16.84788590944936},\\\"lv\\\":{\\\"x\\\":-2.2933002802534532,\\\"y\\\":16.333499883787308}}}\"}"} +m1426446033906{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":15.216050100270346,\\\"y\\\":17.114162758801857},\\\"lv\\\":{\\\"x\\\":-2.278623158459831,\\\"y\\\":16.642303084531072}}}\"}"} +m1426446034032{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":-0.1,\\\"y\\\":0}}\"}"} +m1426446034032{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveLeft\\\":null}\"}"} +w1426446034554{"doll-7389285181034131943":{"p":{"x":11.194618169931237,"y":18.075345972889064},"a":0,"lv":{"x":-8,"y":-0.3919449863882458},"av":0,"as":"run","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.5543134118221587,"y":18.08462667589248},"a":25.09946829820324,"lv":{"x":-0.19007540236753293,"y":-0.061006264861284215},"av":-0.46231125937975326},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":9.013612698412686,"y":18.087738095238098},"a":0,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446034796{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"handActionRequest\\\":{\\\"x\\\":-0.1,\\\"y\\\":0,\\\"av\\\":0}}\"}"} +m1426446034797{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446035284{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":0.1,\\\"y\\\":0}}\"}"} +m1426446035284{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveRight\\\":null}\"}"} +m1426446035395{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jump\\\":null}\"}"} +w1426446035556{"doll-7389285181034131943":{"p":{"x":10.491286858763196,"y":16.009696234603773},"a":0,"lv":{"x":6.2,"y":-10.887028542012015},"av":0,"as":"jump","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":10.824620192096528,"y":15.128743853651395},"a":0.5,"lv":{"x":6.1577922291668665,"y":-10.887028542012015},"av":-1.4981364335015035e-95},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446035619{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jumpStop\\\":null}\"}"} +m1426446035622{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"handActionRequest\\\":{\\\"x\\\":2,\\\"y\\\":1.0402407501042503,\\\"av\\\":0.4762204811665006}}\"}"} +m1426446035669{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446036222{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":0.1,\\\"y\\\":0}}\"}"} +m1426446036222{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveRight\\\":null}\"}"} +w1426446036557{"doll-7389285181034131943":{"p":{"x":14.892865112434567,"y":18.093198012571065},"a":0,"lv":{"x":8,"y":1.1357017756785659e-17},"av":0,"as":"run","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.67263575288429,"y":9.396029900844805},"a":1.5453100773100037,"lv":{"x":1.2141986028185257,"y":1.5118096406061725},"av":7.842891058848907},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446036597{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jump\\\":null}\"}"} +m1426446037146{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jumpStop\\\":null}\"}"} +m1426446037146{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446037233{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":-0.1,\\\"y\\\":0}}\"}"} +m1426446037233{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveLeft\\\":null}\"}"} +w1426446037559{"doll-7389285181034131943":{"p":{"x":16.315888057006195,"y":18.09351694650934},"a":0,"lv":{"x":-8,"y":0},"av":0,"as":"run","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":17.676190476190477,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446037870{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jump\\\":null}\"}"} +m1426446037907{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446037932{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":0.1,\\\"y\\\":0}}\"}"} +m1426446037933{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveRight\\\":null}\"}"} +m1426446038419{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jumpStop\\\":null}\"}"} +m1426446038432{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446038538{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"handActionRequest\\\":{\\\"x\\\":0.1,\\\"y\\\":0,\\\"av\\\":0}}\"}"} +w1426446038561{"doll-7389285181034131943":{"p":{"x":17.1826631025223,"y":14.213702272433377},"a":0,"lv":{"x":2.316415665762817,"y":3.1852767893487735},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":17.49218691204611,"y":13.332749891480995},"a":0.3,"lv":{"x":2.316415665762817,"y":3.1852767893487735},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446038958{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":-0.1,\\\"y\\\":0}}\"}"} +m1426446038958{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveLeft\\\":null}\"}"} +m1426446038996{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jump\\\":null}\"}"} +m1426446039345{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446039357{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jumpStop\\\":null}\"}"} +w1426446039562{"doll-7389285181034131943":{"p":{"x":14.373155722224688,"y":10.923172851093172},"a":0,"lv":{"x":-2.3491405651705346,"y":3.215539708036451},"av":0,"as":"jump","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":14.063631912700878,"y":10.04222047014079},"a":-0.3,"lv":{"x":-2.3491405651705346,"y":3.215539708036451},"av":1.4981364335015035e-95},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446039848{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jump\\\":null}\"}"} +m1426446039870{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":-0.1,\\\"y\\\":0}}\"}"} +m1426446039870{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveLeft\\\":null}\"}"} +m1426446039961{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"mePositionStateUpdate\\\":{\\\"p\\\":{\\\"x\\\":13.763554582654288,\\\"y\\\":9.91021111614182},\\\"lv\\\":{\\\"x\\\":-6.2,\\\"y\\\":-12.214568104301154}}}\"}"} +m1426446040457{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"jumpStop\\\":null}\"}"} +m1426446040491{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +w1426446040564{"doll-7389285181034131943":{"p":{"x":9.827992197957391,"y":7.616287969672424},"a":0,"lv":{"x":-0.0000010315612595218654,"y":-0.3467108761433166},"av":0,"as":"stand","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":9.51846838843358,"y":6.735335588720043},"a":-0.3,"lv":{"x":-0.0000010315612595218745,"y":-0.3467108761433166},"av":-3.237869826367756e-34},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446040814{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"handActionRequest\\\":{\\\"x\\\":null,\\\"y\\\":null,\\\"av\\\":0}}\"}"} +m1426446041546{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":-0.1,\\\"y\\\":0}}\"}"} +m1426446041546{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveLeft\\\":null}\"}"} +w1426446041565{"doll-7389285181034131943":{"p":{"x":9.695420727381228,"y":7.6162879696953505},"a":0,"lv":{"x":-8,"y":0},"av":0,"as":"run","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":9.401617976491387,"y":7.516140983169705},"a":-1.564982640581702,"lv":{"x":0.0015602824631008733,"y":-0.0055646575139384315},"av":0.0151800309605853},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446041708{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446042118{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"handActionRequest\\\":{\\\"x\\\":-0.1,\\\"y\\\":0,\\\"av\\\":0}}\"}"} +m1426446042420{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":-0.1,\\\"y\\\":0}}\"}"} +m1426446042420{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveLeft\\\":null}\"}"} +w1426446042568{"doll-7389285181034131943":{"p":{"x":7.146502745202811,"y":7.6190476190527345},"a":0,"lv":{"x":-8,"y":1.8167431059639174e-9},"av":0,"as":"run","laxy":{"x":-0.1,"y":0}},"item-6":{"p":{"x":6.836978935679003,"y":6.738095238100354},"a":-0.3,"lv":{"x":-7.710315253398224,"y":1.816743105963944e-9},"av":-1.2647929009154966e-36},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446042873{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +m1426446042996{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"lookAt\\\":{\\\"x\\\":0.1,\\\"y\\\":0}}\"}"} +m1426446042996{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"moveRight\\\":null}\"}"} +m1426446043102{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"handActionRequest\\\":{\\\"x\\\":2,\\\"y\\\":0.24735158698021256,\\\"av\\\":-0.506800103937166}}\"}"} +m1426446043149{"recipient":"7389285181034131943","data":"{\"gameCommand\":\"{\\\"stop\\\":null}\"}"} +w1426446043570{"doll-7389285181034131943":{"p":{"x":6.717469927715379,"y":18.026718836374023},"a":0,"lv":{"x":0,"y":-1.5933058441069676},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":15.346920374111809,"y":8.242346533188677},"a":13.745544723304238,"lv":{"x":8.865053038008881,"y":-6.948476024418163},"av":40.16880149763361},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446044571{"doll-7389285181034131943":{"p":{"x":6.717469927715379,"y":18.094932218730197},"a":0,"lv":{"x":0,"y":0},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":24.736836349036146,"y":14.105602828936636},"a":53.954515022435494,"lv":{"x":8.865053038008881,"y":19.077523975581837},"av":40.16880149763361},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446045571{"doll-7389285181034131943":{"p":{"x":6.717469927715379,"y":18.094932218730197},"a":0,"lv":{"x":0,"y":0},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":25.484252760088392,"y":17.1308518892069},"a":56.5833675581005,"lv":{"x":0.04489757650580847,"y":-0.010299028060006578},"av":0.12321006381376746},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446046572{"doll-7389285181034131943":{"p":{"x":6.717469927715379,"y":18.094932218730197},"a":0,"lv":{"x":0,"y":0},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446047573{"doll-7389285181034131943":{"p":{"x":6.717469927715379,"y":18.094932218730197},"a":0,"lv":{"x":0,"y":0},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446048574{"doll-7389285181034131943":{"p":{"x":6.717469927715379,"y":18.094932218730197},"a":0,"lv":{"x":0,"y":0},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446049575{"doll-7389285181034131943":{"p":{"x":6.717469927715379,"y":18.094932218730197},"a":0,"lv":{"x":0,"y":0},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446050576{"doll-7389285181034131943":{"p":{"x":6.717469927715379,"y":18.094932218730197},"a":0,"lv":{"x":0,"y":0},"av":0,"as":"stand","laxy":{"x":0.1,"y":0}},"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +m1426446051478{"recipient":"channel","data":{"releaseUser":"7389285181034131943"}} +w1426446051575{"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446052576{"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446053576{"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446054579{"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446055579{"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446056580{"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} +w1426446057580{"item-6":{"p":{"x":25.484809555865787,"y":17.13345683956885},"a":56.55108306250028,"lv":{"x":0,"y":0},"av":0},"item-5":{"p":{"x":3.551564486509986,"y":18.086205519078288},"a":25.13402937147234,"lv":{"x":0,"y":0},"av":0},"item-4":{"p":{"x":20.200046042197616,"y":14.276203440989589},"a":-0.0004911852214511747,"lv":{"x":0,"y":0},"av":0},"item-3":{"p":{"x":22.4,"y":14.277445638095237},"a":0,"lv":{"x":0,"y":0},"av":0},"item-2":{"p":{"x":25.676240547787568,"y":9.396188210902643},"a":1.5696221500784544,"lv":{"x":0,"y":0},"av":0},"item-1":{"p":{"x":19.642184126984116,"y":14.278214285714286},"a":0,"lv":{"x":0,"y":0},"av":0},"item-0":{"p":{"x":19.147450032657666,"y":14.276009262801196},"a":0.0025201794161469693,"lv":{"x":0,"y":0},"av":0}} diff --git a/static/maps/tiled/debug/debug.json b/static/maps/tiled/debug.json similarity index 100% rename from static/maps/tiled/debug/debug.json rename to static/maps/tiled/debug.json