Raspsnir/public_html/browserquest/js/game.js

35 lines
146 KiB
JavaScript

/*
RequireJS text 0.26.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
Available via the MIT or new BSD license.
see: http://github.com/jrburke/requirejs for details
*/
/*
Copyright (c) 2010-2011 Ivo Wetzel.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/**
* A* (A-Star) algorithm for a path finder
* @author Andrea Giammarchi
* @license Mit Style License
*/
define("infomanager",[],function(){var e=Class.extend({init:function(e){this.game=e,this.infos={},this.destroyQueue=[]},addDamageInfo:function(e,t,r,i){var s=this.game.currentTime,o=s+""+Math.abs(e)+""+t+""+r,u=this,a=new n(o,e,t,r,n.DURATION,i);a.onDestroy(function(e){u.destroyQueue.push(e)}),this.infos[o]=a},forEachInfo:function(e){var t=this;_.each(this.infos,function(t,n){e(t)})},update:function(e){var t=this;this.forEachInfo(function(t){t.update(e)}),_.each(this.destroyQueue,function(e){delete t.infos[e]}),this.destroyQueue=[]}}),t={received:{fill:"rgb(255, 50, 50)",stroke:"rgb(255, 180, 180)"},inflicted:{fill:"white",stroke:"#373737"},healed:{fill:"rgb(80, 255, 80)",stroke:"rgb(50, 120, 50)"}},n=Class.extend({DURATION:1e3,init:function(e,n,r,i,s,o){this.id=e,this.value=n,this.duration=s,this.x=r,this.y=i,this.opacity=1,this.lastTime=0,this.speed=100,this.fillColor=t[o].fill,this.strokeColor=t[o].stroke},isTimeToAnimate:function(e){return e-this.lastTime>this.speed},update:function(e){this.isTimeToAnimate(e)&&(this.lastTime=e,this.tick())},tick:function(){this.y-=1,this.opacity-=.07,this.opacity<0&&this.destroy()},onDestroy:function(e){this.destroy_callback=e},destroy:function(){this.destroy_callback&&this.destroy_callback(this.id)}});return e}),define("timer",[],function(){var e=Class.extend({init:function(e,t){this.lastTime=t||0,this.duration=e},isOver:function(e){var t=!1;return e-this.lastTime>this.duration&&(t=!0,this.lastTime=e),t}});return e}),define("bubble",["jquery","timer"],function(e,t){var n=Class.extend({init:function(e,n,r){this.id=e,this.element=n,this.timer=new t(5e3,r)},isOver:function(e){return this.timer.isOver(e)?!0:!1},destroy:function(){e(this.element).remove()},reset:function(e){this.timer.lastTime=e}}),r=Class.extend({init:function(e){this.container=e,this.bubbles={}},getBubbleById:function(e){return e in this.bubbles?this.bubbles[e]:null},create:function(t,r,i){if(this.bubbles[t])this.bubbles[t].reset(i),e("#"+t+" p").html(r);else{var s=e('<div id="'+t+'" class="bubble"><p>'+r+'</p><div class="thingy"></div></div>');e(s).appendTo(this.container),this.bubbles[t]=new n(t,s,i)}},update:function(e){var t=this,n=[];_.each(this.bubbles,function(t){t.isOver(e)&&(t.destroy(),n.push(t.id))}),_.each(n,function(e){delete t.bubbles[e]})},clean:function(){var e=this,t=[];_.each(this.bubbles,function(e){e.destroy(),t.push(e.id)}),_.each(t,function(t){delete e.bubbles[t]}),this.bubbles={}},destroyBubble:function(e){var t=this.getBubbleById(e);t&&(t.destroy(),delete this.bubbles[e])},forEachBubble:function(e){_.each(this.bubbles,function(t){e(t)})}});return r}),define("camera",[],function(){var e=Class.extend({init:function(e){this.renderer=e,this.x=0,this.y=0,this.gridX=0,this.gridY=0,this.offset=.5,this.rescale()},rescale:function(){var e=this.renderer.mobile?1:2;this.gridW=15*e,this.gridH=7*e,log.debug("---------"),log.debug("Factor:"+e),log.debug("W:"+this.gridW+" H:"+this.gridH)},setPosition:function(e,t){this.x=e,this.y=t,this.gridX=Math.floor(e/16),this.gridY=Math.floor(t/16)},setGridPosition:function(e,t){this.gridX=e,this.gridY=t,this.x=this.gridX*16,this.y=this.gridY*16},lookAt:function(e){var t=this.renderer,n=Math.round(e.x-Math.floor(this.gridW/2)*t.tilesize),r=Math.round(e.y-Math.floor(this.gridH/2)*t.tilesize);this.setPosition(n,r)},forEachVisiblePosition:function(e,t){var t=t||0;for(var n=this.gridY-t,r=this.gridY+this.gridH+t*2;n<r;n+=1)for(var i=this.gridX-t,s=this.gridX+this.gridW+t*2;i<s;i+=1)e(i,n)},isVisible:function(e){return this.isVisiblePosition(e.gridX,e.gridY)},isVisiblePosition:function(e,t){return t>=this.gridY&&t<this.gridY+this.gridH&&e>=this.gridX&&e<this.gridX+this.gridW?!0:!1},focusEntity:function(e){var t=this.gridW-2,n=this.gridH-2,r=Math.floor((e.gridX-1)/t)*t,i=Math.floor((e.gridY-1)/n)*n;this.setGridPosition(r,i)}});return e}),define("entity",[],function(){var e=Class.extend({init:function(e,t){var n=this;this.id=e,this.kind=t,this.sprite=null,this.flipSpriteX=!1,this.flipSpriteY=!1,this.animations=null,this.currentAnimation=null,this.shadowOffsetY=0,this.setGridPosition(0,0),this.isLoaded=!1,this.isHighlighted=!1,this.visible=!0,this.isFading=!1,this.setDirty()},setName:function(e){this.name=e},setPosition:function(e,t){this.x=e,this.y=t},setGridPosition:function(e,t){this.gridX=e,this.gridY=t,this.setPosition(e*16,t*16)},setSprite:function(e){if(!e)throw log.error(this.id+" : sprite is null",!0),"Error";if(this.sprite&&this.sprite.name===e.name)return;this.sprite=e,this.normalSprite=this.sprite;if(Types.isMob(this.kind)||Types.isPlayer(this.kind))this.hurtSprite=e.getHurtSprite();this.animations=e.createAnimations(),this.isLoaded=!0,this.ready_func&&this.ready_func()},getSprite:function(){return this.sprite},getSpriteName:function(){return Types.getKindAsString(this.kind)},getAnimationByName:function(e){var t=null;return e in this.animations?t=this.animations[e]:log.error("No animation called "+e),t},setAnimation:function(e,t,n,r){var i=this;if(this.isLoaded){if(this.currentAnimation&&this.currentAnimation.name===e)return;var s=this.sprite,o=this.getAnimationByName(e);o&&(this.currentAnimation=o,e.substr(0,3)==="atk"&&this.currentAnimation.reset(),this.currentAnimation.setSpeed(t),this.currentAnimation.setCount(n?n:0,r||function(){i.idle()}))}else this.log_error("Not ready for animation")},hasShadow:function(){return!1},ready:function(e){this.ready_func=e},clean:function(){this.stopBlinking()},log_info:function(e){log.info("["+this.id+"] "+e)},log_error:function(e){log.error("["+this.id+"] "+e)},setHighlight:function(e){e===!0?(this.sprite=this.sprite.silhouetteSprite,this.isHighlighted=!0):(this.sprite=this.normalSprite,this.isHighlighted=!1)},setVisible:function(e){this.visible=e},isVisible:function(){return this.visible},toggleVisibility:function(){this.visible?this.setVisible(!1):this.setVisible(!0)},getDistanceToEntity:function(e){var t=Math.abs(e.gridX-this.gridX),n=Math.abs(e.gridY-this.gridY);return t>n?t:n},isCloseTo:function(e){var t,n,r,i=!1;return e&&(t=Math.abs(e.gridX-this.gridX),n=Math.abs(e.gridY-this.gridY),t<30&&n<14&&(i=!0)),i},isAdjacent:function(e){var t=!1;return e&&(t=this.getDistanceToEntity(e)>1?!1:!0),t},isAdjacentNonDiagonal:function(e){var t=!1;return this.isAdjacent(e)&&(this.gridX===e.gridX||this.gridY===e.gridY)&&(t=!0),t},isDiagonallyAdjacent:function(e){return this.isAdjacent(e)&&!this.isAdjacentNonDiagonal(e)},forEachAdjacentNonDiagonalPosition:function(e){e(this.gridX-1,this.gridY,Types.Orientations.LEFT),e(this.gridX,this.gridY-1,Types.Orientations.UP),e(this.gridX+1,this.gridY,Types.Orientations.RIGHT),e(this.gridX,this.gridY+1,Types.Orientations.DOWN)},fadeIn:function(e){this.isFading=!0,this.startFadingTime=e},blink:function(e,t){var n=this;this.blinking=setInterval(function(){n.toggleVisibility()},e)},stopBlinking:function(){this.blinking&&clearInterval(this.blinking),this.setVisible(!0)},setDirty:function(){this.isDirty=!0,this.dirty_callback&&this.dirty_callback(this)},onDirty:function(e){this.dirty_callback=e}});return e}),define("item",["entity"],function(e){var t=e.extend({init:function(e,t,n){this._super(e,t),this.itemKind=Types.getKindAsString(t),this.type=n,this.wasDropped=!1},hasShadow:function(){return!0},onLoot:function(e){this.type==="weapon"?e.switchWeapon(this.itemKind):this.type==="armor"&&e.armorloot_callback(this.itemKind)},getSpriteName:function(){return"item-"+this.itemKind},getLootMessage:function(){return this.lootMessage}});return t}),define("transition",[],function(){var e=Class.extend({init:function(){this.startValue=0,this.endValue=0,this.duration=0,this.inProgress=!1},start:function(e,t,n,r,i,s){this.startTime=e,this.updateFunction=t,this.stopFunction=n,this.startValue=r,this.endValue=i,this.duration=s,this.inProgress=!0,this.count=0},step:function(e){if(this.inProgress)if(this.count>0)this.count-=1,log.debug(e+": jumped frame");else{var t=e-this.startTime;t>this.duration&&(t=this.duration);var n=this.endValue-this.startValue,r=this.startValue+n/this.duration*t;r=Math.round(r),t===this.duration||r===this.endValue?(this.stop(),this.stopFunction&&this.stopFunction()):this.updateFunction&&this.updateFunction(r)}},restart:function(e,t,n){this.start(e,this.updateFunction,this.stopFunction,t,n,this.duration),this.step(e)},stop:function(){this.inProgress=!1}});return e}),define("character",["entity","transition","timer"],function(e,t,n){var r=e.extend({init:function(e,n){var r=this;this._super(e,n),this.nextGridX=-1,this.nextGridY=-1,this.orientation=Types.Orientations.DOWN,this.atkSpeed=50,this.moveSpeed=120,this.walkSpeed=100,this.idleSpeed=450,this.setAttackRate(800),this.movement=new t,this.path=null,this.newDestination=null,this.adjacentTiles={},this.target=null,this.unconfirmedTarget=null,this.attackers={},this.hitPoints=0,this.maxHitPoints=0,this.isDead=!1,this.attackingMode=!1,this.followingMode=!1},clean:function(){this.forEachAttacker(function(e){e.disengage(),e.idle()})},setMaxHitPoints:function(e){this.maxHitPoints=e,this.hitPoints=e},setDefaultAnimation:function(){this.idle()},hasWeapon:function(){return!1},hasShadow:function(){return!0},animate:function(e,t,n,r){var i=["atk","walk","idle"];o=this.orientation;if(!this.currentAnimation||this.currentAnimation.name!=="death")this.flipSpriteX=!1,this.flipSpriteY=!1,_.indexOf(i,e)>=0&&(e+="_"+(o===Types.Orientations.LEFT?"right":Types.getOrientationAsString(o)),this.flipSpriteX=this.orientation===Types.Orientations.LEFT?!0:!1),this.setAnimation(e,t,n,r)},turnTo:function(e){this.orientation=e,this.idle()},setOrientation:function(e){e&&(this.orientation=e)},idle:function(e){this.setOrientation(e),this.animate("idle",this.idleSpeed)},hit:function(e){this.setOrientation(e),this.animate("atk",this.atkSpeed,1)},walk:function(e){this.setOrientation(e),this.animate("walk",this.walkSpeed)},moveTo_:function(e,t,n){this.destination={gridX:e,gridY:t},this.adjacentTiles={};if(this.isMoving())this.continueTo(e,t);else{var r=this.requestPathfindingTo(e,t);this.followPath(r)}},requestPathfindingTo:function(e,t){return this.request_path_callback?this.request_path_callback(e,t):(log.error(this.id+" couldn't request pathfinding to "+e+", "+t),[])},onRequestPath:function(e){this.request_path_callback=e},onStartPathing:function(e){this.start_pathing_callback=e},onStopPathing:function(e){this.stop_pathing_callback=e},followPath:function(e){e.length>1&&(this.path=e,this.step=0,this.followingMode&&e.pop(),this.start_pathing_callback&&this.start_pathing_callback(e),this.nextStep())},continueTo:function(e,t){this.newDestination={x:e,y:t}},updateMovement:function(){var e=this.path,t=this.step;e[t][0]<e[t-1][0]&&this.walk(Types.Orientations.LEFT),e[t][0]>e[t-1][0]&&this.walk(Types.Orientations.RIGHT),e[t][1]<e[t-1][1]&&this.walk(Types.Orientations.UP),e[t][1]>e[t-1][1]&&this.walk(Types.Orientations.DOWN)},updatePositionOnGrid:function(){this.setGridPosition(this.path[this.step][0],this.path[this.step][1])},nextStep:function(){var e=!1,t,n,r;this.isMoving()&&(this.before_step_callback&&this.before_step_callback(),this.updatePositionOnGrid(),this.checkAggro(),this.interrupted?(e=!0,this.interrupted=!1):(this.hasNextStep()&&(this.nextGridX=this.path[this.step+1][0],this.nextGridY=this.path[this.step+1][1]),this.step_callback&&this.step_callback(),this.hasChangedItsPath()?(t=this.newDestination.x,n=this.newDestination.y,r=this.requestPathfindingTo(t,n),this.newDestination=null,r.length<2?e=!0:this.followPath(r)):this.hasNextStep()?(this.step+=1,this.updateMovement()):e=!0),e&&(this.path=null,this.idle(),this.stop_pathing_callback&&this.stop_pathing_callback(this.gridX,this.gridY)))},onBeforeStep:function(e){this.before_step_callback=e},onStep:function(e){this.step_callback=e},isMoving:function(){return this.path!==null},hasNextStep:function(){return this.path.length-1>this.step},hasChangedItsPath:function(){return this.newDestination!==null},isNear:function(e,t){var n,r,i=!1;return n=Math.abs(this.gridX-e.gridX),r=Math.abs(this.gridY-e.gridY),n<=t&&r<=t&&(i=!0),i},onAggro:function(e){this.aggro_callback=e},onCheckAggro:function(e){this.checkaggro_callback=e},checkAggro:function(){this.checkaggro_callback&&this.checkaggro_callback()},aggro:function(e){this.aggro_callback&&this.aggro_callback(e)},onDeath:function(e){this.death_callback=e},lookAtTarget:function(){this.target&&this.turnTo(this.getOrientationTo(this.target))},go:function(e,t){this.isAttacking()?this.disengage():this.followingMode&&(this.followingMode=!1,this.target=null),this.moveTo_(e,t)},follow:function(e){e&&(this.followingMode=!0,this.moveTo_(e.gridX,e.gridY))},stop:function(){this.isMoving()&&(this.interrupted=!0)},engage:function(e){this.attackingMode=!0,this.setTarget(e),this.follow(e)},disengage:function(){this.attackingMode=!1,this.followingMode=!1,this.removeTarget()},isAttacking:function(){return this.attackingMode},getOrientationTo:function(e){return this.gridX<e.gridX?Types.Orientations.RIGHT:this.gridX>e.gridX?Types.Orientations.LEFT:this.gridY>e.gridY?Types.Orientations.UP:Types.Orientations.DOWN},isAttackedBy:function(e){return e.id in this.attackers},addAttacker:function(e){this.isAttackedBy(e)?log.error(this.id+" is already attacked by "+e.id):this.attackers[e.id]=e},removeAttacker:function(e){this.isAttackedBy(e)?delete this.attackers[e.id]:log.error(this.id+" is not attacked by "+e.id)},forEachAttacker:function(e){_.each(this.attackers,function(t){e(t)})},setTarget:function(e){this.target!==e?(this.hasTarget()&&this.removeTarget(),this.unconfirmedTarget=null,this.target=e):log.debug(e.id+" is already the target of "+this.id)},removeTarget:function(){var e=this;this.target&&(this.target instanceof r&&this.target.removeAttacker(this),this.target=null)},hasTarget:function(){return this.target!==null},waitToAttack:function(e){this.unconfirmedTarget=e},isWaitingToAttack:function(e){return this.unconfirmedTarget===e},canAttack:function(e){return this.canReachTarget()&&this.attackCooldown.isOver(e)?!0:!1},canReachTarget:function(){return this.hasTarget()&&this.isAdjacentNonDiagonal(this.target)?!0:!1},die:function(){this.removeTarget(),this.isDead=!0,this.death_callback&&this.death_callback()},onHasMoved:function(e){this.hasmoved_callback=e},hasMoved:function(){this.setDirty(),this.hasmoved_callback&&this.hasmoved_callback(this)},hurt:function(){var e=this;this.stopHurting(),this.sprite=this.hurtSprite,this.hurting=setTimeout(this.stopHurting.bind(this),75)},stopHurting:function(){this.sprite=this.normalSprite,clearTimeout(this.hurting)},setAttackRate:function(e){this.attackCooldown=new n(e)}});return r}),define("exceptions",[],function(){var e={LootException:Class.extend({init:function(e){this.message=e}})};return e}),define("player",["character","exceptions"],function(e,t){var n=e.extend({MAX_LEVEL:10,init:function(e,t,n){this._super(e,n),this.name=t,this.nameOffsetY=-10,this.spriteName="clotharmor",this.weaponName="sword1",this.isLootMoving=!1,this.isSwitchingWeapon=!0},loot:function(e){if(e){var n,r,i,s;this.currentArmorSprite?s=this.currentArmorSprite.name:s=this.spriteName,e.type==="armor"?(n=Types.getArmorRank(e.kind),r=Types.getArmorRank(Types.getKindFromString(s)),i="You are wearing a better armor"):e.type==="weapon"&&(n=Types.getWeaponRank(e.kind),r=Types.getWeaponRank(Types.getKindFromString(this.weaponName)),i="You are wielding a better weapon");if(n&&r){if(n===r)throw new t.LootException("You already have this "+e.type);if(n<=r)throw new t.LootException(i)}log.info("Player "+this.id+" has looted "+e.id),Types.isArmor(e.kind)&&this.invincible&&this.stopInvincibility(),e.onLoot(this)}},isMovingToLoot:function(){return this.isLootMoving},getSpriteName:function(){return this.spriteName},setSpriteName:function(e){this.spriteName=e},getArmorName:function(){var e=this.getArmorSprite();return e.id},getArmorSprite:function(){return this.invincible?this.currentArmorSprite:this.sprite},getWeaponName:function(){return this.weaponName},setWeaponName:function(e){this.weaponName=e},hasWeapon:function(){return this.weaponName!==null},switchWeapon:function(e){var t=14,n=!1,r=this,i=function(){return n=!n,n};if(e!==this.getWeaponName()){this.isSwitchingWeapon&&clearInterval(s),this.switchingWeapon=!0;var s=setInterval(function(){i()?r.setWeaponName(e):r.setWeaponName(null),t-=1,t===1&&(clearInterval(s),r.switchingWeapon=!1,r.switch_callback&&r.switch_callback())},90)}},switchArmor:function(e){var t=14,n=!1,r=this,i=function(){return n=!n,n};if(e&&e.id!==this.getSpriteName()){this.isSwitchingArmor&&clearInterval(s),this.isSwitchingArmor=!0,r.setSprite(e),r.setSpriteName(e.id);var s=setInterval(function(){r.setVisible(i()),t-=1,t===1&&(clearInterval(s),r.isSwitchingArmor=!1,r.switch_callback&&r.switch_callback())},90)}},onArmorLoot:function(e){this.armorloot_callback=e},onSwitchItem:function(e){this.switch_callback=e},onInvincible:function(e){this.invincible_callback=e},startInvincibility:function(){var e=this;this.invincible?this.invincibleTimeout&&clearTimeout(this.invincibleTimeout):(this.currentArmorSprite=this.getSprite(),this.invincible=!0,this.invincible_callback()),this.invincibleTimeout=setTimeout(function(){e.stopInvincibility(),e.idle()},15e3)},stopInvincibility:function(){this.invincible_callback(),this.invincible=!1,this.currentArmorSprite&&(this.setSprite(this.currentArmorSprite),this.setSpriteName(this.currentArmorSprite.id),this.currentArmorSprite=null),this.invincibleTimeout&&clearTimeout(this.invincibleTimeout)}});return n}),define("renderer",["camera","item","character","player","timer"],function(e,t,n,r,i){var s=Class.extend({init:function(e,t,n,r){this.game=e,this.context=t&&t.getContext?t.getContext("2d"):null,this.background=n&&n.getContext?n.getContext("2d"):null,this.foreground=r&&r.getContext?r.getContext("2d"):null,this.canvas=t,this.backcanvas=n,this.forecanvas=r,this.initFPS(),this.tilesize=16,this.upscaledRendering=this.context.mozImageSmoothingEnabled!==undefined,this.supportsSilhouettes=this.upscaledRendering,this.rescale(this.getScaleFactor()),this.lastTime=new Date,this.frameCount=0,this.maxFPS=this.FPS,this.realFPS=0,this.isDebugInfoVisible=!1,this.animatedTileCount=0,this.highTileCount=0,this.tablet=Detect.isTablet(window.innerWidth),this.fixFlickeringTimer=new i(100)},getWidth:function(){return this.canvas.width},getHeight:function(){return this.canvas.height},setTileset:function(e){this.tileset=e},getScaleFactor:function(){var e=window.innerWidth,t=window.innerHeight,n;return this.mobile=!1,e<=1e3?(n=2,this.mobile=!0):e<=1500||t<=870?n=2:n=3,n},rescale:function(e){this.scale=this.getScaleFactor(),this.createCamera(),this.context.mozImageSmoothingEnabled=!1,this.background.mozImageSmoothingEnabled=!1,this.foreground.mozImageSmoothingEnabled=!1,this.initFont(),this.initFPS(),!this.upscaledRendering&&this.game.map&&this.game.map.tilesets&&this.setTileset(this.game.map.tilesets[this.scale-1]),this.game.renderer&&this.game.setSpriteScale(this.scale)},createCamera:function(){this.camera=new e(this),this.camera.rescale(),this.canvas.width=this.camera.gridW*this.tilesize*this.scale,this.canvas.height=this.camera.gridH*this.tilesize*this.scale,log.debug("#entities set to "+this.canvas.width+" x "+this.canvas.height),this.backcanvas.width=this.canvas.width,this.backcanvas.height=this.canvas.height,log.debug("#background set to "+this.backcanvas.width+" x "+this.backcanvas.height),this.forecanvas.width=this.canvas.width,this.forecanvas.height=this.canvas.height,log.debug("#foreground set to "+this.forecanvas.width+" x "+this.forecanvas.height)},initFPS:function(){this.FPS=this.mobile?50:50},initFont:function(){var e;switch(this.scale){case 1:e=10;break;case 2:e=Detect.isWindows()?10:13;break;case 3:e=20}this.setFontSize(e)},setFontSize:function(e){var t=e+"px GraphicPixel";this.context.font=t,this.background.font=t},drawText:function(e,t,n,r,i,s){var o=this.context,u;switch(this.scale){case 1:u=3;break;case 2:u=3;break;case 3:u=5}e&&t&&n&&(o.save(),r&&(o.textAlign="center"),o.strokeStyle=s||"#373737",o.lineWidth=u,o.strokeText(e,t,n),o.fillStyle=i||"white",o.fillText(e,t,n),o.restore())},drawCellRect:function(e,t,n){this.context.save(),this.context.lineWidth=2*this.scale,this.context.strokeStyle=n,this.context.translate(e+2,t+2),this.context.strokeRect(0,0,this.tilesize*this.scale-4,this.tilesize*this.scale-4),this.context.restore()},drawCellHighlight:function(e,t,n){var r=this.scale,i=this.tilesize,s=e*i*r,o=t*i*r;this.drawCellRect(s,o,n)},drawTargetCell:function(){var e=this.game.getMouseGridPosition();this.game.targetCellVisible&&(e.x!==this.game.selectedX||e.y!==this.game.selectedY)&&this.drawCellHighlight(e.x,e.y,this.game.targetColor)},drawAttackTargetCell:function(){var e=this.game.getMouseGridPosition(),t=this.game.getEntityAt(e.x,e.y),n=this.scale;t&&this.drawCellRect(t.x*n,t.y*n,"rgba(255, 0, 0, 0.5)")},drawOccupiedCells:function(){var e=this.game.entityGrid;if(e)for(var t=0;t<e.length;t+=1)for(var n=0;n<e[t].length;n+=1)_.isNull(e[t][n])||this.drawCellHighlight(t,n,"rgba(50, 50, 255, 0.5)")},drawPathingCells:function(){var e=this.game.pathingGrid;if(e&&this.game.debugPathing)for(var t=0;t<e.length;t+=1)for(var n=0;n<e[t].length;n+=1)e[t][n]===1&&this.game.camera.isVisiblePosition(n,t)&&this.drawCellHighlight(n,t,"rgba(50, 50, 255, 0.5)")},drawSelectedCell:function(){var e=this.game.cursors.target,t=this.game.targetAnimation,n=this.upscaledRendering?1:this.scale,r=this.upscaledRendering?this.scale:1;if(this.game.selectedCellVisible)if(this.mobile||this.tablet){if(this.game.drawTarget){var i=this.game.selectedX,s=this.game.selectedY;this.drawCellHighlight(this.game.selectedX,this.game.selectedY,"rgb(51, 255, 0)"),this.lastTargetPos={x:i,y:s},this.game.drawTarget=!1}}else if(e&&t){var o=t.currentFrame,u=this.scale,i=o.x*n,s=o.y*n,a=e.width*n,f=e.height*n,l=16,c=this.game.selectedX*l*u,h=this.game.selectedY*l*u,p=a*r,d=f*r;this.context.save(),this.context.translate(c,h),this.context.drawImage(e.image,i,s,a,f,0,0,p,d),this.context.restore()}},clearScaledRect:function(e,t,n,r,i){var s=this.scale;e.clearRect(t*s,n*s,r*s,i*s)},drawCursor:function(){var e=this.game.mouse.x,t=this.game.mouse.y,n=this.scale,r=this.upscaledRendering?1:this.scale;this.context.save(),this.game.currentCursor&&this.game.currentCursor.isLoaded&&this.context.drawImage(this.game.currentCursor.image,0,0,14*r,14*r,e,t,14*n,14*n),this.context.restore()},drawScaledImage:function(e,t,n,r,i,s,o,u){var a=this.upscaledRendering?1:this.scale;_.each(arguments,function(e){if(_.isUndefined(e)||_.isNaN(e)||_.isNull(e)||e<0)throw log.error("x:"+n+" y:"+r+" w:"+i+" h:"+s+" dx:"+o+" dy:"+u,!0),Error("A problem occured when trying to draw on the canvas")}),e.drawImage(t,n*a,r*a,i*a,s*a,o*this.scale,u*this.scale,i*this.scale,s*this.scale)},drawTile:function(e,t,n,r,i,s){var u=this.upscaledRendering?1:this.scale;t!==-1&&this.drawScaledImage(e,n,o(t+1,r/u)*this.tilesize,Math.floor(t/(r/u))*this.tilesize,this.tilesize,this.tilesize,o(s+1,i)*this.tilesize,Math.floor(s/i)*this.tilesize)},clearTile:function(e,t,n){var r=this.scale,i=this.tilesize,s=o(n+1,t)*i*r,u=Math.floor(n/t)*i*r,a=i*r,f=a;e.clearRect(s,u,f,a)},drawEntity:function(e){var r=e.sprite,i=this.game.shadows.small,s=e.currentAnimation,o=this.upscaledRendering?1:this.scale,u=this.upscaledRendering?this.scale:1;if(s&&r){var a=s.currentFrame,f=this.scale,l=a.x*o,c=a.y*o,h=r.width*o,p=r.height*o,d=r.offsetX*f,v=r.offsetY*f,m=e.x*f,g=e.y*f,y=h*u,b=p*u;e.isFading&&(this.context.save(),this.context.globalAlpha=e.fadingAlpha),!this.mobile&&!this.tablet&&this.drawEntityName(e),this.context.save(),e.flipSpriteX?(this.context.translate(m+this.tilesize*f,g),this.context.scale(-1,1)):e.flipSpriteY?(this.context.translate(m,g+b),this.context.scale(1,-1)):this.context.translate(m,g);if(e.isVisible()){e.hasShadow()&&this.context.drawImage(i.image,0,0,i.width*o,i.height*o,0,e.shadowOffsetY*u,i.width*o*u,i.height*o*u),this.context.drawImage(r.image,l,c,h,p,d,v,y,b);if(e instanceof t&&e.kind!==Types.Entities.CAKE){var w=this.game.sprites.sparks,s=this.game.sparksAnimation,a=s.currentFrame,E=w.width*a.index*o,S=w.height*s.row*o,x=w.width*o,T=w.width*o;this.context.drawImage(w.image,E,S,x,T,w.offsetX*f,w.offsetY*f,x*u,T*u)}}if(e instanceof n&&!e.isDead&&e.hasWeapon()){var N=this.game.sprites[e.getWeaponName()];if(N){var C=N.animationData[s.name],k=a.index<C.length?a.index:a.index%C.length;wx=N.width*k*o,wy=N.height*s.row*o,ww=N.width*o,wh=N.height*o,this.context.drawImage(N.image,wx,wy,ww,wh,N.offsetX*f,N.offsetY*f,ww*u,wh*u)}}this.context.restore(),e.isFading&&this.context.restore()}},drawEntities:function(e){var t=this;this.game.forEachVisibleEntityByDepth(function(n){n.isLoaded&&(e?n.isDirty&&(t.drawEntity(n),n.isDirty=!1,n.oldDirtyRect=n.dirtyRect,n.dirtyRect=null):t.drawEntity(n))})},drawDirtyEntities:function(){this.drawEntities(!0)},clearDirtyRect:function(e){this.context.clearRect(e.x,e.y,e.w,e.h)},clearDirtyRects:function(){var e=this,t=0;this.game.forEachVisibleEntityByDepth(function(n){n.isDirty&&n.oldDirtyRect&&(e.clearDirtyRect(n.oldDirtyRect),t+=1)}),this.game.forEachAnimatedTile(function(n){n.isDirty&&(e.clearDirtyRect(n.dirtyRect),t+=1)});if(this.game.clearTarget&&this.lastTargetPos){var n=this.lastTargetPos;rect=this.getTargetBoundingRect(n.x,n.y),this.clearDirtyRect(rect),this.game.clearTarget=!1,t+=1}t>0},getEntityBoundingRect:function(e){var t={},n=this.scale,i;if(e instanceof r&&e.hasWeapon()){var s=this.game.sprites[e.getWeaponName()];i=s}else i=e.sprite;return i&&(t.x=(e.x+i.offsetX-this.camera.x)*n,t.y=(e.y+i.offsetY-this.camera.y)*n,t.w=i.width*n,t.h=i.height*n,t.left=t.x,t.right=t.x+t.w,t.top=t.y,t.bottom=t.y+t.h),t},getTileBoundingRect:function(e){var t={},n=this.game.map.width,r=this.scale,i=this.tilesize,s=e.index;return t.x=(o(s+1,n)*i-this.camera.x)*r,t.y=(Math.floor(s/n)*i-this.camera.y)*r,t.w=i*r,t.h=i*r,t.left=t.x,t.right=t.x+t.w,t.top=t.y,t.bottom=t.y+t.h,t},getTargetBoundingRect:function(e,t){var n={},r=this.scale,i=this.tilesize,s=e||this.game.selectedX,o=t||this.game.selectedY;return n.x=(s*i-this.camera.x)*r,n.y=(o*i-this.camera.y)*r,n.w=i*r,n.h=i*r,n.left=n.x,n.right=n.x+n.w,n.top=n.y,n.bottom=n.y+n.h,n},isIntersecting:function(e,t){return!(t.left>e.right||t.right<e.left||t.top>e.bottom||t.bottom<e.top)},drawEntityName:function(e){this.context.save();if(e.name&&e instanceof r){var t=e.id===this.game.playerId?"#fcda5c":"white";this.drawText(e.name,(e.x+8)*this.scale,(e.y+e.nameOffsetY)*this.scale,!0,t)}this.context.restore()},drawTerrain:function(){var e=this,t=this.game.map,n=this.tileset.width/t.tilesize;this.game.forEachVisibleTile(function(r,i){!t.isHighTile(r)&&!t.isAnimatedTile(r)&&e.drawTile(e.background,r,e.tileset,n,t.width,i)},1)},drawAnimatedTiles:function(e){var t=this,n=this.game.map,r=this.tileset.width/n.tilesize;this.animatedTileCount=0,this.game.forEachAnimatedTile(function(i){e?i.isDirty&&(t.drawTile(t.context,i.id,t.tileset,r,n.width,i.index),i.isDirty=!1):(t.drawTile(t.context,i.id,t.tileset,r,n.width,i.index),t.animatedTileCount+=1)})},drawDirtyAnimatedTiles:function(){this.drawAnimatedTiles(!0)},drawHighTiles:function(e){var t=this,n=this.game.map,r=this.tileset.width/n.tilesize;this.highTileCount=0,this.game.forEachVisibleTile(function(i,s){n.isHighTile(i)&&(t.drawTile(e,i,t.tileset,r,n.width,s),t.highTileCount+=1)},1)},drawBackground:function(e,t){e.fillStyle=t,e.fillRect(0,0,this.canvas.width,this.canvas.height)},drawFPS:function(){var e=new Date,t=e.getTime()-this.lastTime.getTime();t>=1e3&&(this.realFPS=this.frameCount,this.frameCount=0,this.lastTime=e),this.frameCount++,this.drawText("FPS: "+this.realFPS,30,30,!1)},drawDebugInfo:function(){this.isDebugInfoVisible&&(this.drawFPS(),this.drawText("A: "+this.animatedTileCount,100,30,!1),this.drawText("H: "+this.highTileCount,140,30,!1))},drawCombatInfo:function(){var e=this;switch(this.scale){case 2:this.setFontSize(20);break;case 3:this.setFontSize(30)}this.game.infoManager.forEachInfo(function(t){e.context.save(),e.context.globalAlpha=t.opacity,e.drawText(t.value,(t.x+8)*e.scale,Math.floor(t.y*e.scale),!0,t.fillColor,t.strokeColor),e.context.restore()}),this.initFont()},setCameraView:function(e){e.translate(-this.camera.x*this.scale,-this.camera.y*this.scale)},clearScreen:function(e){e.clearRect(0,0,this.canvas.width,this.canvas.height)},getPlayerImage:function(){var e=document.createElement("canvas"),t=e.getContext("2d"),n=this.upscaledRendering?1:this.scale,r=this.game.player,i=r.getArmorSprite(),s=i.animationData.idle_down,o=s.row,u=i.width*n,a=i.height*n,f=o*a,l=this.game.sprites[this.game.player.getWeaponName()],c=l.width*n,h=l.height*n,p=h*o,d=(l.offsetX-i.offsetX)*n,v=(l.offsetY-i.offsetY)*n,m=this.game.shadows.small,g=m.width*n,y=m.height*n,b=-i.offsetX*n;return oy=-i.offsetY*n,e.width=u,e.height=a,t.clearRect(0,0,u,a),t.drawImage(m.image,0,0,g,y,b,oy,g,y),t.drawImage(i.image,0,f,u,a,0,0,u,a),t.drawImage(l.image,0,p,c,h,d,v,c,h),e.toDataURL("image/png")},renderStaticCanvases:function(){this.background.save(),this.setCameraView(this.background),this.drawTerrain(),this.background.restore();if(this.mobile||this.tablet)this.clearScreen(this.foreground),this.foreground.save(),this.setCameraView(this.foreground),this.drawHighTiles(this.foreground),this.foreground.restore()},renderFrame:function(){this.mobile||this.tablet?this.renderFrameMobile():this.renderFrameDesktop()},renderFrameDesktop:function(){this.clearScreen(this.context),this.context.save(),this.setCameraView(this.context),this.drawAnimatedTiles(),this.game.started&&(this.drawSelectedCell(),this.drawTargetCell()),this.drawPathingCells(),this.drawEntities(),this.drawCombatInfo(),this.drawHighTiles(this.context),this.context.restore(),this.drawCursor(),this.drawDebugInfo()},renderFrameMobile:function(){this.clearDirtyRects(),this.preventFlickeringBug(),this.context.save(),this.setCameraView(this.context),this.drawDirtyAnimatedTiles(),this.drawSelectedCell(),this.drawDirtyEntities(),this.context.restore()},preventFlickeringBug:function(){this.fixFlickeringTimer.isOver(this.game.currentTime)&&(this.background.fillRect(0,0,0,0),this.context.fillRect(0,0,0,0),this.foreground.fillRect(0,0,0,0))}}),o=function(e,t){return e==0?0:e%t==0?t-1:e%t-1};return s}),define("area",[],function(){var e=Class.extend({init:function(e,t,n,r){this.x=e,this.y=t,this.width=n,this.height=r},contains:function(e){return e?e.gridX>=this.x&&e.gridY>=this.y&&e.gridX<this.x+this.width&&e.gridY<this.y+this.height:!1}});return e}),define("map",["jquery","area"],function(e,t){var n=Class.extend({init:function(e,t){this.game=t,this.data=[],this.isLoaded=!1,this.tilesetsLoaded=!1,this.mapLoaded=!1,this.loadMultiTilesheets=e;var n=!this.game.renderer.mobile&&!this.game.renderer.tablet;this._loadMap(n),this._initTilesets()},_checkReady:function(){this.tilesetsLoaded&&this.mapLoaded&&(this.isLoaded=!0,this.ready_func&&this.ready_func())},_loadMap:function(t){var n=this,r="maps/world_client.json";if(t){log.info("Loading map with web worker.");var i=new Worker("js/mapworker.js");i.postMessage(1),i.onmessage=function(e){var t=e.data;n._initMap(t),n.grid=t.grid,n.plateauGrid=t.plateauGrid,n.mapLoaded=!0,n._checkReady()}}else log.info("Loading map via Ajax."),e.get(r,function(e){n._initMap(e),n._generateCollisionGrid(),n._generatePlateauGrid(),n.mapLoaded=!0,n._checkReady()},"json")},_initTilesets:function(){var e,t,n;this.loadMultiTilesheets?this.game.renderer.mobile||this.game.renderer.tablet?(this.tilesetCount=1,t=this._loadTileset("img/2/tilesheet.png")):(this.tilesetCount=2,t=this._loadTileset("img/2/tilesheet.png"),n=this._loadTileset("img/3/tilesheet.png")):(this.tilesetCount=1,e=this._loadTileset("img/1/tilesheet.png")),this.tilesets=[e,t,n]},_initMap:function(e){this.width=e.width,this.height=e.height,this.tilesize=e.tilesize,this.data=e.data,this.blocking=e.blocking||[],this.plateau=e.plateau||[],this.musicAreas=e.musicAreas||[],this.collisions=e.collisions,this.high=e.high,this.animated=e.animated,this.doors=this._getDoors(e),this.checkpoints=this._getCheckpoints(e)},_getDoors:function(e){var t={},n=this;return _.each(e.doors,function(e){var r;switch(e.to){case"u":r=Types.Orientations.UP;break;case"d":r=Types.Orientations.DOWN;break;case"l":r=Types.Orientations.LEFT;break;case"r":r=Types.Orientations.RIGHT;break;default:r=Types.Orientations.DOWN}t[n.GridPositionToTileIndex(e.x,e.y)]={x:e.tx,y:e.ty,orientation:r,cameraX:e.tcx,cameraY:e.tcy,portal:e.p===1}}),t},_loadTileset:function(e){var t=this,n=new Image;return n.src=e,log.info("Loading tileset: "+e),n.onload=function(){if(n.width%t.tilesize>0)throw Error("Tileset size should be a multiple of "+t.tilesize);log.info("Map tileset loaded."),t.tilesetCount-=1,t.tilesetCount===0&&(log.debug("All map tilesets loaded."),t.tilesetsLoaded=!0,t._checkReady())},n},ready:function(e){this.ready_func=e},tileIndexToGridPosition:function(e){var t=0,n=0,r=function(e,t){return e==0?0:e%t==0?t-1:e%t-1};return e-=1,t=r(e+1,this.width),n=Math.floor(e/this.width),{x:t,y:n}},GridPositionToTileIndex:function(e,t){return t*this.width+e+1},isColliding:function(e,t){return this.isOutOfBounds(e,t)||!this.grid?!1:this.grid[t][e]===1},isPlateau:function(e,t){return this.isOutOfBounds(e,t)||!this.plateauGrid?!1:this.plateauGrid[t][e]===1},_generateCollisionGrid:function(){var e=0,t=this;this.grid=[];for(var n,r=0;r<this.height;r++){this.grid[r]=[];for(n=0;n<this.width;n++)this.grid[r][n]=0}_.each(this.collisions,function(e){var n=t.tileIndexToGridPosition(e+1);t.grid[n.y][n.x]=1}),_.each(this.blocking,function(e){var n=t.tileIndexToGridPosition(e+1);t.grid[n.y]!==undefined&&(t.grid[n.y][n.x]=1)}),log.info("Collision grid generated.")},_generatePlateauGrid:function(){var e=0;this.plateauGrid=[];for(var t,n=0;n<this.height;n++){this.plateauGrid[n]=[];for(t=0;t<this.width;t++)_.include(this.plateau,e)?this.plateauGrid[n][t]=1:this.plateauGrid[n][t]=0,e+=1}log.info("Plateau grid generated.")},isOutOfBounds:function(e,t){return isInt(e)&&isInt(t)&&(e<0||e>=this.width||t<0||t>=this.height)},isHighTile:function(e){return _.indexOf(this.high,e+1)>=0},isAnimatedTile:function(e){return e+1 in this.animated},getTileAnimationLength:function(e){return this.animated[e+1].l},getTileAnimationDelay:function(e){var t=this.animated[e+1];return t.d?t.d:100},isDoor:function(e,t){return this.doors[this.GridPositionToTileIndex(e,t)]!==undefined},getDoorDestination:function(e,t){return this.doors[this.GridPositionToTileIndex(e,t)]},_getCheckpoints:function(e){var n=[];return _.each(e.checkpoints,function(e){var r=new t(e.x,e.y,e.w,e.h);r.id=e.id,n.push(r)}),n},getCurrentCheckpoint:function(e){return _.detect(this.checkpoints,function(t){return t.contains(e)})}});return n}),define("animation",[],function(){var e=Class.extend({init:function(e,t,n,r,i){this.name=e,this.length=t,this.row=n,this.width=r,this.height=i,this.reset()},tick:function(){var e=this.currentFrame.index;e=e<this.length-1?e+1:0;if(this.count>0&&e===0){this.count-=1;if(this.count===0){this.currentFrame.index=0,this.endcount_callback();return}}this.currentFrame.x=this.width*e,this.currentFrame.y=this.height*this.row,this.currentFrame.index=e},setSpeed:function(e){this.speed=e},setCount:function(e,t){this.count=e,this.endcount_callback=t},isTimeToAnimate:function(e){return e-this.lastTime>this.speed},update:function(e){return this.lastTime===0&&this.name.substr(0,3)==="atk"&&(this.lastTime=e),this.isTimeToAnimate(e)?(this.lastTime=e,this.tick(),!0):!1},reset:function(){this.lastTime=0,this.currentFrame={index:0,x:0,y:this.row*this.height}}});return e}),function(){var e=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],t=/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,n=/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,r=typeof location!="undefined"&&location.href,i=[];define("text",[],function(){var s,o,u;return typeof window!="undefined"&&window.navigator&&window.document?o=function(e,t){var n=s.createXhr();n.open("GET",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)}:typeof process!="undefined"&&process.versions&&process.versions.node?(u=require.nodeRequire("fs"),o=function(e,t){t(u.readFileSync(e,"utf8"))}):typeof Packages!="undefined"&&(o=function(e,t){var n=new java.io.File(e),r=java.lang.System.getProperty("line.separator"),n=new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(n),"utf-8")),i,s,o="";try{i=new java.lang.StringBuffer,(s=n.readLine())&&s.length()&&s.charAt(0)===65279&&(s=s.substring(1));for(i.append(s);(s=n.readLine())!==null;)i.append(r),i.append(s);o=String(i.toString())}finally{n.close()}t(o)}),s={version:"0.26.0",strip:function(e){if(e){var e=e.replace(t,""),r=e.match(n);r&&(e=r[1])}else e="";return e},jsEscape:function(e){return e.replace(/(['\\])/g,"\\$1").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r")},createXhr:function(){var t,n,r;if(typeof XMLHttpRequest!="undefined")return new XMLHttpRequest;for(n=0;n<3;n++){r=e[n];try{t=new ActiveXObject(r)}catch(i){}if(t){e=[r];break}}if(!t)throw Error("createXhr(): XMLHttpRequest not available");return t},get:o,parseName:function(e){var t=!1,n=e.indexOf("."),r=e.substring(0,n),e=e.substring(n+1,e.length),n=e.indexOf("!");return n!==-1&&(t=e.substring(n+1,e.length),t=t==="strip",e=e.substring(0,n)),{moduleName:r,ext:e,strip:t}},xdRegExp:/^((\w+)\:)?\/\/([^\/\\]+)/,canUseXhr:function(e,t,n,r){var i=s.xdRegExp.exec(e),o;return i?(e=i[2],i=i[3],i=i.split(":"),o=i[1],i=i[0],(!e||e===t)&&(!i||i===n)&&(!o&&!i||o===r)):!0},finishLoad:function(e,t,n,r,o){n=t?s.strip(n):n,o.isBuild&&o.inlineText&&(i[e]=n),r(n)},load:function(e,t,n,i){var o=s.parseName(e),u=o.moduleName+"."+o.ext,a=t.toUrl(u);!r||s.canUseXhr(a)?s.get(a,function(t){s.finishLoad(e,o.strip,t,n,i)}):t([u],function(e){s.finishLoad(o.moduleName+"."+o.ext,o.strip,e,n,i)})},write:function(e,t,n){if(t in i){var r=s.jsEscape(i[t]);n("define('"+e+"!"+t+"', function () { return '"+r+"';});\n")}},writeFile:function(e,t,n,r,i){var t=s.parseName(t),o=t.moduleName+"."+t.ext,u=n.toUrl(t.moduleName+"."+t.ext)+".js";s.load(o,n,function(){s.write(e,o,function(e){r(u,e)},i)},i)}}})}(),define("text!../sprites/agent.json",function(){return'{\r "id": "agent",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/arrow.json",function(){return'{\n "id": "arrow",\n "width": 14,\n "height": 14,\n "animations": {\n "idle_down": {\n "length": 1,\n "row": 0\n }\n }\n}\n'}),define("text!../sprites/axe.json",function(){return'{\r "id": "axe",\r "width": 48,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -16,\r "offset_y": -20\r}\r'}),define("text!../sprites/bat.json",function(){return'{\r "id": "bat",\r "width": 32,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 5,\r "row": 1\r },\r "idle_right": {\r "length": 5,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 5,\r "row": 4\r },\r "idle_up": {\r "length": 5,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 5,\r "row": 7\r },\r "idle_down": {\r "length": 5,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -24\r}\r'}),define("text!../sprites/beachnpc.json",function(){return'{\r "id": "beachnpc",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/bluesword.json",function(){return'{\r "id": "bluesword",\r "width": 48,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -16,\r "offset_y": -20\r}\r'}),define("text!../sprites/boss.json",function(){return'{\r "id": "boss",\r "width": 64,\r "height": 72,\r "animations": {\r "atk_right": {\r "length": 6,\r "row": 0\r },\r "walk_right": {\r "length": 3,\r "row": 1\r },\r "idle_right": {\r "length": 4,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 4,\r "row": 5\r },\r "atk_down": {\r "length": 6,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 4,\r "row": 8\r },\r "Group 5": {\r "length": 3,\r "row": 9\r }\r },\r "offset_x": -24,\r "offset_y": -36\r}\r'}),define("text!../sprites/chest.json",function(){return'{\r "id": "chest",\r "width": 16,\r "height": 16,\r "animations": {\r "idle_down": {\r "length": 1,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/clotharmor.json",function(){return'{\r "id": "clotharmor",\r "width": 32,\r "height": 32,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/coder.json",function(){return'{\r "id": "coder",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -7\r}\r'}),define("text!../sprites/crab.json",function(){return'{\r "id": "crab",\r "width": 32,\r "height": 32,\r "animations": {\r "death": {\r "length": 8,\r "row": 0\r },\r "atk_right": {\r "length": 7,\r "row": 1\r },\r "walk_right": {\r "length": 6,\r "row": 2\r },\r "idle_right": {\r "length": 4,\r "row": 3\r },\r "atk_up": {\r "length": 8,\r "row": 4\r },\r "idle_up": {\r "length": 4,\r "row": 5\r },\r "walk_up": {\r "length": 6,\r "row": 6\r },\r "atk_down": {\r "length": 8,\r "row": 7\r },\r "walk_down": {\r "length": 6,\r "row": 8\r },\r "idle_down": {\r "length": 7,\r "row": 9\r }\r },\r "offset_x": -8,\r "offset_y": -8\r}\r'}),define("text!../sprites/death.json",function(){return'{\r "id": "death",\r "width": 24,\r "height": 24,\r "animations": {\r "death": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -4\r}\r'}),define("text!../sprites/deathknight.json",function(){return'{\r "id": "deathknight",\r "width": 42,\r "height": 42,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -13,\r "offset_y": -17\r}\r'}),define("text!../sprites/desertnpc.json",function(){return'{\r "id": "desertnpc",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/eye.json",function(){return'{\r "id": "eye",\r "width": 40,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 6,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 14,\r "row": 2\r },\r "atk_up": {\r "length": 4,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 14,\r "row": 5\r },\r "atk_down": {\r "length": 8,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 14,\r "row": 8\r }\r },\r "offset_x": -12,\r "offset_y": -18\r}\r'}),define("text!../sprites/firefox.json",function(){return'{\r "id": "firefox",\r "width": 32,\r "height": 32,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 5,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 8,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/forestnpc.json",function(){return'{\r "id": "forestnpc",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/goblin.json",function(){return'{\r "id": "goblin",\r "width": 26,\r "height": 26,\r "animations": {\r "atk_right": {\r "length": 3,\r "row": 0\r },\r "walk_right": {\r "length": 3,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 3,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 3,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -5,\r "offset_y": -9\r}\r'}),define("text!../sprites/goldenarmor.json",function(){return'{\r "id": "goldenarmor",\r "width": 32,\r "height": 32,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/goldensword.json",function(){return'{\r "id": "goldensword",\r "width": 48,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -16,\r "offset_y": -20\r}\r'}),define("text!../sprites/guard.json",function(){return'{\r "id": "guard",\r "width": 25,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -5,\r "offset_y": -8\r}\r'}),define("text!../sprites/hand.json",function(){return'{\r "id": "hand",\r "width": 14,\r "height": 14,\r "animations": {\r "idle_down": {\r "length": 1,\r "row": 0\r }\r }\r}\r'}),define("text!../sprites/impact.json",function(){return'{\r "id": "impact",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 1,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-axe.json",function(){return'{\r "id": "item-axe",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-bluesword.json",function(){return'{\r "id": "item-bluesword",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-burger.json",function(){return'{\r "id": "item-burger",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-cake.json",function(){return'{\r "id": "item-cake",\r "width": 24,\r "height": 24,\r "animations": {\r "idle": {\r "length": 3,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -6\r}\r'}),define("text!../sprites/item-firepotion.json",function(){return'{\r "id": "item-firepotion",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-flask.json",function(){return'{\r "id": "item-flask",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-goldenarmor.json",function(){return'{\r "id": "item-goldenarmor",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-goldensword.json",function(){return'{\r "id": "item-goldensword",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-leatherarmor.json",function(){return'{\r "id": "item-leatherarmor",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-mailarmor.json",function(){return'{\r "id": "item-mailarmor",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-morningstar.json",function(){return'{\r "id": "item-morningstar",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-platearmor.json",function(){return'{\r "id": "item-platearmor",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-redarmor.json",function(){return'{\r "id": "item-redarmor",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-redsword.json",function(){return'{\r "id": "item-redsword",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-sword1.json",function(){return'{\r "id": "item-sword1",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/item-sword2.json",function(){return'{\r "id": "item-sword2",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/king.json",function(){return'{\r "id": "king",\r "width": 32,\r "height": 32,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/lavanpc.json",function(){return'{\r "id": "lavanpc",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/leatherarmor.json",function(){return'{\r "id": "leatherarmor",\r "width": 32,\r "height": 32,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/loot.json",function(){return'{\r "id": "loot",\r "width": 14,\r "height": 14,\r "animations": {\r "idle_down": {\r "length": 1,\r "row": 0\r }\r }\r}\r'}),define("text!../sprites/mailarmor.json",function(){return'{\r "id": "mailarmor",\r "width": 32,\r "height": 32,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/morningstar.json",function(){return'{\r "id": "morningstar",\r "width": 38,\r "height": 38,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -11,\r "offset_y": -15\r}\r'}),define("text!../sprites/nyan.json",function(){return'{\r "id": "nyan",\r "width": 49,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": -22,\r "offset_y": -6\r}\r'}),define("text!../sprites/octocat.json",function(){return'{\r "id": "octocat",\r "width": 32,\r "height": 32,\r "animations": {\r "idle_down": {\r "length": 4,\r "row": 0\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/ogre.json",function(){return'{\r "id": "ogre",\r "width": 48,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 3,\r "row": 0\r },\r "walk_right": {\r "length": 6,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 3,\r "row": 3\r },\r "walk_up": {\r "length": 5,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 3,\r "row": 6\r },\r "walk_down": {\r "length": 6,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -16,\r "offset_y": -24\r}\r'}),define("text!../sprites/platearmor.json",function(){return'{\r "id": "platearmor",\r "width": 32,\r "height": 32,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/priest.json",function(){return'{\r "id": "priest",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/rat.json",function(){return'{\r "id": "rat",\r "width": 48,\r "height": 48,\r "animations": {\r "death": {\r "length": 4,\r "row": 0\r },\r "atk_right": {\r "length": 6,\r "row": 1\r },\r "walk_right": {\r "length": 3,\r "row": 2\r },\r "idle_right": {\r "length": 2,\r "row": 3\r },\r "atk_up": {\r "length": 4,\r "row": 4\r },\r "walk_up": {\r "length": 4,\r "row": 5\r },\r "idle_up": {\r "length": 4,\r "row": 6\r },\r "atk_down": {\r "length": 4,\r "row": 7\r },\r "walk_down": {\r "length": 4,\r "row": 8\r },\r "idle_down": {\r "length": 4,\r "row": 9\r }\r }\r}\r'}),define("text!../sprites/redarmor.json",function(){return'{\r "id": "redarmor",\r "width": 32,\r "height": 32,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/redsword.json",function(){return'{\r "id": "redsword",\r "width": 48,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -16,\r "offset_y": -20\r}\r'}),define("text!../sprites/rick.json",function(){return'{\r "id": "rick",\r "width": 32,\r "height": 32,\r "animations": {\r "idle_down": {\r "length": 4,\r "row": 0\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/scientist.json",function(){return'{\r "id": "scientist",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/shadow16.json",function(){return'{\r "id": "shadow16",\r "width": 16,\r "height": 16\r}\r'}),define("text!../sprites/skeleton.json",function(){return'{\r "id": "skeleton",\r "width": 48,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 3,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 3,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 3,\r "row": 5\r },\r "atk_down": {\r "length": 3,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 3,\r "row": 8\r }\r },\r "offset_x": -16,\r "offset_y": -20\r}\r'}),define("text!../sprites/skeleton2.json",function(){return'{\r "id": "skeleton2",\r "width": 48,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 3,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 3,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 3,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 3,\r "row": 8\r }\r },\r "offset_x": -16,\r "offset_y": -20\r}\r'}),define("text!../sprites/snake.json",function(){return'{\r "id": "snake",\r "width": 28,\r "height": 28,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 4,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 4,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 6,\r "row": 8\r }\r },\r "offset_x": -6,\r "offset_y": -10\r}\r'}),define("text!../sprites/sorcerer.json",function(){return'{\r "id": "sorcerer",\r "width": 26,\r "height": 26,\r "animations": {\r "idle_down": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": -5,\r "offset_y": -9\r}\r'}),define("text!../sprites/sparks.json",function(){return'{\r "id": "sparks",\r "width": 16,\r "height": 16,\r "animations": {\r "idle": {\r "length": 6,\r "row": 0\r }\r },\r "offset_x": 0,\r "offset_y": 0\r}\r'}),define("text!../sprites/spectre.json",function(){return'{\r "id": "spectre",\r "width": 34,\r "height": 34,\r "animations": {\r "atk_right": {\r "length": 8,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 6,\r "row": 3\r },\r "walk_up": {\r "length": 8,\r "row": 4\r },\r "idle_up": {\r "length": 8,\r "row": 5\r },\r "atk_down": {\r "length": 6,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -9,\r "offset_y": -13\r}\r'}),define("text!../sprites/sword.json",function(){return'{\r "id": "sword",\r "width": 14,\r "height": 14,\r "animations": {\r "idle_down": {\r "length": 1,\r "row": 0\r }\r }\r}\r'}),define("text!../sprites/sword1.json",function(){return'{\r "id": "sword1",\r "width": 32,\r "height": 32,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -8,\r "offset_y": -12\r}\r'}),define("text!../sprites/sword2.json",function(){return'{\r "id": "sword2",\r "width": 48,\r "height": 48,\r "animations": {\r "atk_right": {\r "length": 5,\r "row": 0\r },\r "walk_right": {\r "length": 4,\r "row": 1\r },\r "idle_right": {\r "length": 2,\r "row": 2\r },\r "atk_up": {\r "length": 5,\r "row": 3\r },\r "walk_up": {\r "length": 4,\r "row": 4\r },\r "idle_up": {\r "length": 2,\r "row": 5\r },\r "atk_down": {\r "length": 5,\r "row": 6\r },\r "walk_down": {\r "length": 4,\r "row": 7\r },\r "idle_down": {\r "length": 2,\r "row": 8\r }\r },\r "offset_x": -16,\r "offset_y": -20\r}\r'}),define("text!../sprites/talk.json",function(){return'{\r "id": "talk",\r "width": 14,\r "height": 14,\r "animations": {\r "idle_down": {\r "length": 1,\r "row": 0\r }\r }\r}\r'}),define("text!../sprites/target.json",function(){return'{\r "id": "target",\r "width": 16,\r "height": 16,\r "animations": {\r "move": {\r "length": 4,\r "row": 0\r },\r "atk": {\r "length": 4,\r "row": 1\r }\r }\r}\r'}),define("text!../sprites/villagegirl.json",function(){return'{\r "id": "villagegirl",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/villager.json",function(){return'{\r "id": "villager",\r "width": 24,\r "height": 24,\r "animations": {\r "idle_down": {\r "length": 2,\r "row": 0\r }\r },\r "offset_x": -4,\r "offset_y": -8\r}\r'}),define("text!../sprites/wizard.json",function(){return'{\r "id": "wizard",\r "width": 26,\r "height": 26,\r "animations": {\r "death": {\r "length": 3,\r "row": 0\r },\r "atk_right": {\r "length": 4,\r "row": 1\r },\r "atk_up": {\r "length": 4,\r "row": 2\r },\r "atk_down": {\r "length": 4,\r "row": 3\r },\r "walk_right": {\r "length": 4,\r "row": 4\r },\r "walk_up": {\r "length": 4,\r "row": 5\r },\r "walk_down": {\r "length": 4,\r "row": 6\r },\r "idle_right": {\r "length": 6,\r "row": 7\r },\r "idle_up": {\r "length": 6,\r "row": 8\r },\r "idle_down": {\r "length": 6,\r "row": 9\r }\r },\r "offset_x": -5,\r "offset_y": -9\r}\r'}),define("sprites",["text!../sprites/agent.json","text!../sprites/arrow.json","text!../sprites/axe.json","text!../sprites/bat.json","text!../sprites/beachnpc.json","text!../sprites/bluesword.json","text!../sprites/boss.json","text!../sprites/chest.json","text!../sprites/clotharmor.json","text!../sprites/coder.json","text!../sprites/crab.json","text!../sprites/death.json","text!../sprites/deathknight.json","text!../sprites/desertnpc.json","text!../sprites/eye.json","text!../sprites/firefox.json","text!../sprites/forestnpc.json","text!../sprites/goblin.json","text!../sprites/goldenarmor.json","text!../sprites/goldensword.json","text!../sprites/guard.json","text!../sprites/hand.json","text!../sprites/impact.json","text!../sprites/item-axe.json","text!../sprites/item-bluesword.json","text!../sprites/item-burger.json","text!../sprites/item-cake.json","text!../sprites/item-firepotion.json","text!../sprites/item-flask.json","text!../sprites/item-goldenarmor.json","text!../sprites/item-goldensword.json","text!../sprites/item-leatherarmor.json","text!../sprites/item-mailarmor.json","text!../sprites/item-morningstar.json","text!../sprites/item-platearmor.json","text!../sprites/item-redarmor.json","text!../sprites/item-redsword.json","text!../sprites/item-sword1.json","text!../sprites/item-sword2.json","text!../sprites/king.json","text!../sprites/lavanpc.json","text!../sprites/leatherarmor.json","text!../sprites/loot.json","text!../sprites/mailarmor.json","text!../sprites/morningstar.json","text!../sprites/nyan.json","text!../sprites/octocat.json","text!../sprites/ogre.json","text!../sprites/platearmor.json","text!../sprites/priest.json","text!../sprites/rat.json","text!../sprites/redarmor.json","text!../sprites/redsword.json","text!../sprites/rick.json","text!../sprites/scientist.json","text!../sprites/shadow16.json","text!../sprites/skeleton.json","text!../sprites/skeleton2.json","text!../sprites/snake.json","text!../sprites/sorcerer.json","text!../sprites/sparks.json","text!../sprites/spectre.json","text!../sprites/sword.json","text!../sprites/sword1.json","text!../sprites/sword2.json","text!../sprites/talk.json","text!../sprites/target.json","text!../sprites/villagegirl.json","text!../sprites/villager.json","text!../sprites/wizard.json"],function(){var e={};return _.each(arguments,function(t){var n=JSON.parse(t);e[n.id]=n}),e}),define("sprite",["jquery","animation","sprites"],function(e,t,n){var r=Class.extend({init:function(e,t){this.name=e,this.scale=t,this.isLoaded=!1,this.offsetX=0,this.offsetY=0,this.loadJSON(n[e])},loadJSON:function(e){this.id=e.id,this.filepath="img/"+this.scale+"/"+this.id+".png",this.animationData=e.animations,this.width=e.width,this.height=e.height,this.offsetX=e.offset_x!==undefined?e.offset_x:-16,this.offsetY=e.offset_y!==undefined?e.offset_y:-16,this.load()},load:function(){var e=this;this.image=new Image,this.image.src=this.filepath,this.image.onload=function(){e.isLoaded=!0,e.onload_func&&e.onload_func()}},createAnimations:function(){var e={};for(var n in this.animationData){var r=this.animationData[n];e[n]=new t(n,r.length,r.row,this.width,this.height)}return e},createHurtSprite:function(){var e=document.createElement("canvas"),t=e.getContext("2d"),n=this.image.width,r=this.image.height,i,s;e.width=n,e.height=r,t.drawImage(this.image,0,0,n,r);try{i=t.getImageData(0,0,n,r),s=i.data;for(var o=0;o<s.length;o+=4)s[o]=255,s[o+1]=s[o+2]=75;i.data=s,t.putImageData(i,0,0),this.whiteSprite={image:e,isLoaded:!0,offsetX:this.offsetX,offsetY:this.offsetY,width:this.width,height:this.height}}catch(u){log.error("Error getting image data for sprite : "+this.name)}},getHurtSprite:function(){return this.whiteSprite},createSilhouette:function(){var e=document.createElement("canvas"),t=e.getContext("2d"),n=this.image.width,r=this.image.height,i,s,o;e.width=n,e.height=r,t.drawImage(this.image,0,0,n,r),o=t.getImageData(0,0,n,r).data,s=t.getImageData(0,0,n,r),fdata=s.data;var u=function(e,t){return(n*(t-1)+e-1)*4},a=function(e){var t,r;return e=e/4+1,t=e%n,r=(e-t)/n+1,{x:t,y:r}},f=function(e){var t=a(e);return t.x<n&&!l(u(t.x+1,t.y))?!0:t.x>1&&!l(u(t.x-1,t.y))?!0:t.y<r&&!l(u(t.x,t.y+1))?!0:t.y>1&&!l(u(t.x,t.y-1))?!0:!1},l=function(e){return e<0||e>=o.length?!0:o[e]===0&&o[e+1]===0&&o[e+2]===0&&o[e+3]===0};for(var c=0;c<o.length;c+=4)l(c)&&f(c)&&(fdata[c]=fdata[c+1]=255,fdata[c+2]=150,fdata[c+3]=150);s.data=fdata,t.putImageData(s,0,0),this.silhouetteSprite={image:e,isLoaded:!0,offsetX:this.offsetX,offsetY:this.offsetY,width:this.width,height:this.height}}});return r}),define("tile",[],function(){var e=Class.extend({}),t=e.extend({init:function(e,t,n,r){this.startId=e,this.id=e,this.length=t,this.speed=n,this.index=r,this.lastTime=0},tick:function(){this.id-this.startId<this.length-1?this.id+=1:this.id=this.startId},animate:function(e){return e-this.lastTime>this.speed?(this.tick(),this.lastTime=e,!0):!1}});return t}),define("warrior",["player"],function(e){var t=e.extend({init:function(e,t){this._super(e,t,Types.Entities.WARRIOR)}});return t}),define("mob",["character"],function(e){var t=e.extend({init:function(e,t){this._super(e,t),this.aggroRange=1,this.isAggressive=!0}});return t}),define("mobs",["mob","timer"],function(e,t){var n={Rat:e.extend({init:function(e){this._super(e,Types.Entities.RAT),this.moveSpeed=350,this.idleSpeed=700,this.shadowOffsetY=-2,this.isAggressive=!1}}),Skeleton:e.extend({init:function(e){this._super(e,Types.Entities.SKELETON),this.moveSpeed=350,this.atkSpeed=100,this.idleSpeed=800,this.shadowOffsetY=1,this.setAttackRate(1300)}}),Skeleton2:e.extend({init:function(e){this._super(e,Types.Entities.SKELETON2),this.moveSpeed=200,this.atkSpeed=100,this.idleSpeed=800,this.walkSpeed=200,this.shadowOffsetY=1,this.setAttackRate(1300)}}),Spectre:e.extend({init:function(e){this._super(e,Types.Entities.SPECTRE),this.moveSpeed=150,this.atkSpeed=50,this.idleSpeed=200,this.walkSpeed=200,this.shadowOffsetY=1,this.setAttackRate(900)}}),Deathknight:e.extend({init:function(e){this._super(e,Types.Entities.DEATHKNIGHT),this.atkSpeed=50,this.moveSpeed=220,this.walkSpeed=100,this.idleSpeed=450,this.setAttackRate(800),this.aggroRange=3},idle:function(e){this.hasTarget()?this._super(e):this._super(Types.Orientations.DOWN)}}),Goblin:e.extend({init:function(e){this._super(e,Types.Entities.GOBLIN),this.moveSpeed=150,this.atkSpeed=60,this.idleSpeed=600,this.setAttackRate(700)}}),Ogre:e.extend({init:function(e){this._super(e,Types.Entities.OGRE),this.moveSpeed=300,this.atkSpeed=100,this.idleSpeed=600}}),Crab:e.extend({init:function(e){this._super(e,Types.Entities.CRAB),this.moveSpeed=200,this.atkSpeed=40,this.idleSpeed=500}}),Snake:e.extend({init:function(e){this._super(e,Types.Entities.SNAKE),this.moveSpeed=200,this.atkSpeed=40,this.idleSpeed=250,this.walkSpeed=100,this.shadowOffsetY=-4}}),Eye:e.extend({init:function(e){this._super(e,Types.Entities.EYE),this.moveSpeed=200,this.atkSpeed=40,this.idleSpeed=50}}),Bat:e.extend({init:function(e){this._super(e,Types.Entities.BAT),this.moveSpeed=120,this.atkSpeed=90,this.idleSpeed=90,this.walkSpeed=85,this.isAggressive=!1}}),Wizard:e.extend({init:function(e){this._super(e,Types.Entities.WIZARD),this.moveSpeed=200,this.atkSpeed=100,this.idleSpeed=150}}),Boss:e.extend({init:function(e){this._super(e,Types.Entities.BOSS),this.moveSpeed=300,this.atkSpeed=50,this.idleSpeed=400,this.atkRate=2e3,this.attackCooldown=new t(this.atkRate),this.aggroRange=3},idle:function(e){this.hasTarget()?this._super(e):this._super(Types.Orientations.DOWN)}})};return n}),define("items",["item"],function(e){var t={Sword2:e.extend({init:function(e){this._super(e,Types.Entities.SWORD2,"weapon"),this.lootMessage="You pick up a steel sword"}}),Axe:e.extend({init:function(e){this._super(e,Types.Entities.AXE,"weapon"),this.lootMessage="You pick up an axe"}}),RedSword:e.extend({init:function(e){this._super(e,Types.Entities.REDSWORD,"weapon"),this.lootMessage="You pick up a blazing sword"}}),BlueSword:e.extend({init:function(e){this._super(e,Types.Entities.BLUESWORD,"weapon"),this.lootMessage="You pick up a magic sword"}}),GoldenSword:e.extend({init:function(e){this._super(e,Types.Entities.GOLDENSWORD,"weapon"),this.lootMessage="You pick up the ultimate sword"}}),MorningStar:e.extend({init:function(e){this._super(e,Types.Entities.MORNINGSTAR,"weapon"),this.lootMessage="You pick up a morning star"}}),LeatherArmor:e.extend({init:function(e){this._super(e,Types.Entities.LEATHERARMOR,"armor"),this.lootMessage="You equip a leather armor"}}),MailArmor:e.extend({init:function(e){this._super(e,Types.Entities.MAILARMOR,"armor"),this.lootMessage="You equip a mail armor"}}),PlateArmor:e.extend({init:function(e){this._super(e,Types.Entities.PLATEARMOR,"armor"),this.lootMessage="You equip a plate armor"}}),RedArmor:e.extend({init:function(e){this._super(e,Types.Entities.REDARMOR,"armor"),this.lootMessage="You equip a ruby armor"}}),GoldenArmor:e.extend({init:function(e){this._super(e,Types.Entities.GOLDENARMOR,"armor"),this.lootMessage="You equip a golden armor"}}),Flask:e.extend({init:function(e){this._super(e,Types.Entities.FLASK,"object"),this.lootMessage="You drink a health potion"}}),Cake:e.extend({init:function(e){this._super(e,Types.Entities.CAKE,"object"),this.lootMessage="You eat a cake"}}),Burger:e.extend({init:function(e){this._super(e,Types.Entities.BURGER,"object"),this.lootMessage="You can haz rat burger"}}),FirePotion:e.extend({init:function(e){this._super(e,Types.Entities.FIREPOTION,"object"),this.lootMessage="You feel the power of Firefox!"},onLoot:function(e){e.startInvincibility()}})};return t}),define("npc",["character"],function(e){var t={guard:["Hello there","We don't need to see your identification","You are not the player we're looking for","Move along, move along..."],king:["Hi, I'm the King","I run this place","Like a boss","I talk to people","Like a boss","I wear a crown","Like a boss","I do nothing all day","Like a boss","Now leave me alone","Like a boss"],villagegirl:["Hi there, adventurer!","How do you like this game?","It's all happening in a single web page! Isn't it crazy?","It's all made possible thanks to WebSockets.","I don't know much about it, after all I'm just a program.",'Why don&#x27;t you read this <a target="_blank" href="http://hacks.mozilla.org/2012/03/browserquest/">blog post</a> and learn all about it?'],villager:["Howdy stranger. Do you like poetry?","Roses are red, violets are blue...","I like hunting rats, and so do you...","The rats are dead, now what to do?","To be honest, I have no clue.","Maybe the forest, could interest you...","or instead, cook a rat stew."],agent:["Do not try to bend the sword","That's impossible","Instead, only try to realize the truth...","There is no sword."],rick:["We're no strangers to love","You know the rules and so do I","A full commitment's what I'm thinking of","You wouldn't get this from any other guy","I just wanna tell you how I'm feeling","Gotta make you understand","Never gonna give you up","Never gonna let you down","Never gonna run around and desert you","Never gonna make you cry","Never gonna say goodbye","Never gonna tell a lie and hurt you"],scientist:["Greetings.","I am the inventor of these two potions.","The red one will replenish your health points...","The orange one will turn you into a firefox and make you invincible...","But it only lasts for a short while.","So make good use of it!","Now if you'll excuse me, I need to get back to my experiments..."],nyan:["nyan nyan nyan nyan nyan","nyan nyan nyan nyan nyan nyan nyan","nyan nyan nyan nyan nyan nyan","nyan nyan nyan nyan nyan nyan nyan nyan"],beachnpc:["lorem ipsum dolor sit amet","consectetur adipisicing elit, sed do eiusmod tempor"],forestnpc:["lorem ipsum dolor sit amet","consectetur adipisicing elit, sed do eiusmod tempor"],desertnpc:["lorem ipsum dolor sit amet","consectetur adipisicing elit, sed do eiusmod tempor"],lavanpc:["lorem ipsum dolor sit amet","consectetur adipisicing elit, sed do eiusmod tempor"],priest:["Oh, hello, young man.","Wisdom is everything, so I'll share a few guidelines with you.","You are free to go wherever you like in this world","but beware of the many foes that await you.","You can find many weapons and armors by killing enemies.","The tougher the enemy, the higher the potential rewards.","You can also unlock achievements by exploring and hunting.","Click on the small cup icon to see a list of all the achievements.","Please stay a while and enjoy the many surprises of BrowserQuest","Farewell, young friend."],sorcerer:["Ah... I had foreseen you would come to see me.","Well? How do you like my new staff?","Pretty cool, eh?","Where did I get it, you ask?","I understand. It's easy to get envious.","I actually crafted it myself, using my mad wizard skills.","But let me tell you one thing...","There are lots of items in this game.","Some more powerful than others.","In order to find them, exploration is key.","Good luck."],octocat:["Welcome to BrowserQuest!","Want to see the source code?",'Check out <a target="_blank" href="http://github.com/nenuadrian/BrowserQuest">the repository on GitHub</a>'],coder:["Hi! Do you know that you can also play BrowserQuest on your tablet or mobile?","That's the beauty of HTML5!","Give it a try..."],beachnpc:["Don't mind me, I'm just here on vacation.","I have to say...","These giant crabs are somewhat annoying.","Could you please get rid of them for me?"],desertnpc:["One does not simply walk into these mountains...","An ancient undead lord is said to dwell here.","Nobody knows exactly what he looks like...","...for none has lived to tell the tale.","It's not too late to turn around and go home, kid."],othernpc:["lorem ipsum","lorem ipsum"]},n=e.extend({init:function(e,n){this._super(e,n,1),this.itemKind=Types.getKindAsString(this.kind),this.talkCount=t[this.itemKind].length,this.talkIndex=0},talk:function(){var e=null;return this.talkIndex>this.talkCount&&(this.talkIndex=0),this.talkIndex<this.talkCount&&(e=t[this.itemKind][this.talkIndex]),this.talkIndex+=1,e}});return n}),define("npcs",["npc"],function(e){var t={Guard:e.extend({init:function(e){this._super(e,Types.Entities.GUARD,1)}}),King:e.extend({init:function(e){this._super(e,Types.Entities.KING,1)}}),Agent:e.extend({init:function(e){this._super(e,Types.Entities.AGENT,1)}}),Rick:e.extend({init:function(e){this._super(e,Types.Entities.RICK,1)}}),VillageGirl:e.extend({init:function(e){this._super(e,Types.Entities.VILLAGEGIRL,1)}}),Villager:e.extend({init:function(e){this._super(e,Types.Entities.VILLAGER,1)}}),Coder:e.extend({init:function(e){this._super(e,Types.Entities.CODER,1)}}),Scientist:e.extend({init:function(e){this._super(e,Types.Entities.SCIENTIST,1)}}),Nyan:e.extend({init:function(e){this._super(e,Types.Entities.NYAN,1),this.idleSpeed=50}}),Sorcerer:e.extend({init:function(e){this._super(e,Types.Entities.SORCERER,1),this.idleSpeed=150}}),Priest:e.extend({init:function(e){this._super(e,Types.Entities.PRIEST,1)}}),BeachNpc:e.extend({init:function(e){this._super(e,Types.Entities.BEACHNPC,1)}}),ForestNpc:e.extend({init:function(e){this._super(e,Types.Entities.FORESTNPC,1)}}),DesertNpc:e.extend({init:function(e){this._super(e,Types.Entities.DESERTNPC,1)}}),LavaNpc:e.extend({init:function(e){this._super(e,Types.Entities.LAVANPC,1)}}),Octocat:e.extend({init:function(e){this._super(e,Types.Entities.OCTOCAT,1)}})};return t}),define("chest",["entity"],function(e){var t=e.extend({init:function(e,t){this._super(e,Types.Entities.CHEST)},getSpriteName:function(){return"chest"},isMoving:function(){return!1},open:function(){this.open_callback&&this.open_callback()},onOpen:function(e){this.open_callback=e}});return t}),define("entityfactory",["mobs","items","npcs","warrior","chest"],function(e,t,n,r,i){var s={};return s.createEntity=function(e,t,n){if(!e){log.error("kind is undefined",!0);return}if(!_.isFunction(s.builders[e]))throw Error(e+" is not a valid Entity type");return s.builders[e](t,n)},s.builders=[],s.builders[Types.Entities.WARRIOR]=function(e,t){return new r(e,t)},s.builders[Types.Entities.RAT]=function(t){return new e.Rat(t)},s.builders[Types.Entities.SKELETON]=function(t){return new e.Skeleton(t)},s.builders[Types.Entities.SKELETON2]=function(t){return new e.Skeleton2(t)},s.builders[Types.Entities.SPECTRE]=function(t){return new e.Spectre(t)},s.builders[Types.Entities.DEATHKNIGHT]=function(t){return new e.Deathknight(t)},s.builders[Types.Entities.GOBLIN]=function(t){return new e.Goblin(t)},s.builders[Types.Entities.OGRE]=function(t){return new e.Ogre(t)},s.builders[Types.Entities.CRAB]=function(t){return new e.Crab(t)},s.builders[Types.Entities.SNAKE]=function(t){return new e.Snake(t)},s.builders[Types.Entities.EYE]=function(t){return new e.Eye(t)},s.builders[Types.Entities.BAT]=function(t){return new e.Bat(t)},s.builders[Types.Entities.WIZARD]=function(t){return new e.Wizard(t)},s.builders[Types.Entities.BOSS]=function(t){return new e.Boss(t)},s.builders[Types.Entities.SWORD2]=function(e){return new t.Sword2(e)},s.builders[Types.Entities.AXE]=function(e){return new t.Axe(e)},s.builders[Types.Entities.REDSWORD]=function(e){return new t.RedSword(e)},s.builders[Types.Entities.BLUESWORD]=function(e){return new t.BlueSword(e)},s.builders[Types.Entities.GOLDENSWORD]=function(e){return new t.GoldenSword(e)},s.builders[Types.Entities.MORNINGSTAR]=function(e){return new t.MorningStar(e)},s.builders[Types.Entities.MAILARMOR]=function(e){return new t.MailArmor(e)},s.builders[Types.Entities.LEATHERARMOR]=function(e){return new t.LeatherArmor(e)},s.builders[Types.Entities.PLATEARMOR]=function(e){return new t.PlateArmor(e)},s.builders[Types.Entities.REDARMOR]=function(e){return new t.RedArmor(e)},s.builders[Types.Entities.GOLDENARMOR]=function(e){return new t.GoldenArmor(e)},s.builders[Types.Entities.FLASK]=function(e){return new t.Flask(e)},s.builders[Types.Entities.FIREPOTION]=function(e){return new t.FirePotion(e)},s.builders[Types.Entities.BURGER]=function(e){return new t.Burger(e)},s.builders[Types.Entities.CAKE]=function(e){return new t.Cake(e)},s.builders[Types.Entities.CHEST]=function(e){return new i(e)},s.builders[Types.Entities.GUARD]=function(e){return new n.Guard(e)},s.builders[Types.Entities.KING]=function(e){return new n.King(e)},s.builders[Types.Entities.VILLAGEGIRL]=function(e){return new n.VillageGirl(e)},s.builders[Types.Entities.VILLAGER]=function(e){return new n.Villager(e)},s.builders[Types.Entities.CODER]=function(e){return new n.Coder(e)},s.builders[Types.Entities.AGENT]=function(e){return new n.Agent(e)},s.builders[Types.Entities.RICK]=function(e){return new n.Rick(e)},s.builders[Types.Entities.SCIENTIST]=function(e){return new n.Scientist(e)},s.builders[Types.Entities.NYAN]=function(e){return new n.Nyan(e)},s.builders[Types.Entities.PRIEST]=function(e){return new n.Priest(e)},s.builders[Types.Entities.SORCERER]=function(e){return new n.Sorcerer(e)},s.builders[Types.Entities.OCTOCAT]=function(e){return new n.Octocat(e)},s.builders[Types.Entities.BEACHNPC]=function(e){return new n.BeachNpc(e)},s.builders[Types.Entities.FORESTNPC]=function(e){return new n.ForestNpc(e)},s.builders[Types.Entities.DESERTNPC]=function(e){return new n.DesertNpc(e)},s.builders[Types.Entities.LAVANPC]=function(e){return new n.LavaNpc(e)},s}),function(e){function s(e,t){if(typeof e=="number"){var r=e|0;if(r!==e){var o=0,u=(e-r)*100;u<0?(o=(u+1|0)-u,u=o>=1&&o<=1.5?u|0:u-1|0):(o=u|0,u=u-o>=.5?u+1|0:o),o=0,e<0&&(r=0-r,u=0-u,o=1),r<65536?r===0?i+=n[13+o]+n[u+128]:i+=n[13+o]+n[u]+n[r]:i+=n[15+o]+n[r>>16&65535]+n[r&65535]+n[u]}else{var o=0;e<=0?(e=0-e,o=1):e--,e<116?i+=n[17+e+o*116]:e<65536?i+=n[1+o]+n[e]:i+=n[3+o]+n[e>>16&65535]+n[e&65535]}}else if(typeof e=="string"){var a=e.length;i+=n[7];while(a>=65535)a-=65535,i+=n[65535];i+=n[a]+e}else if(e===!0)i+=n[5];else if(e===!1)i+=n[6];else if(e===null)i+=n[0];else if(e instanceof Array){i+=n[8];for(var f=0,a=e.length;f<a;f++)s(e[f],!1);t||(i+=n[9])}else if(e instanceof Object){i+=n[10];for(var l in e)i+=n[17+l.length]+l,s(e[l],!1);t||(i+=n[11])}}function o(e){return i="",s(e,!0),i}function u(t){var n=0,r=t.length,i=[],s=e,o=null,u=0,a=-1,f=!1,l=!1,c="",h=null,p=0;while(n<r){u=t.charCodeAt(n++),o=i[a];if(f&&l&&u>16)c=t.substring(n,n+u-17),n+=u-17,l=!1;else if(u===8||u===10)h=u===8?new Array:new Object,l=f=u===10,s!==e?o instanceof Array?o.push(h):o[c]=h:s=h,i.push(h),a++;else if(u===11||u===9)i.pop(),l=f=!(i[--a]instanceof Array);else if(u>16)u-=17,u=u>115?0-u+116:u+1,o instanceof Array?o.push(u):o[c]=u,l=!0;else if(u>0&&u<5)((u-1)/2|0)===0?(h=t.charCodeAt(n),n++):(h=(t.charCodeAt(n)<<16)+t.charCodeAt(n+1),n+=2),h=u%2?h+1:0-h,o instanceof Array?o.push(h):o[c]=h,l=!0;else if(u>12&&u<17)((u-13)/2|0)===0?(p=t.charCodeAt(n),p>127?(h=0,p-=128,n++):(h=t.charCodeAt(n+1),n+=2)):(h=(t.charCodeAt(n)<<16)+t.charCodeAt(n+1),p=t.charCodeAt(n+2),n+=3),h=u%2?h+p*.01:0-(h+p*.01),o instanceof Array?o.push(h):o[c]=h,l=!0;else if(u>4&&u<7)o instanceof Array?o.push(u===5):o[c]=u===5,l=!0;else if(u===0)o instanceof Array?o.push(null):o[c]=null,l=!0;else if(u===7){h=0;while(t.charCodeAt(n)===65535)h+=65535,n++;h+=t.charCodeAt(n++),o instanceof Array?o.push(t.substr(n,h)):o[c]=t.substr(n,h),n+=h,l=!0}}return s}var t=String.fromCharCode,n=new Array(65536);for(var r=0;r<65536;r++)n[r]=t(r);var i="";typeof window=="undefined"?(exports.encode=o,exports.decode=u):window.BISON={encode:o,decode:u}}(),define("lib/bison",function(){}),define("gameclient",["player","entityfactory","lib/bison"],function(e,t,n){var r=Class.extend({init:function(e,t){this.connection=null,this.host=e,this.port=t,this.connected_callback=null,this.spawn_callback=null,this.movement_callback=null,this.handlers=[],this.handlers[Types.Messages.WELCOME]=this.receiveWelcome,this.handlers[Types.Messages.MOVE]=this.receiveMove,this.handlers[Types.Messages.LOOTMOVE]=this.receiveLootMove,this.handlers[Types.Messages.ATTACK]=this.receiveAttack,this.handlers[Types.Messages.SPAWN]=this.receiveSpawn,this.handlers[Types.Messages.DESPAWN]=this.receiveDespawn,this.handlers[Types.Messages.SPAWN_BATCH]=this.receiveSpawnBatch,this.handlers[Types.Messages.HEALTH]=this.receiveHealth,this.handlers[Types.Messages.CHAT]=this.receiveChat,this.handlers[Types.Messages.EQUIP]=this.receiveEquipItem,this.handlers[Types.Messages.DROP]=this.receiveDrop,this.handlers[Types.Messages.TELEPORT]=this.receiveTeleport,this.handlers[Types.Messages.DAMAGE]=this.receiveDamage,this.handlers[Types.Messages.POPULATION]=this.receivePopulation,this.handlers[Types.Messages.LIST]=this.receiveList,this.handlers[Types.Messages.DESTROY]=this.receiveDestroy,this.handlers[Types.Messages.KILL]=this.receiveKill,this.handlers[Types.Messages.HP]=this.receiveHitPoints,this.handlers[Types.Messages.BLINK]=this.receiveBlink,this.useBison=!1,this.enable()},enable:function(){this.isListening=!0},disable:function(){this.isListening=!1},connect:function(e){var t="http://"+this.host+":"+this.port+"/",n=this;this.connection=io(t,{"force new connection":!0}),this.connection.on("connection",function(e){log.info("Connected to server "+t)}),e?(this.connection.emit("dispatch",!0),this.connection.on("dispatched",function(e){console.log("Dispatched: "),console.log(e),e.status==="OK"?n.dispatched_callback(e.host,e.port):e.status==="FULL"?console.log("BrowserQuest is currently at maximum player population. Please retry later."):console.log("Unknown error while connecting to BrowserQuest.")})):(this.connection.on("message",function(e){if(e==="go"){n.connected_callback&&n.connected_callback();return}if(e==="timeout"){n.isTimeout=!0;return}n.receiveMessage(e)}),this.connection.on("disconnect",function(){log.debug("Connection closed"),$("#container").addClass("error"),n.disconnected_callback&&(n.isTimeout?n.disconnected_callback("You have been disconnected for being inactive for too long"):n.disconnected_callback("The connection to BrowserQuest has been lost"))}))},sendMessage:function(e){this.connection.connected&&this.connection.emit("message",e)},receiveMessage:function(e){this.isListening&&(log.debug("data: "+e),e instanceof Array&&(e[0]instanceof Array?this.receiveActionBatch(e):this.receiveAction(e)))},receiveAction:function(e){var t=e[0];this.handlers[t]&&_.isFunction(this.handlers[t])?this.handlers[t].call(this,e):log.error("Unknown action : "+t)},receiveActionBatch:function(e){var t=this;_.each(e,function(e){t.receiveAction(e)})},receiveWelcome:function(e){var t=e[1],n=e[2],r=e[3],i=e[4],s=e[5];this.welcome_callback&&this.welcome_callback(t,n,r,i,s)},receiveMove:function(e){var t=e[1],n=e[2],r=e[3];this.move_callback&&this.move_callback(t,n,r)},receiveLootMove:function(e){var t=e[1],n=e[2];this.lootmove_callback&&this.lootmove_callback(t,n)},receiveAttack:function(e){var t=e[1],n=e[2];this.attack_callback&&this.attack_callback(t,n)},receiveSpawn:function(n){var r=n[1],i=n[2],s=n[3],o=n[4];if(Types.isItem(i)){var u=t.createEntity(i,r);this.spawn_item_callback&&this.spawn_item_callback(u,s,o)}else if(Types.isChest(i)){var u=t.createEntity(i,r);this.spawn_chest_callback&&this.spawn_chest_callback(u,s,o)}else{var a,f,l,c,h;Types.isPlayer(i)?(a=n[5],f=n[6],h=n[7],c=n[8],n.length>9&&(l=n[9])):Types.isMob(i)&&(f=n[5],n.length>6&&(l=n[6]));var p=t.createEntity(i,r,a);p instanceof e&&(p.weaponName=Types.getKindAsString(c),p.spriteName=Types.getKindAsString(h)),this.spawn_character_callback&&this.spawn_character_callback(p,s,o,f,l)}},receiveDespawn:function(e){var t=e[1];this.despawn_callback&&this.despawn_callback(t)},receiveHealth:function(e){var t=e[1],n=!1;e[2]&&(n=!0),this.health_callback&&this.health_callback(t,n)},receiveChat:function(e){var t=e[1],n=e[2];this.chat_callback&&this.chat_callback(t,n)},receiveEquipItem:function(e){var t=e[1],n=e[2];this.equip_callback&&this.equip_callback(t,n)},receiveDrop:function(e){var n=e[1],r=e[2],i=e[3],s=t.createEntity(i,r);s.wasDropped=!0,s.playersInvolved=e[4],this.drop_callback&&this.drop_callback(s,n)},receiveTeleport:function(e){var t=e[1],n=e[2],r=e[3];this.teleport_callback&&this.teleport_callback(t,n,r)},receiveDamage:function(e){var t=e[1],n=e[2];this.dmg_callback&&this.dmg_callback(t,n)},receivePopulation:function(e){var t=e[1],n=e[2];this.population_callback&&this.population_callback(t,n)},receiveKill:function(e){var t=e[1];this.kill_callback&&this.kill_callback(t)},receiveList:function(e){e.shift(),this.list_callback&&this.list_callback(e)},receiveDestroy:function(e){var t=e[1];this.destroy_callback&&this.destroy_callback(t)},receiveHitPoints:function(e){var t=e[1];this.hp_callback&&this.hp_callback(t)},receiveBlink:function(e){var t=e[1];this.blink_callback&&this.blink_callback(t)},onDispatched:function(e){this.dispatched_callback=e},onConnected:function(e){this.connected_callback=e},onDisconnected:function(e){this.disconnected_callback=e},onWelcome:function(e){this.welcome_callback=e},onSpawnCharacter:function(e){this.spawn_character_callback=e},onSpawnItem:function(e){this.spawn_item_callback=e},onSpawnChest:function(e){this.spawn_chest_callback=e},onDespawnEntity:function(e){this.despawn_callback=e},onEntityMove:function(e){this.move_callback=e},onEntityAttack:function(e){this.attack_callback=e},onPlayerChangeHealth:function(e){this.health_callback=e},onPlayerEquipItem:function(e){this.equip_callback=e},onPlayerMoveToItem:function(e){this.lootmove_callback=e},onPlayerTeleport:function(e){this.teleport_callback=e},onChatMessage:function(e){this.chat_callback=e},onDropItem:function(e){this.drop_callback=e},onPlayerDamageMob:function(e){this.dmg_callback=e},onPlayerKillMob:function(e){this.kill_callback=e},onPopulationChange:function(e){this.population_callback=e},onEntityList:function(e){this.list_callback=e},onEntityDestroy:function(e){this.destroy_callback=e},onPlayerChangeMaxHitPoints:function(e){this.hp_callback=e},onItemBlink:function(e){this.blink_callback=e},sendHello:function(e){this.sendMessage([Types.Messages.HELLO,e.name,Types.getKindFromString(e.getSpriteName()),Types.getKindFromString(e.getWeaponName())])},sendMove:function(e,t){this.sendMessage([Types.Messages.MOVE,e,t])},sendLootMove:function(e,t,n){this.sendMessage([Types.Messages.LOOTMOVE,t,n,e.id])},sendAggro:function(e){this.sendMessage([Types.Messages.AGGRO,e.id])},sendAttack:function(e){this.sendMessage([Types.Messages.ATTACK,e.id])},sendHit:function(e){this.sendMessage([Types.Messages.HIT,e.id])},sendHurt:function(e){this.sendMessage([Types.Messages.HURT,e.id])},sendChat:function(e){this.sendMessage([Types.Messages.CHAT,e])},sendLoot:function(e){this.sendMessage([Types.Messages.LOOT,e.id])},sendTeleport:function(e,t){this.sendMessage([Types.Messages.TELEPORT,e,t])},sendWho:function(e){e.unshift(Types.Messages.WHO),this.sendMessage(e)},sendZone:function(){this.sendMessage([Types.Messages.ZONE])},sendOpen:function(e){this.sendMessage([Types.Messages.OPEN,e.id])},sendCheck:function(e){this.sendMessage([Types.Messages.CHECK,e])}});return r}),define("audio",["area"],function(e){var t=Class.extend({init:function(e){var t=this;this.enabled=!0,this.extension=Detect.canPlayMP3()?"mp3":"ogg",this.sounds={},this.game=e,this.currentMusic=null,this.areas=[],this.musicNames=["village","beach","forest","cave","desert","lavaland","boss"],this.soundNames=["loot","hit1","hit2","hurt","heal","chat","revive","death","firefox","achievement","kill1","kill2","noloot","teleport","chest","npc","npc-end"];var n=function(){var e=_.size(t.soundNames);log.info("Loading sound files..."),_.each(t.soundNames,function(n){t.loadSound(n,function(){e-=1,e===0&&(Detect.isSafari()||r())})})},r=function(){t.game.renderer.mobile||(log.info("Loading music files..."),t.loadMusic(t.musicNames.shift(),function(){_.each(t.musicNames,function(e){t.loadMusic(e)})}))};!Detect.isSafari()||!Detect.isWindows()?n():this.enabled=!1},toggle:function(){this.enabled?(this.enabled=!1,this.currentMusic&&this.resetMusic(this.currentMusic)):(this.enabled=!0,this.currentMusic&&(this.currentMusic=null),this.updateMusic())},load:function(e,t,n,r){var i=e+t+"."+this.extension,s=document.createElement("audio"),o=this;s.addEventListener("canplaythrough",function(e){this.removeEventListener("canplaythrough",arguments.callee,!1),log.debug(i+" is ready to play."),n&&n()},!1),s.addEventListener("error",function(e){log.error("Error: "+i+" could not be loaded."),o.sounds[t]=null},!1),s.preload="auto",s.autobuffer=!0,s.src=i,s.load(),this.sounds[t]=[s],_.times(r-1,function(){o.sounds[t].push(s.cloneNode(!0))})},loadSound:function(e,t){this.load("audio/sounds/",e,t,4)},loadMusic:function(e,t){this.load("audio/music/",e,t,1);var n=this.sounds[e][0];n.loop=!0,n.addEventListener("ended",function(){n.play()},!1)},getSound:function(e){if(!this.sounds[e])return null;var t=_.detect(this.sounds[e],function(e){return e.ended||e.paused});return t&&t.ended?t.currentTime=0:t=this.sounds[e][0],t},playSound:function(e){var t=this.enabled&&this.getSound(e);t&&t.play()},addArea:function(t,n,r,i,s){var o=new e(t,n,r,i);o.musicName=s,this.areas.push(o)},getSurroundingMusic:function(e){var t=null,n=_.detect(this.areas,function(t){return t.contains(e)});return n&&(t={sound:this.getSound(n.musicName),name:n.musicName}),t},updateMusic:function(){if(this.enabled){var e=this.getSurroundingMusic(this.game.player);e?this.isCurrentMusic(e)||(this.currentMusic&&this.fadeOutCurrentMusic(),this.playMusic(e)):this.fadeOutCurrentMusic()}},isCurrentMusic:function(e){return this.currentMusic&&e.name===this.currentMusic.name},playMusic:function(e){this.enabled&&e&&e.sound&&(e.sound.fadingOut?this.fadeInMusic(e):(e.sound.volume=1,e.sound.play()),this.currentMusic=e)},resetMusic:function(e){e&&e.sound&&e.sound.readyState>0&&(e.sound.pause(),e.sound.currentTime=0)},fadeOutMusic:function(e,t){var n=this;e&&!e.sound.fadingOut&&(this.clearFadeIn(e),e.sound.fadingOut=setInterval(function(){var r=.02;volume=e.sound.volume-r,n.enabled&&volume>=r?e.sound.volume=volume:(e.sound.volume=0,n.clearFadeOut(e),t(e))},50))},fadeInMusic:function(e){var t=this;e&&!e.sound.fadingIn&&(this.clearFadeOut(e),e.sound.fadingIn=setInterval(function(){var n=.01;volume=e.sound.volume+n,t.enabled&&volume<1-n?e.sound.volume=volume:(e.sound.volume=1,t.clearFadeIn(e))},30))},clearFadeOut:function(e){e.sound.fadingOut&&(clearInterval(e.sound.fadingOut),e.sound.fadingOut=null)},clearFadeIn:function(e){e.sound.fadingIn&&(clearInterval(e.sound.fadingIn),e.sound.fadingIn=null)},fadeOutCurrentMusic:function(){var e=this;this.currentMusic&&(this.fadeOutMusic(this.currentMusic,function(t){e.resetMusic(t)}),this.currentMusic=null)}});return t}),define("updater",["character","timer"],function(e,t){var n=Class.extend({init:function(e){this.game=e,this.playerAggroTimer=new t(1e3)},update:function(){this.updateZoning(),this.updateCharacters(),this.updatePlayerAggro(),this.updateTransitions(),this.updateAnimations(),this.updateAnimatedTiles(),this.updateChatBubbles(),this.updateInfos()},updateCharacters:function(){var t=this;this.game.forEachEntity(function(n){var r=n instanceof e;n.isLoaded&&(r&&(t.updateCharacter(n),t.game.onCharacterUpdate(n)),t.updateEntityFading(n))})},updatePlayerAggro:function(){var e=this.game.currentTime,t=this.game.player;t&&!t.isMoving()&&!t.isAttacking()&&this.playerAggroTimer.isOver(e)&&t.checkAggro()},updateEntityFading:function(e){if(e&&e.isFading){var t=1e3,n=this.game.currentTime,r=n-e.startFadingTime;r>t?(this.isFading=!1,e.fadingAlpha=1):e.fadingAlpha=r/t}},updateTransitions:function(){var e=this,t=null,n=this.game.currentZoning;this.game.forEachEntity(function(n){t=n.movement,t&&t.inProgress&&t.step(e.game.currentTime)}),n&&n.inProgress&&n.step(this.game.currentTime)},updateZoning:function(){var e=this.game,t=e.camera,n=e.currentZoning,r=3,i=16,s=500;if(n&&n.inProgress===!1){var o=this.game.zoningOrientation,u=endValue=offset=0,a=null,f=null;if(o===Types.Orientations.LEFT||o===Types.Orientations.RIGHT)offset=(t.gridW-2)*i,u=o===Types.Orientations.LEFT?t.x-i:t.x+i,endValue=o===Types.Orientations.LEFT?t.x-offset:t.x+offset,a=function(n){t.setPosition(n,t.y),e.initAnimatedTiles(),e.renderer.renderStaticCanvases()},f=function(){t.setPosition(n.endValue,t.y),e.endZoning()};else if(o===Types.Orientations.UP||o===Types.Orientations.DOWN)offset=(t.gridH-2)*i,u=o===Types.Orientations.UP?t.y-i:t.y+i,endValue=o===Types.Orientations.UP?t.y-offset:t.y+offset,a=function(n){t.setPosition(t.x,n),e.initAnimatedTiles(),e.renderer.renderStaticCanvases()},f=function(){t.setPosition(t.x,n.endValue),e.endZoning()};n.start(this.game.currentTime,a,f,u,endValue,s)}},updateCharacter:function(e){var t=this,n=Math.round(16/Math.round(e.moveSpeed/(1e3/this.game.renderer.FPS)));e.isMoving()&&e.movement.inProgress===!1&&(e.orientation===Types.Orientations.LEFT?e.movement.start(this.game.currentTime,function(t){e.x=t,e.hasMoved()},function(){e.x=e.movement.endValue,e.hasMoved(),e.nextStep()},e.x-n,e.x-16,e.moveSpeed):e.orientation===Types.Orientations.RIGHT?e.movement.start(this.game.currentTime,function(t){e.x=t,e.hasMoved()},function(){e.x=e.movement.endValue,e.hasMoved(),e.nextStep()},e.x+n,e.x+16,e.moveSpeed):e.orientation===Types.Orientations.UP?e.movement.start(this.game.currentTime,function(t){e.y=t,e.hasMoved()},function(){e.y=e.movement.endValue,e.hasMoved(),e.nextStep()},e.y-n,e.y-16,e.moveSpeed):e.orientation===Types.Orientations.DOWN&&e.movement.start(this.game.currentTime,function(t){e.y=t,e.hasMoved()},function(){e.y=e.movement.endValue,e.hasMoved(),e.nextStep()},e.y+n,e.y+16,e.moveSpeed))},updateAnimations:function(){var e=this.game.currentTime;this.game.forEachEntity(function(t){var n=t.currentAnimation;n&&n.update(e)&&t.setDirty()});var t=this.game.sparksAnimation;t&&t.update(e);var n=this.game.targetAnimation;n&&n.update(e)},updateAnimatedTiles:function(){var e=this,t=this.game.currentTime;this.game.forEachAnimatedTile(function(n){n.animate(t)&&(n.isDirty=!0,n.dirtyRect=e.game.renderer.getTileBoundingRect(n),(e.game.renderer.mobile||e.game.renderer.tablet)&&e.game.checkOtherDirtyRects(n.dirtyRect,n,n.x,n.y))})},updateChatBubbles:function(){var e=this.game.currentTime;this.game.bubbleManager.update(e)},updateInfos:function(){var e=this.game.currentTime;this.game.infoManager.update(e)}});return n}),define("lib/astar",[],function(){var e=function(){function e(e,t,n,r,i,s,o,u,a,f,l,c,h){return e&&(n&&!a[i][o]&&(c[h++]={x:o,y:i}),r&&!a[i][u]&&(c[h++]={x:u,y:i})),t&&(n&&!a[s][o]&&(c[h++]={x:o,y:s}),r&&!a[s][u]&&(c[h++]={x:u,y:s})),c}function t(e,t,n,r,i,s,o,u,a,f,l,c,h){return e=i>-1,t=s<f,n=o<l,r=u>-1,n&&(e&&!a[i][o]&&(c[h++]={x:o,y:i}),t&&!a[s][o]&&(c[h++]={x:o,y:s})),r&&(e&&!a[i][u]&&(c[h++]={x:u,y:i}),t&&!a[s][u]&&(c[h++]={x:u,y:s})),c}function n(e,t,n,r,i,s,o,u,a,f,l,c,h){return c}function r(e,t,n,r,i,s){var o=n-1,u=n+1,a=t+1,f=t-1,l=o>-1&&!r[o][t],c=u<i&&!r[u][t],h=a<s&&!r[n][a],p=f>-1&&!r[n][f],d=[],v=0;return l&&(d[v++]={x:t,y:o}),h&&(d[v++]={x:a,y:n}),c&&(d[v++]={x:t,y:u}),p&&(d[v++]={x:f,y:n}),e(l,c,h,p,o,u,a,f,r,i,s,d,v)}function i(e,t,n,r){return r(n(e.x-t.x),n(e.y-t.y))}function s(e,t,n,r){var i=e.x-t.x,s=e.y-t.y;return r(i*i+s*s)}function o(e,t,n,r){return n(e.x-t.x)+n(e.y-t.y)}function u(u,a,f,l){var c=u[0].length,h=u.length,p=c*h,d=Math.abs,v=Math.max,m={},g=[],y=[{x:a[0],y:a[1],f:0,g:0,v:a[0]+a[1]*c}],b=1,w,E,S,x,T,N,C,k,L;f={x:f[0],y:f[1],v:f[0]+f[1]*c};switch(l){case"Diagonal":S=e;case"DiagonalFree":E=i;break;case"Euclidean":S=e;case"EuclideanFree":v=Math.sqrt,E=s;break;default:E=o,S=n}S||(S=t);do{N=p,C=0;for(x=0;x<b;++x)(l=y[x].f)<N&&(N=l,C=x);k=y.splice(C,1)[0];if(k.v!=f.v){--b,L=r(S,k.x,k.y,u,h,c);for(x=0,T=L.length;x<T;++x)(w=L[x]).p=k,w.f=w.g=0,w.v=w.x+w.y*c,w.v in m||(w.f=(w.g=k.g+E(w,k,d,v))+E(w,f,d,v),y[b++]=w,m[w.v]=1)}else{x=b=0;do g[x++]=[k.x,k.y];while(k=k.p);g.reverse()}}while(b);return g}return u}();return e}),define("pathfinder",["lib/astar"],function(e){var t=Class.extend({init:function(e,t){this.width=e,this.height=t,this.grid=null,this.blankGrid=[],this.initBlankGrid_(),this.ignored=[]},initBlankGrid_:function(){for(var e=0;e<this.height;e+=1){this.blankGrid[e]=[];for(var t=0;t<this.width;t+=1)this.blankGrid[e][t]=0}},findPath:function(t,n,r,i,s){var o=[n.gridX,n.gridY],u=[r,i],a;return this.grid=t,this.applyIgnoreList_(!0),a=e(this.grid,o,u),a.length===0&&s===!0&&(a=this.findIncompletePath_(o,u)),a},findIncompletePath_:function(t,n){var r,i,s,o=[];r=e(this.blankGrid,t,n);for(var u=r.length-1;u>0;u-=1){i=r[u][0],s=r[u][1];if(this.grid[s][i]===0){o=e(this.grid,t,[i,s]);break}}return o},ignoreEntity:function(e){e&&this.ignored.push(e)},applyIgnoreList_:function(e){var t=this,n,r,i;_.each(this.ignored,function(i){n=i.isMoving()?i.nextGridX:i.gridX,r=i.isMoving()?i.nextGridY:i.gridY,n>=0&&r>=0&&(t.grid[r][n]=e?0:1)})},clearIgnoreList:function(){this.applyIgnoreList_(!1),this.ignored=[]}});return t}),define("text!../config/config_build.json",function(){return'{\n "host": "raspbiyou.ddns.net",\n "port": 8000\n}'}),define("config",["text!../config/config_build.json"],function(e){var t={dev:{host:"localhost",port:8e3,dispatcher:!1},build:JSON.parse(e)};return t}),Types={Messages:{HELLO:0,WELCOME:1,SPAWN:2,DESPAWN:3,MOVE:4,LOOTMOVE:5,AGGRO:6,ATTACK:7,HIT:8,HURT:9,HEALTH:10,CHAT:11,LOOT:12,EQUIP:13,DROP:14,TELEPORT:15,DAMAGE:16,POPULATION:17,KILL:18,LIST:19,WHO:20,ZONE:21,DESTROY:22,HP:23,BLINK:24,OPEN:25,CHECK:26},Entities:{WARRIOR:1,RAT:2,SKELETON:3,GOBLIN:4,OGRE:5,SPECTRE:6,CRAB:7,BAT:8,WIZARD:9,EYE:10,SNAKE:11,SKELETON2:12,BOSS:13,DEATHKNIGHT:14,FIREFOX:20,CLOTHARMOR:21,LEATHERARMOR:22,MAILARMOR:23,PLATEARMOR:24,REDARMOR:25,GOLDENARMOR:26,FLASK:35,BURGER:36,CHEST:37,FIREPOTION:38,CAKE:39,GUARD:40,KING:41,OCTOCAT:42,VILLAGEGIRL:43,VILLAGER:44,PRIEST:45,SCIENTIST:46,AGENT:47,RICK:48,NYAN:49,SORCERER:50,BEACHNPC:51,FORESTNPC:52,DESERTNPC:53,LAVANPC:54,CODER:55,SWORD1:60,SWORD2:61,REDSWORD:62,GOLDENSWORD:63,MORNINGSTAR:64,AXE:65,BLUESWORD:66},Orientations:{UP:1,DOWN:2,LEFT:3,RIGHT:4}};var kinds={warrior:[Types.Entities.WARRIOR,"player"],rat:[Types.Entities.RAT,"mob"],skeleton:[Types.Entities.SKELETON,"mob"],goblin:[Types.Entities.GOBLIN,"mob"],ogre:[Types.Entities.OGRE,"mob"],spectre:[Types.Entities.SPECTRE,"mob"],deathknight:[Types.Entities.DEATHKNIGHT,"mob"],crab:[Types.Entities.CRAB,"mob"],snake:[Types.Entities.SNAKE,"mob"],bat:[Types.Entities.BAT,"mob"],wizard:[Types.Entities.WIZARD,"mob"],eye:[Types.Entities.EYE,"mob"],skeleton2:[Types.Entities.SKELETON2,"mob"],boss:[Types.Entities.BOSS,"mob"],sword1:[Types.Entities.SWORD1,"weapon"],sword2:[Types.Entities.SWORD2,"weapon"],axe:[Types.Entities.AXE,"weapon"],redsword:[Types.Entities.REDSWORD,"weapon"],bluesword:[Types.Entities.BLUESWORD,"weapon"],goldensword:[Types.Entities.GOLDENSWORD,"weapon"],morningstar:[Types.Entities.MORNINGSTAR,"weapon"],firefox:[Types.Entities.FIREFOX,"armor"],clotharmor:[Types.Entities.CLOTHARMOR,"armor"],leatherarmor:[Types.Entities.LEATHERARMOR,"armor"],mailarmor:[Types.Entities.MAILARMOR,"armor"],platearmor:[Types.Entities.PLATEARMOR,"armor"],redarmor:[Types.Entities.REDARMOR,"armor"],goldenarmor:[Types.Entities.GOLDENARMOR,"armor"],flask:[Types.Entities.FLASK,"object"],cake:[Types.Entities.CAKE,"object"],burger:[Types.Entities.BURGER,"object"],chest:[Types.Entities.CHEST,"object"],firepotion:[Types.Entities.FIREPOTION,"object"],guard:[Types.Entities.GUARD,"npc"],villagegirl:[Types.Entities.VILLAGEGIRL,"npc"],villager:[Types.Entities.VILLAGER,"npc"],coder:[Types.Entities.CODER,"npc"],scientist:[Types.Entities.SCIENTIST,"npc"],priest:[Types.Entities.PRIEST,"npc"],king:[Types.Entities.KING,"npc"],rick:[Types.Entities.RICK,"npc"],nyan:[Types.Entities.NYAN,"npc"],sorcerer:[Types.Entities.SORCERER,"npc"],agent:[Types.Entities.AGENT,"npc"],octocat:[Types.Entities.OCTOCAT,"npc"],beachnpc:[Types.Entities.BEACHNPC,"npc"],forestnpc:[Types.Entities.FORESTNPC,"npc"],desertnpc:[Types.Entities.DESERTNPC,"npc"],lavanpc:[Types.Entities.LAVANPC,"npc"],getType:function(e){return kinds[Types.getKindAsString(e)][1]}};Types.rankedWeapons=[Types.Entities.SWORD1,Types.Entities.SWORD2,Types.Entities.AXE,Types.Entities.MORNINGSTAR,Types.Entities.BLUESWORD,Types.Entities.REDSWORD,Types.Entities.GOLDENSWORD],Types.rankedArmors=[Types.Entities.CLOTHARMOR,Types.Entities.LEATHERARMOR,Types.Entities.MAILARMOR,Types.Entities.PLATEARMOR,Types.Entities.REDARMOR,Types.Entities.GOLDENARMOR],Types.getWeaponRank=function(e){return _.indexOf(Types.rankedWeapons,e)},Types.getArmorRank=function(e){return _.indexOf(Types.rankedArmors,e)},Types.isPlayer=function(e){return kinds.getType(e)==="player"},Types.isMob=function(e){return kinds.getType(e)==="mob"},Types.isNpc=function(e){return kinds.getType(e)==="npc"},Types.isCharacter=function(e){return Types.isMob(e)||Types.isNpc(e)||Types.isPlayer(e)},Types.isArmor=function(e){return kinds.getType(e)==="armor"},Types.isWeapon=function(e){return kinds.getType(e)==="weapon"},Types.isObject=function(e){return kinds.getType(e)==="object"},Types.isChest=function(e){return e===Types.Entities.CHEST},Types.isItem=function(e){return Types.isWeapon(e)||Types.isArmor(e)||Types.isObject(e)&&!Types.isChest(e)},Types.isHealingItem=function(e){return e===Types.Entities.FLASK||e===Types.Entities.BURGER},Types.isExpendableItem=function(e){return Types.isHealingItem(e)||e===Types.Entities.FIREPOTION||e===Types.Entities.CAKE},Types.getKindFromString=function(e){if(e in kinds)return kinds[e][0]},Types.getKindAsString=function(e){for(var t in kinds)if(kinds[t][0]===e)return t},Types.forEachKind=function(e){for(var t in kinds)e(kinds[t][0],t)},Types.forEachArmor=function(e){Types.forEachKind(function(t,n){Types.isArmor(t)&&e(t,n)})},Types.forEachMobOrNpcKind=function(e){Types.forEachKind(function(t,n){(Types.isMob(t)||Types.isNpc(t))&&e(t,n)})},Types.forEachArmorKind=function(e){Types.forEachKind(function(t,n){Types.isArmor(t)&&e(t,n)})},Types.getOrientationAsString=function(e){switch(e){case Types.Orientations.LEFT:return"left";case Types.Orientations.RIGHT:return"right";case Types.Orientations.UP:return"up";case Types.Orientations.DOWN:return"down"}},Types.getRandomItemKind=function(e){var t=_.union(this.rankedWeapons,this.rankedArmors),n=[Types.Entities.SWORD1,Types.Entities.CLOTHARMOR],r=_.difference(t,n),i=Math.floor(Math.random()*_.size(r));return r[i]},Types.getMessageTypeAsString=function(e){var t;return _.each(Types.Messages,function(n,r){n===e&&(t=r)}),t||(t="UNKNOWN"),t},typeof exports!="undefined"&&(module.exports=Types),define("../../shared/js/gametypes",function(){}),define("game",["infomanager","bubble","renderer","map","animation","sprite","tile","warrior","gameclient","audio","updater","transition","pathfinder","item","mob","npc","player","character","chest","mobs","exceptions","config","../../shared/js/gametypes"],function(e,t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E){var S=Class.extend({init:function(t){this.app=t,this.app.config=E,this.ready=!1,this.started=!1,this.hasNeverStarted=!0,this.renderer=null,this.updater=null,this.pathfinder=null,this.chatinput=null,this.bubbleManager=null,this.audioManager=null,this.player=new u("player",""),this.entities={},this.deathpositions={},this.entityGrid=null,this.pathingGrid=null,this.renderingGrid=null,this.itemGrid=null,this.currentCursor=null,this.mouse={x:0,y:0},this.zoningQueue=[],this.previousClickPosition={},this.selectedX=0,this.selectedY=0,this.selectedCellVisible=!1,this.targetColor="rgba(255, 255, 255, 0.5)",this.targetCellVisible=!0,this.hoveringTarget=!1,this.hoveringMob=!1,this.hoveringItem=!1,this.hoveringCollidingTile=!1,this.infoManager=new e(this),this.currentZoning=null,this.cursors={},this.sprites={},this.animatedTiles=null,this.debugPathing=!1,this.spriteNames=["hand","sword","loot","target","talk","sparks","shadow16","rat","skeleton","skeleton2","spectre","boss","deathknight","ogre","crab","snake","eye","bat","goblin","wizard","guard","king","villagegirl","villager","coder","agent","rick","scientist","nyan","priest","sorcerer","octocat","beachnpc","forestnpc","desertnpc","lavanpc","clotharmor","leatherarmor","mailarmor","platearmor","redarmor","goldenarmor","firefox","death","sword1","axe","chest","sword2","redsword","bluesword","goldensword","item-sword2","item-axe","item-redsword","item-bluesword","item-goldensword","item-leatherarmor","item-mailarmor","item-platearmor","item-redarmor","item-goldenarmor","item-flask","item-cake","item-burger","morningstar","item-morningstar","item-firepotion"]},setup:function(e,r,i,s,o){this.setBubbleManager(new t(e)),this.setRenderer(new n(this,r,i,s)),this.setChatInput(o)},setStorage:function(e){this.storage=e},setRenderer:function(e){this.renderer=e},setUpdater:function(e){this.updater=e},setPathfinder:function(e){this.pathfinder=e},setChatInput:function(e){this.chatinput=e},setBubbleManager:function(e){this.bubbleManager=e},loadMap:function(){var e=this;this.map=new r(!this.renderer.upscaledRendering,this),this.map.ready(function(){log.info("Map loaded.");var t=e.renderer.upscaledRendering?0:e.renderer.scale-1;e.renderer.setTileset(e.map.tilesets[t])})},initPlayer:function(){this.storage.hasAlreadyPlayed()&&(this.player.setSpriteName(this.storage.data.player.armor),this.player.setWeaponName(this.storage.data.player.weapon)),this.player.setSprite(this.sprites[this.player.getSpriteName()]),this.player.idle(),log.debug("Finished initPlayer")},initShadows:function(){this.shadows={},this.shadows.small=this.sprites.shadow16},initCursors:function(){this.cursors.hand=this.sprites.hand,this.cursors.sword=this.sprites.sword,this.cursors.loot=this.sprites.loot,this.cursors.target=this.sprites.target,this.cursors.arrow=this.sprites.arrow,this.cursors.talk=this.sprites.talk},initAnimations:function(){this.targetAnimation=new i("idle_down",4,0,16,16),this.targetAnimation.setSpeed(50),this.sparksAnimation=new i("idle_down",6,0,16,16),this.sparksAnimation.setSpeed(120)},initHurtSprites:function(){var e=this;Types.forEachArmorKind(function(t,n){e.sprites[n].createHurtSprite()})},initSilhouettes:function(){var e=this;Types.forEachMobOrNpcKind(function(t,n){e.sprites[n].createSilhouette()}),e.sprites.chest.createSilhouette(),e.sprites["item-cake"].createSilhouette()},initAchievements:function(){var e=this;this.achievements={A_TRUE_WARRIOR:{id:1,name:"A True Warrior",desc:"Find a new weapon"},INTO_THE_WILD:{id:2,name:"Into the Wild",desc:"Venture outside the village"},ANGRY_RATS:{id:3,name:"Angry Rats",desc:"Kill 10 rats",isCompleted:function(){return e.storage.getRatCount()>=10}},SMALL_TALK:{id:4,name:"Small Talk",desc:"Talk to a non-player character"},FAT_LOOT:{id:5,name:"Fat Loot",desc:"Get a new armor set"},UNDERGROUND:{id:6,name:"Underground",desc:"Explore at least one cave"},AT_WORLDS_END:{id:7,name:"At World's End",desc:"Reach the south shore"},COWARD:{id:8,name:"Coward",desc:"Successfully escape an enemy"},TOMB_RAIDER:{id:9,name:"Tomb Raider",desc:"Find the graveyard"},SKULL_COLLECTOR:{id:10,name:"Skull Collector",desc:"Kill 10 skeletons",isCompleted:function(){return e.storage.getSkeletonCount()>=10}},NINJA_LOOT:{id:11,name:"Ninja Loot",desc:"Get hold of an item you didn't fight for"},NO_MANS_LAND:{id:12,name:"No Man's Land",desc:"Travel through the desert"},HUNTER:{id:13,name:"Hunter",desc:"Kill 50 enemies",isCompleted:function(){return e.storage.getTotalKills()>=50}},STILL_ALIVE:{id:14,name:"Still Alive",desc:"Revive your character five times",isCompleted:function(){return e.storage.getTotalRevives()>=5}},MEATSHIELD:{id:15,name:"Meatshield",desc:"Take 5,000 points of damage",isCompleted:function(){return e.storage.getTotalDamageTaken()>=5e3}},HOT_SPOT:{id:16,name:"Hot Spot",desc:"Enter the volcanic mountains"},HERO:{id:17,name:"Hero",desc:"Defeat the final boss"},FOXY:{id:18,name:"Foxy",desc:"Find the Firefox costume",hidden:!0},FOR_SCIENCE:{id:19,name:"For Science",desc:"Enter into a portal",hidden:!0},RICKROLLD:{id:20,name:"Rickroll'd",desc:"Take some singing lessons",hidden:!0}},_.each(this.achievements,function(e){e.isCompleted||(e.isCompleted=function(){return!0}),e.hidden||(e.hidden=!1)}),this.app.initAchievementList(this.achievements),this.storage.hasAlreadyPlayed()&&this.app.initUnlockedAchievements(this.storage.data.achievements.unlocked)},getAchievementById:function(e){var t=null;return _.each(this.achievements,function(n,r){n.id===parseInt(e)&&(t=n)}),t},loadSprite:function(e){this.renderer.upscaledRendering?this.spritesets[0][e]=new s(e,1):(this.spritesets[1][e]=new s(e,2),!this.renderer.mobile&&!this.renderer.tablet&&(this.spritesets[2][e]=new s(e,3)))},setSpriteScale:function(e){var t=this;this.renderer.upscaledRendering?this.sprites=this.spritesets[0]:(this.sprites=this.spritesets[e-1],_.each(this.entities,function(e){e.sprite=null,e.setSprite(t.sprites[e.getSpriteName()])}),this.initHurtSprites(),this.initShadows(),this.initCursors())},loadSprites:function(){log.info("Loading sprites..."),this.spritesets=[],this.spritesets[0]={},this.spritesets[1]={},this.spritesets[2]={},_.map(this.spriteNames,this.loadSprite,this)},spritesLoaded:function(){return _.any(this.sprites,function(e){return!e.isLoaded})?!1:!0},setCursor:function(e,t){e in this.cursors?(this.currentCursor=this.cursors[e],this.currentCursorOrientation=t):log.error("Unknown cursor name :"+e)},updateCursorLogic:function(){this.hoveringCollidingTile&&this.started?this.targetColor="rgba(255, 50, 50, 0.5)":this.targetColor="rgba(255, 255, 255, 0.5)",this.hoveringMob&&this.started?(this.setCursor("sword"),this.hoveringTarget=!1,this.targetCellVisible=!1):this.hoveringNpc&&this.started?(this.setCursor("talk"),this.hoveringTarget=!1,this.targetCellVisible=!1):(this.hoveringItem||this.hoveringChest)&&this.started?(this.setCursor("loot"),this.hoveringTarget=!1,this.targetCellVisible=!0):(this.setCursor("hand"),this.hoveringTarget=!1,this.targetCellVisible=!0)},focusPlayer:function(){this.renderer.camera.lookAt(this.player)},addEntity:function(e){var t=this;this.entities[e.id]===undefined?(this.entities[e.id]=e,this.registerEntityPosition(e),!(e instanceof p&&e.wasDropped)&&!this.renderer.mobile&&!this.renderer.tablet&&e.fadeIn(this.currentTime),(this.renderer.mobile||this.renderer.tablet)&&e.onDirty(function(e){t.camera.isVisible(e)&&(e.dirtyRect=t.renderer.getEntityBoundingRect(e),t.checkOtherDirtyRects(e.dirtyRect,e,e.gridX,e.gridY))})):log.error("This entity already exists : "+e.id+" ("+e.kind+")")},removeEntity:function(e){e.id in this.entities?(this.unregisterEntityPosition(e),delete this.entities[e.id]):log.error("Cannot remove entity. Unknown ID : "+e.id)},addItem:function(e,t,n){e.setSprite(this.sprites[e.getSpriteName()]),e.setGridPosition(t,n),e.setAnimation("idle",150),this.addEntity(e)},removeItem:function(e){e?(this.removeFromItemGrid(e,e.gridX,e.gridY),this.removeFromRenderingGrid(e,e.gridX,e.gridY),delete this.entities[e.id]):log.error("Cannot remove item. Unknown ID : "+e.id)},initPathingGrid:function(){this.pathingGrid=[];for(var e=0;e<this.map.height;e+=1){this.pathingGrid[e]=[];for(var t=0;t<this.map.width;t+=1)this.pathingGrid[e][t]=this.map.grid[e][t]}log.info("Initialized the pathing grid with static colliding cells.")},initEntityGrid:function(){this.entityGrid=[];for(var e=0;e<this.map.height;e+=1){this.entityGrid[e]=[];for(var t=0;t<this.map.width;t+=1)this.entityGrid[e][t]={}}log.info("Initialized the entity grid.")},initRenderingGrid:function(){this.renderingGrid=[];for(var e=0;e<this.map.height;e+=1){this.renderingGrid[e]=[];for(var t=0;t<this.map.width;t+=1)this.renderingGrid[e][t]={}}log.info("Initialized the rendering grid.")},initItemGrid:function(){this.itemGrid=[];for(var e=0;e<this.map.height;e+=1){this.itemGrid[e]=[];for(var t=0;t<this.map.width;t+=1)this.itemGrid[e][t]={}}log.info("Initialized the item grid.")},initAnimatedTiles:function(){var e=this,t=this.map;this.animatedTiles=[],this.forEachVisibleTile(function(n,r){if(t.isAnimatedTile(n)){var i=new o(n,t.getTileAnimationLength(n),t.getTileAnimationDelay(n),r),s=e.map.tileIndexToGridPosition(i.index);i.x=s.x,i.y=s.y,e.animatedTiles.push(i)}},1)},addToRenderingGrid:function(e,t,n){this.map.isOutOfBounds(t,n)||(this.renderingGrid[n][t][e.id]=e)},removeFromRenderingGrid:function(e,t,n){e&&this.renderingGrid[n][t]&&e.id in this.renderingGrid[n][t]&&delete this.renderingGrid[n][t][e.id]},removeFromEntityGrid:function(e,t,n){this.entityGrid[n][t][e.id]&&delete this.entityGrid[n][t][e.id]},removeFromItemGrid:function(e,t,n){e&&this.itemGrid[n][t][e.id]&&delete this.itemGrid[n][t][e.id]},removeFromPathingGrid:function(e,t){this.pathingGrid[t][e]=0},registerEntityDualPosition:function(e){e&&(this.entityGrid[e.gridY][e.gridX][e.id]=e,this.addToRenderingGrid(e,e.gridX,e.gridY),e.nextGridX>=0&&e.nextGridY>=0&&(this.entityGrid[e.nextGridY][e.nextGridX][e.id]=e,e instanceof m||(this.pathingGrid[e.nextGridY][e.nextGridX]=1)))},unregisterEntityPosition:function(e){e&&(this.removeFromEntityGrid(e,e.gridX,e.gridY),this.removeFromPathingGrid(e.gridX,e.gridY),this.removeFromRenderingGrid(e,e.gridX,e.gridY),e.nextGridX>=0&&e.nextGridY>=0&&(this.removeFromEntityGrid(e,e.nextGridX,e.nextGridY),this.removeFromPathingGrid(e.nextGridX,e.nextGridY)))},registerEntityPosition:function(e){var t=e.gridX,n=e.gridY;if(e){if(e instanceof g||e instanceof y)this.entityGrid[n][t][e.id]=e,e instanceof m||(this.pathingGrid[n][t]=1);e instanceof p&&(this.itemGrid[n][t][e.id]=e),this.addToRenderingGrid(e,t,n)}},setServerOptions:function(e,t,n){this.host=e,this.port=t,this.username=n},loadAudio:function(){this.audioManager=new f(this)},initMusicAreas:function(){var e=this;_.each(this.map.musicAreas,function(t){e.audioManager.addArea(t.x,t.y,t.w,t.h,t.id)})},run:function(e){var t=this;this.loadSprites(),this.setUpdater(new l(this)),this.camera=this.renderer.camera,this.setSpriteScale(this.renderer.scale);var n=setInterval(function(){t.map.isLoaded&&t.spritesLoaded()&&(t.ready=!0,log.debug("All sprites loaded."),t.loadAudio(),t.initMusicAreas(),t.initAchievements(),t.initCursors(),t.initAnimations(),t.initShadows(),t.initHurtSprites(),!t.renderer.mobile&&!t.renderer.tablet&&t.renderer.upscaledRendering&&t.initSilhouettes(),t.initEntityGrid(),t.initItemGrid(),t.initPathingGrid(),t.initRenderingGrid(),t.setPathfinder(new h(t.map.width,t.map.height)),t.initPlayer(),t.setCursor("hand"),t.connect(e),clearInterval(n))},100)},tick:function(){this.currentTime=(new Date).getTime(),this.started&&(this.updateCursorLogic(),this.updater.update(),this.renderer.renderFrame()),this.isStopped||requestAnimFrame(this.tick.bind(this))},start:function(){this.tick(),this.hasNeverStarted=!1,log.info("Game loop started.")},stop:function(){log.info("Game stopped."),this.isStopped=!0},entityIdExists:function(e){return e in this.entities},getEntityById:function(e){if(e in this.entities)return this.entities[e];log.error("Unknown entity id : "+e,!0)},connect:function(e){var t=this,n=!1;this.client=new a(this.host,this.port),n||this.client.connect(!0),this.client.onDispatched(function(e,n){log.debug("Dispatched to game server "+e+":"+n),t.client.host=e,t.client.port=n,t.client.connect()}),this.client.onConnected(function(){log.info("Starting client/server handshake"),t.player.name=t.username,t.started=!0,t.sendHello(t.player)}),this.client.onEntityList(function(e){var n=_.pluck(t.entities,"id"),r=_.intersection(n,e),i=_.difference(e,r);t.obsoleteEntities=_.reject(t.entities,function(e){return _.include(r,e.id)||e.id===t.player.id}),t.removeObsoleteEntities(),_.size(i)>0&&t.client.sendWho(i)}),this.client.onWelcome(function(n,r,i,s,o){log.info("Received player ID from server : "+n),t.player.id=n,t.playerId=n,t.player.name=r,t.player.setGridPosition(i,s),t.player.setMaxHitPoints(o),t.updateBars(),t.resetCamera(),t.updatePlateauMode(),t.audioManager.updateMusic(),t.addEntity(t.player),t.player.dirtyRect=t.renderer.getEntityBoundingRect(t.player),setTimeout(function(){t.tryUnlockingAchievement("STILL_ALIVE")},1500),t.storage.hasAlreadyPlayed()?(t.showNotification("Welcome back to BrowserQuest!"),t.storage.setPlayerName(r)):(t.storage.initPlayer(t.player.name),t.storage.savePlayer(t.renderer.getPlayerImage(),t.player.getSpriteName(),t.player.getWeaponName()),t.showNotification("Welcome to BrowserQuest!")),t.player.onStartPathing(function(e){var n=e.length-1,r=e[n][0],i=e[n][1];t.player.isMovingToLoot()?t.player.isLootMoving=!1:t.player.isAttacking()||t.client.sendMove(r,i),t.selectedX=r,t.selectedY=i,t.selectedCellVisible=!0;if(t.renderer.mobile||t.renderer.tablet)t.drawTarget=!0,t.clearTarget=!0,t.renderer.targetRect=t.renderer.getTargetBoundingRect(),t.checkOtherDirtyRects(t.renderer.targetRect,null,t.selectedX,t.selectedY)}),t.player.onCheckAggro(function(){t.forEachMob(function(e){e.isAggressive&&!e.isAttacking()&&t.player.isNear(e,e.aggroRange)&&t.player.aggro(e)})}),t.player.onAggro(function(e){!e.isWaitingToAttack(t.player)&&!t.player.isAttackedBy(e)&&(t.player.log_info("Aggroed by "+e.id+" at ("+t.player.gridX+", "+t.player.gridY+")"),t.client.sendAggro(e),e.waitToAttack(t.player))}),t.player.onBeforeStep(function(){var e=t.getEntityAt(t.player.nextGridX,t.player.nextGridY);e&&e.id!==t.playerId&&log.debug("Blocked by "+e.id),t.unregisterEntityPosition(t.player)}),t.player.onStep(function(){t.player.hasNextStep()&&t.registerEntityDualPosition(t.player),t.isZoningTile(t.player.gridX,t.player.gridY)&&t.enqueueZoningFrom(t.player.gridX,t.player.gridY),t.player.forEachAttacker(function(e){e.isAdjacent(e.target)?e.lookAtTarget():e.follow(t.player)}),(t.player.gridX<=85&&t.player.gridY<=179&&t.player.gridY>178||t.player.gridX<=85&&t.player.gridY<=266&&t.player.gridY>265)&&t.tryUnlockingAchievement("INTO_THE_WILD"),t.player.gridX<=85&&t.player.gridY<=293&&t.player.gridY>292&&t.tryUnlockingAchievement("AT_WORLDS_END"),t.player.gridX<=85&&t.player.gridY<=100&&t.player.gridY>99&&t.tryUnlockingAchievement("NO_MANS_LAND"),t.player.gridX<=85&&t.player.gridY<=51&&t.player.gridY>50&&t.tryUnlockingAchievement("HOT_SPOT"),t.player.gridX<=27&&t.player.gridY<=123&&t.player.gridY>112&&t.tryUnlockingAchievement("TOMB_RAIDER"),t.updatePlayerCheckpoint(),t.player.isDead||t.audioManager.updateMusic()}),t.player.onStopPathing(function(e,n){t.player.hasTarget()&&t.player.lookAtTarget(),t.selectedCellVisible=!1;if(t.isItemAt(e,n)){var r=t.getItemAt(e,n);try{t.player.loot(r),t.client.sendLoot(r),t.removeItem(r),t.showNotification(r.getLootMessage()),r.type==="armor"&&t.tryUnlockingAchievement("FAT_LOOT"),r.type==="weapon"&&t.tryUnlockingAchievement("A_TRUE_WARRIOR"),r.kind===Types.Entities.CAKE&&t.tryUnlockingAchievement("FOR_SCIENCE"),r.kind===Types.Entities.FIREPOTION&&(t.tryUnlockingAchievement("FOXY"),t.audioManager.playSound("firefox")),Types.isHealingItem(r.kind)?t.audioManager.playSound("heal"):t.audioManager.playSound("loot"),r.wasDropped&&!_(r.playersInvolved).include(t.playerId)&&t.tryUnlockingAchievement("NINJA_LOOT")}catch(i){if(!(i instanceof w.LootException))throw i;t.showNotification(i.message),t.audioManager.playSound("noloot")}}if(!t.player.hasTarget()&&t.map.isDoor(e,n)){var s=t.map.getDoorDestination(e,n);t.player.setGridPosition(s.x,s.y),t.player.nextGridX=s.x,t.player.nextGridY=s.y,t.player.turnTo(s.orientation),t.client.sendTeleport(s.x,s.y),t.renderer.mobile&&s.cameraX&&s.cameraY?(t.camera.setGridPosition(s.cameraX,s.cameraY),t.resetZone()):s.portal?t.assignBubbleTo(t.player):(t.camera.focusEntity(t.player),t.resetZone()),_.size(t.player.attackers)>0&&setTimeout(function(){t.tryUnlockingAchievement("COWARD")},500),t.player.forEachAttacker(function(e){e.disengage(),e.idle()}),t.updatePlateauMode(),t.checkUndergroundAchievement(),(t.renderer.mobile||t.renderer.tablet)&&t.renderer.clearScreen(t.renderer.context),s.portal&&t.audioManager.playSound("teleport"),t.player.isDead||t.audioManager.updateMusic()}t.player.target instanceof v?t.makeNpcTalk(t.player.target):t.player.target instanceof y&&(t.client.sendOpen(t.player.target),t.audioManager.playSound("chest")),t.player.forEachAttacker(function(e){e.isAdjacentNonDiagonal(t.player)||e.follow(t.player)}),t.unregisterEntityPosition(t.player),t.registerEntityPosition(t.player)}),t.player.onRequestPath(function(e,n){var r=[t.player];return t.player.hasTarget()&&r.push(t.player.target),t.findPath(t.player,e,n,r)}),t.player.onDeath(function(){log.info(t.playerId+" is dead"),t.player.stopBlinking(),t.player.setSprite(t.sprites.death),t.player.animate("death",120,1,function(){log.info(t.playerId+" was removed"),t.removeEntity(t.player),t.removeFromRenderingGrid(t.player,t.player.gridX,t.player.gridY),t.player=null,t.client.disable(),setTimeout(function(){t.playerdeath_callback()},1e3)}),t.player.forEachAttacker(function(e){e.disengage(),e.idle()}),t.audioManager.fadeOutCurrentMusic(),t.audioManager.playSound("death")}),t.player.onHasMoved(function(e){t.assignBubbleTo(e)}),t.player.onArmorLoot(function(e){t.player.switchArmor(t.sprites[e])}),t.player.onSwitchItem(function(){t.storage.savePlayer(t.renderer.getPlayerImage(),t.player.getArmorName(),t.player.getWeaponName()),t.equipment_callback&&t.equipment_callback()}),t.player.onInvincible(function(){t.invincible_callback(),t.player.switchArmor(t.sprites.firefox)}),t.client.onSpawnItem(function(e,n,r){log.info("Spawned "+Types.getKindAsString(e.kind)+" ("+e.id+") at "+n+", "+r),t.addItem(e,n,r)}),t.client.onSpawnChest(function(e,n,r){log.info("Spawned chest ("+e.id+") at "+n+", "+r),e.setSprite(t.sprites[e.getSpriteName()]),e.setGridPosition(n,r),e.setAnimation("idle_down",150),t.addEntity(e,n,r),e.onOpen(function(){e.stopBlinking(),e.setSprite(t.sprites.death),e.setAnimation("death",120,1,function(){log.info(e.id+" was removed"),t.removeEntity(e),t.removeFromRenderingGrid(e,e.gridX,e.gridY),t.previousClickPosition={}})})}),t.client.onSpawnCharacter(function(e,n,r,i,s){if(!t.entityIdExists(e.id))try{if(e.id!==t.playerId){e.setSprite(t.sprites[e.getSpriteName()]),e.setGridPosition(n,r),e.setOrientation(i),e.idle(),t.addEntity(e),log.debug("Spawned "+Types.getKindAsString(e.kind)+" ("+e.id+") at "+e.gridX+", "+e.gridY);if(e instanceof g){e.onBeforeStep(function(){t.unregisterEntityPosition(e)}),e.onStep(function(){e.isDying||(t.registerEntityDualPosition(e),e.forEachAttacker(function(t){t.isAdjacent(t.target)?t.lookAtTarget():t.follow(e)}))}),e.onStopPathing(function(n,r){if(!e.isDying){e.hasTarget()&&e.isAdjacent(e.target)&&e.lookAtTarget();if(e instanceof m){var i=e.destination.gridX,s=e.destination.gridY;if(t.map.isDoor(i,s)){var o=t.map.getDoorDestination(i,s);e.setGridPosition(o.x,o.y)}}e.forEachAttacker(function(n){!n.isAdjacentNonDiagonal(e)&&n.id!==t.playerId&&n.follow(e)}),t.unregisterEntityPosition(e),t.registerEntityPosition(e)}}),e.onRequestPath(function(n,r){var i=[e],s=function(e){i.push(e),e.forEachAttacker(function(e){i.push(e)})};return e.hasTarget()?s(e.target):e.previousTarget&&s(e.previousTarget),t.findPath(e,n,r,i)}),e.onDeath(function(){log.info(e.id+" is dead"),e instanceof d&&(t.deathpositions[e.id]={x:e.gridX,y:e.gridY}),e.isDying=!0,e.setSprite(t.sprites[e instanceof b.Rat?"rat":"death"]),e.animate("death",120,1,function(){log.info(e.id+" was removed"),t.removeEntity(e),t.removeFromRenderingGrid(e,e.gridX,e.gridY)}),e.forEachAttacker(function(e){e.disengage()}),t.player.target&&t.player.target.id===e.id&&t.player.disengage(),t.removeFromEntityGrid(e,e.gridX,e.gridY),t.removeFromPathingGrid(e.gridX,e.gridY),t.camera.isVisible(e)&&t.audioManager.playSound("kill"+Math.floor(Math.random()*2+1)),t.updateCursor()}),e.onHasMoved(function(e){t.assignBubbleTo(e)});if(e instanceof d&&s){var o=t.getEntityById(s);o&&t.createAttackLink(e,o)}}}}catch(u){log.error(u)}else log.debug("Character "+e.id+" already exists. Don't respawn.")}),t.client.onDespawnEntity(function(e){var n=t.getEntityById(e);n&&(log.info("Despawning "+Types.getKindAsString(n.kind)+" ("+n.id+")"),n.gridX===t.previousClickPosition.x&&n.gridY===t.previousClickPosition.y&&(t.previousClickPosition={}),n instanceof p?t.removeItem(n):n instanceof g?(n.forEachAttacker(function(e){e.canReachTarget()&&e.hit()}),n.die()):n instanceof y&&n.open(),n.clean())}),t.client.onItemBlink(function(e){var n=t.getEntityById(e);n&&n.blink(150)}),t.client.onEntityMove(function(e,n,r){var i=null;e!==t.playerId&&(i=t.getEntityById(e),i&&(t.player.isAttackedBy(i)&&t.tryUnlockingAchievement("COWARD"),i.disengage(),i.idle(),t.makeCharacterGoTo(i,n,r)))}),t.client.onEntityDestroy(function(e){var n=t.getEntityById(e);n&&(n instanceof p?t.removeItem(n):t.removeEntity(n),log.debug("Entity was destroyed: "+n.id))}),t.client.onPlayerMoveToItem(function(e,n){var r,i;e!==t.playerId&&(r=t.getEntityById(e),i=t.getEntityById(n),r&&i&&t.makeCharacterGoTo(r,i.gridX,i.gridY))}),t.client.onEntityAttack(function(e,n){var r=t.getEntityById(e),i=t.getEntityById(n);r&&i&&r.id!==t.playerId&&(log.debug(r.id+" attacks "+i.id),r&&i instanceof m&&i.id!==t.playerId&&i.target&&i.target.id===r.id&&r.getDistanceToEntity(i)<3?setTimeout(function(){t.createAttackLink(r,i)},200):t.createAttackLink(r,i))}),t.client.onPlayerDamageMob(function(e,n){var r=t.getEntityById(e);r&&n&&t.infoManager.addDamageInfo(n,r.x,r.y-15,"inflicted")}),t.client.onPlayerKillMob(function(e){var n=Types.getKindAsString(e);n==="skeleton2"&&(n="greater skeleton"),n==="eye"&&(n="evil eye"),n==="deathknight"&&(n="death knight"),n==="boss"?t.showNotification("You killed the skeleton king"):_.include(["a","e","i","o","u"],n[0])?t.showNotification("You killed an "+n):t.showNotification("You killed a "+n),t.storage.incrementTotalKills(),t.tryUnlockingAchievement("HUNTER"),e===Types.Entities.RAT&&(t.storage.incrementRatCount(),t.tryUnlockingAchievement("ANGRY_RATS"));if(e===Types.Entities.SKELETON||e===Types.Entities.SKELETON2)t.storage.incrementSkeletonCount(),t.tryUnlockingAchievement("SKULL_COLLECTOR");e===Types.Entities.BOSS&&t.tryUnlockingAchievement("HERO")}),t.client.onPlayerChangeHealth(function(e,n){var r=t.player,i,s;r&&!r.isDead&&!r.invincible&&(s=e<=r.hitPoints,i=e-r.hitPoints,r.hitPoints=e,r.hitPoints<=0&&r.die(),s?(r.hurt(),t.infoManager.addDamageInfo(i,r.x,r.y-15,"received"),t.audioManager.playSound("hurt"),t.storage.addDamage(-i),t.tryUnlockingAchievement("MEATSHIELD"),t.playerhurt_callback&&t.playerhurt_callback()):n||t.infoManager.addDamageInfo("+"+i,r.x,r.y-15,"healed"),t.updateBars())}),t.client.onPlayerChangeMaxHitPoints(function(e){t.player.maxHitPoints=e,t.player.hitPoints=e,t.updateBars()}),t.client.onPlayerEquipItem(function(e,n){var r=t.getEntityById(e),i=Types.getKindAsString(n);r&&(Types.isArmor(n)?r.setSprite(t.sprites[i]):Types.isWeapon(n)&&r.setWeaponName(i))}),t.client.onPlayerTeleport(function(e,n,r){var i=null,s;e!==t.playerId&&(i=t.getEntityById(e),i&&(s=i.orientation,t.makeCharacterTeleportTo(i,n,r),i.setOrientation(s),i.forEachAttacker(function(e){e.disengage(),e.idle(),e.stop()})))}),t.client.onDropItem(function(e,n){var r=t.getDeadMobPosition(n);r&&(t.addItem(e,r.x,r.y),t.updateCursor())}),t.client.onChatMessage(function(e,n){var r=t.getEntityById(e);t.createBubble(e,n),t.assignBubbleTo(r),t.audioManager.playSound("chat")}),t.client.onPopulationChange(function(e,n){t.nbplayers_callback&&t.nbplayers_callback(e,n)}),t.client.onDisconnected(function(e){t.player&&t.player.die(),t.disconnect_callback&&t.disconnect_callback(e)}),t.gamestart_callback(),t.hasNeverStarted&&(t.start(),e())})},createAttackLink:function(e,t){e.hasTarget()&&e.removeTarget(),e.engage(t),e.id!==this.playerId&&t.addAttacker(e)},sendHello:function(){this.client.sendHello(this.player)},getMouseGridPosition:function(){var e=this.mouse.x,t=this.mouse.y,n=this.renderer.camera,r=this.renderer.scale,i=this.renderer.tilesize,s=e%(i*r),o=t%(i*r),u=(e-s)/(i*r)+n.gridX,a=(t-o)/(i*r)+n.gridY;return{x:u,y:a}},makeCharacterGoTo:function(e,t,n){this.map.isOutOfBounds(t,n)||e.go(t,n)},makeCharacterTeleportTo:function(e,t,n){this.map.isOutOfBounds(t,n)?log.debug("Teleport out of bounds: "+t+", "+n):(this.unregisterEntityPosition(e),e.setGridPosition(t,n),this.registerEntityPosition(e),this.assignBubbleTo(e))},makePlayerGoTo:function(e,t){this.makeCharacterGoTo(this.player,e,t)},makePlayerGoToItem:function(e){e&&(this.player.isLootMoving=!0,this.makePlayerGoTo(e.gridX,e.gridY),this.client.sendLootMove(e,e.gridX,e.gridY))},makePlayerTalkTo:function(e){e&&(this.player.setTarget(e),this.player.follow(e))},makePlayerOpenChest:function(e){e&&(this.player.setTarget(e),this.player.follow(e))},makePlayerAttack:function(e){this.createAttackLink(this.player,e),this.client.sendAttack(e)},makeNpcTalk:function(e){var t;e&&(t=e.talk(),this.previousClickPosition={},t?(this.createBubble(e.id,t),this.assignBubbleTo(e),this.audioManager.playSound("npc")):(this.destroyBubble(e.id),this.audioManager.playSound("npc-end")),this.tryUnlockingAchievement("SMALL_TALK"),e.kind===Types.Entities.RICK&&this.tryUnlockingAchievement("RICKROLLD"))},forEachEntity:function(e){_.each(this.entities,function(t){e(t)})},forEachMob:function(e){_.each(this.entities,function(t){t instanceof d&&e(t)})},forEachVisibleEntityByDepth:function(e){var t=this,n=this.map;this.camera.forEachVisiblePosition(function(r,i){n.isOutOfBounds(r,i)||t.renderingGrid[i][r]&&_.each(t.renderingGrid[i][r],function(t){e(t)})},this.renderer.mobile?0:2)},forEachVisibleTileIndex:function(e,t){var n=this.map;this.camera.forEachVisiblePosition(function(t,r){n.isOutOfBounds(t,r)||e(n.GridPositionToTileIndex(t,r)-1)},t)},forEachVisibleTile:function(e,t){var n=this,r=this.map;r.isLoaded&&this.forEachVisibleTileIndex(function(t){_.isArray(r.data[t])?_.each(r.data[t],function(n){e(n-1,t)}):_.isNaN(r.data[t]-1)||e(r.data[t]-1,t)},t)},forEachAnimatedTile:function(e){this.animatedTiles&&_.each(this.animatedTiles,function(t){e(t)})},getEntityAt:function(e,t){if(this.map.isOutOfBounds(e,t)||!this.entityGrid)return null;var n=this.entityGrid[t][e],r=null;return _.size(n)>0?r=n[_.keys(n)[0]]:r=this.getItemAt(e,t),r},getMobAt:function(e,t){var n=this.getEntityAt(e,t);return n&&n instanceof d?n:null},getNpcAt:function(e,t){var n=this.getEntityAt(e,t);return n&&n instanceof v?n:null},getChestAt:function(e,t){var n=this.getEntityAt(e,t);return n&&n instanceof y?n:null},getItemAt:function(e,t){if(this.map.isOutOfBounds(e,t)||!this.itemGrid)return null;var n=this.itemGrid[t][e],r=null;return _.size(n)>0&&(_.each(n,function(e){Types.isExpendableItem(e.kind)&&(r=e)}),r||(r=n[_.keys(n)[0]])),r},isEntityAt:function(e,t){return!_.isNull(this.getEntityAt(e,t))},isMobAt:function(e,t){return!_.isNull(this.getMobAt(e,t))},isItemAt:function(e,t){return!_.isNull(this.getItemAt(e,t))},isNpcAt:function(e,t){return!_.isNull(this.getNpcAt(e,t))},isChestAt:function(e,t){return!_.isNull(this.getChestAt(e,t))},findPath:function(e,t,n,r){var i=this,s=this.pathingGrid;return path=[],isPlayer=e===this.player,this.map.isColliding(t,n)?path:(this.pathfinder&&e?(r&&_.each(r,function(e){i.pathfinder.ignoreEntity(e)}),path=this.pathfinder.findPath(s,e,t,n,!1),r&&this.pathfinder.clearIgnoreList()):log.error("Error while finding the path to "+t+", "+n+" for "+e.id),path)},togglePathingGrid:function(){this.debugPathing?this.debugPathing=!1:this.debugPathing=!0},toggleDebugInfo:function(){this.renderer&&this.renderer.isDebugInfoVisible?this.renderer.isDebugInfoVisible=!1:this.renderer.isDebugInfoVisible=!0},movecursor:function(){var e=this.getMouseGridPosition(),t=e.x,n=e.y;if(this.player&&!this.renderer.mobile&&!this.renderer.tablet){this.hoveringCollidingTile=this.map.isColliding(t,n),this.hoveringPlateauTile=this.player.isOnPlateau?!this.map.isPlateau(t,n):this.map.isPlateau(t,n),this.hoveringMob=this.isMobAt(t,n),this.hoveringItem=this.isItemAt(t,n),this.hoveringNpc=this.isNpcAt(t,n),this.hoveringChest=this.isChestAt(t,n);if(this.hoveringMob||this.hoveringNpc||this.hoveringChest){var r=this.getEntityAt(t,n);!r.isHighlighted&&this.renderer.supportsSilhouettes&&(this.lastHovered&&this.lastHovered.setHighlight(!1),this.lastHovered=r,r.setHighlight(!0))}else this.lastHovered&&(this.lastHovered.setHighlight(!1),this.lastHovered=null)}},click:function(){var e=this.getMouseGridPosition(),t;if(e.x===this.previousClickPosition.x&&e.y===this.previousClickPosition.y)return;this.previousClickPosition=e,this.started&&this.player&&!this.isZoning()&&!this.isZoningTile(this.player.nextGridX,this.player.nextGridY)&&!this.player.isDead&&!this.hoveringCollidingTile&&!this.hoveringPlateauTile&&(t=this.getEntityAt(e.x,e.y),t instanceof d?this.makePlayerAttack(t):t instanceof p?this.makePlayerGoToItem(t):t instanceof v?this.player.isAdjacentNonDiagonal(t)===!1?this.makePlayerTalkTo(t):this.makeNpcTalk(t):t instanceof y?this.makePlayerOpenChest(t):this.makePlayerGoTo(e.x,e.y))},isMobOnSameTile:function(e,t,n){var r=t||e.gridX,i=n||e.gridY,s=this.entityGrid[i][r],o=!1;return _.each(s,function(t){t instanceof d&&t.id!==e.id&&(o=!0)}),o},getFreeAdjacentNonDiagonalPosition:function(e){var t=this,n=null;return e.forEachAdjacentNonDiagonalPosition(function(e,r,i){!n&&!t.map.isColliding(e,r)&&!t.isMobAt(e,r)&&(n={x:e,y:r,o:i})}),n},tryMovingToADifferentTile:function(e){var t=e,n=e.target;if(t&&n&&n instanceof m){if(!n.isMoving()&&t.getDistanceToEntity(n)===0){var r;switch(n.orientation){case Types.Orientations.UP:r={x:n.gridX,y:n.gridY-1,o:n.orientation};break;case Types.Orientations.DOWN:r={x:n.gridX,y:n.gridY+1,o:n.orientation};break;case Types.Orientations.LEFT:r={x:n.gridX-1,y:n.gridY,o:n.orientation};break;case Types.Orientations.RIGHT:r={x:n.gridX+1,y:n.gridY,o:n.orientation}}if(r)return t.previousTarget=n,t.disengage(),t.idle(),this.makeCharacterGoTo(t,r.x,r.y),n.adjacentTiles[r.o]=!0,!0}if(!n.isMoving()&&t.isAdjacentNonDiagonal(n)&&this.isMobOnSameTile(t)){var r=this.getFreeAdjacentNonDiagonalPosition(n);if(r&&!n.adjacentTiles[r.o])return this.player.target&&t.id===this.player.target.id?!1:(t.previousTarget=n,t.disengage(),t.idle(),this.makeCharacterGoTo(t,r.x,r.y),n.adjacentTiles[r.o]=!0,!0)}}return!1},onCharacterUpdate:function(e){var t=this.currentTime,n=this;if(e.previousTarget&&!e.isMoving()&&e instanceof d){var r=e.previousTarget;if(this.getEntityById(r.id)){e.previousTarget=null,this.createAttackLink(e,r);return}}if(e.isAttacking()&&!e.previousTarget){var i=this.tryMovingToADifferentTile(e);e.canAttack(t)?i||(e.hasTarget()&&e.getOrientationTo(e.target)!==e.orientation&&e.lookAtTarget(),e.hit(),e.id===this.playerId&&this.client.sendHit(e.target),e instanceof m&&this.camera.isVisible(e)&&this.audioManager.playSound("hit"+Math.floor(Math.random()*2+1)),e.hasTarget()&&e.target.id===this.playerId&&this.player&&!this.player.invincible&&this.client.sendHurt(e)):e.hasTarget()&&e.isDiagonallyAdjacent(e.target)&&e.target instanceof m&&!e.target.isMoving()&&e.follow(e.target)}},isZoningTile:function(e,t){var n=this.camera;return e-=n.gridX,t-=n.gridY,e===0||t===0||e===n.gridW-1||t===n.gridH-1?!0:!1},getZoningOrientation:function(e,t){var n="",r=this.camera;return e-=r.gridX,t-=r.gridY,e===0?n=Types.Orientations.LEFT:t===0?n=Types.Orientations.UP:e===r.gridW-1?n=Types.Orientations.RIGHT:t===r.gridH-1&&(n=Types.Orientations.DOWN),n},startZoningFrom:function(e,t){this.zoningOrientation=this.getZoningOrientation(e,t);if(this.renderer.mobile||this.renderer.tablet){var n=this.zoningOrientation,r=this.camera,i=this.renderer.tilesize,e=r.x,t=r.y,s=(r.gridW-2)*i,o=(r.gridH-2)*i;if(n===Types.Orientations.LEFT||n===Types.Orientations.RIGHT)e=n===Types.Orientations.LEFT?r.x-s:r.x+s;else if(n===Types.Orientations.UP||n===Types.Orientations.DOWN)t=n===Types.Orientations.UP?r.y-o:r.y+o;r.setPosition(e,t),this.renderer.clearScreen(this.renderer.context),this.endZoning(),this.forEachVisibleEntityByDepth(function(e){e.setDirty()})}else this.currentZoning=new c;this.bubbleManager.clean(),this.client.sendZone()},enqueueZoningFrom:function(e,t){this.zoningQueue.push({x:e,y:t}),this.zoningQueue.length===1&&this.startZoningFrom(e,t)},endZoning:function(){this.currentZoning=null,this.resetZone(),this.zoningQueue.shift();if(this.zoningQueue.length>0){var e=this.zoningQueue[0];this.startZoningFrom(e.x,e.y)}},isZoning:function(){return!_.isNull(this.currentZoning)},resetZone:function(){this.bubbleManager.clean(),this.initAnimatedTiles(),this.renderer.renderStaticCanvases()},resetCamera:function(){this.camera.focusEntity(this.player),this.resetZone()},say:function(e){this.client.sendChat(e)},createBubble:function(e,t){this.bubbleManager.create(e,t,this.currentTime)},destroyBubble:function(e){this.bubbleManager.destroyBubble(e)},assignBubbleTo:function(e){var t=this.bubbleManager.getBubbleById(e.id);if(t){var n=this.renderer.scale,r=16*n,i=(e.x-this.camera.x)*n,s=parseInt(t.element.css("width"))+24,o=s/2-r/2,u,a;e instanceof v?u=0:n===2?this.renderer.mobile?u=0:u=15:u=12,a=(e.y-this.camera.y)*n-r*2-u,t.element.css("left",i-o+"px"),t.element.css("top",a+"px")}},restart:function(){log.debug("Beginning restart"),this.entities={},this.initEntityGrid(),this.initPathingGrid(),this.initRenderingGrid(),this.player=new u("player",this.username),this.initPlayer(),this.started=!0,this.client.enable(),this.sendHello(this.player),this.storage.incrementRevives(),(this.renderer.mobile||this.renderer.tablet)&&this.renderer.clearScreen(this.renderer.context),log.debug("Finished restart")},onGameStart:function(e){this.gamestart_callback=e},onDisconnect:function(e){this.disconnect_callback=e},onPlayerDeath:function(e){this.playerdeath_callback=e},onPlayerHealthChange:function(e){this.playerhp_callback=e},onPlayerHurt:function(e){this.playerhurt_callback=e},onPlayerEquipmentChange:function(e){this.equipment_callback=e},onNbPlayersChange:function(e){this.nbplayers_callback=e},onNotification:function(e){this.notification_callback=e},onPlayerInvincible:function(e){this.invincible_callback=e},resize:function(){var e=this.camera.x,t=this.camera.y,n=this.renderer.scale,r=this.renderer.getScaleFactor();this.renderer.rescale(r),this.camera=this.renderer.camera,this.camera.setPosition(e,t),this.renderer.renderStaticCanvases()},updateBars:function(){this.player&&this.playerhp_callback&&this.playerhp_callback(this.player.hitPoints,this.player.maxHitPoints)},getDeadMobPosition:function(e){var t;return e in this.deathpositions&&(t=this.deathpositions[e],delete this.deathpositions[e]),t},onAchievementUnlock:function(e){this.unlock_callback=e},tryUnlockingAchievement:function(e){var t=null;e in this.achievements&&(t=this.achievements[e],t.isCompleted()&&this.storage.unlockAchievement(t.id)&&this.unlock_callback&&(this.unlock_callback(t.id,t.name,t.desc),this.audioManager.playSound("achievement")))},showNotification:function(e){this.notification_callback&&this.notification_callback(e)},removeObsoleteEntities:function(){var e=_.size(this.obsoleteEntities),t=this;e>0&&(_.each(this.obsoleteEntities,function(e){e.id!=t.player.id&&t.removeEntity(e)}),log.debug("Removed "+e+" entities: "+_.pluck(_.reject(this.obsoleteEntities,function(e){return e===t.player.id}),"id")),this.obsoleteEntities=null)},updateCursor:function(){this.movecursor(),this.updateCursorLogic()},updatePlateauMode:function(){this.map.isPlateau(this.player.gridX,this.player.gridY)?this.player.isOnPlateau=!0:this.player.isOnPlateau=!1},updatePlayerCheckpoint:function(){var e=this.map.getCurrentCheckpoint(this.player);if(e){var t=this.player.lastCheckpoint;if(!t||t&&t.id!==e.id)this.player.lastCheckpoint=e,this.client.sendCheck(e.id)}},checkUndergroundAchievement:function(){var e=this.audioManager.getSurroundingMusic(this.player);e&&e.name==="cave"&&this.tryUnlockingAchievement("UNDERGROUND")},forEachEntityAround:function(e,t,n,r){for(var i=e-n,s=e+n;i<=s;i+=1)for(var o=t-n,u=t+n;o<=u;o+=1)this.map.isOutOfBounds(i,o)||_.each(this.renderingGrid[o][i],function(e){r(e)})},checkOtherDirtyRects:function(e,t,n,r){var i=this.renderer;this.forEachEntityAround(n,r,2,function(n){if(t&&t.id&&n.id===t.id)return;if(!n.isDirty){var r=i.getEntityBoundingRect(n);i.isIntersecting(e,r)&&n.setDirty()}}),t&&!t.hasOwnProperty("index")&&this.forEachAnimatedTile(function(t){if(!t.isDirty){var n=i.getTileBoundingRect(t);i.isIntersecting(e,n)&&(t.isDirty=!0)}});if(!this.drawTarget&&this.selectedCellVisible){var s=i.getTargetBoundingRect();i.isIntersecting(e,s)&&(this.drawTarget=!0,this.renderer.targetRect=s)}}});return S});