<commit_before>/* ===========================================================
 * bootstrap-modal.js v2.1
 * ===========================================================
 * Copyright 2012 Jordan Schroter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

	"use strict"; // jshint ;_;

	/* MODAL CLASS DEFINITION
	* ====================== */

	var Modal = function (element, options) {
		this.init(element, options);
	};

	Modal.prototype = {

		constructor: Modal,

		init: function (element, options) {
			this.options = options;

			this.$element = $(element)
				.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));

			this.options.remote && this.$element.find('.modal-body').load(this.options.remote);

			var manager = typeof this.options.manager === 'function' ?
				this.options.manager.call(this) : this.options.manager;

			manager = manager.appendModal ?
				manager : $(manager).modalmanager().data('modalmanager');

			manager.appendModal(this);
		},

		toggle: function () {
			return this[!this.isShown ? 'show' : 'hide']();
		},

		show: function () {
			var e = $.Event('show');

			if (this.isShown) return;

			this.$element.triggerHandler(e);

			if (e.isDefaultPrevented()) return;

			this.escape();

			this.tab();

			this.options.loading && this.loading();
		},

		hide: function (e) {
			e && e.preventDefault();

			e = $.Event('hide');

			this.$element.triggerHandler(e);

			if (!this.isShown || e.isDefaultPrevented()) return (this.isShown = false);

			this.isShown = false;

			this.escape();

			this.tab();

			this.isLoading && this.loading();

			$(document).off('focusin.modal');

			this.$element
				.removeClass('in')
				.removeClass('animated')
				.removeClass(this.options.attentionAnimation)
				.removeClass('modal-overflow')
				.attr('aria-hidden', true);

			$.support.transition && this.$element.hasClass('fade') ?
				this.hideWithTransition() :
				this.hideModal();
		},

		layout: function () {
			var prop = this.options.height ? 'height' : 'max-height',
				value = this.options.height || this.options.maxHeight;

			if (this.options.width){
				this.$element.css('width', this.options.width);

				var that = this;
				this.$element.css('margin-left', function () {
					if (/%/ig.test(that.options.width)){
						return -(parseInt(that.options.width) / 2) + '%';
					} else {
						return -($(this).width() / 2) + 'px';
					}
				});
			} else {
				this.$element.css('width', '');
				this.$element.css('margin-left', '');
			}

			this.$element.find('.modal-body')
				.css('overflow', '')
				.css(prop, '');

			var modalOverflow = $(window).height() - 10 < this.$element.height();

			if (value){
				this.$element.find('.modal-body')
					.css('overflow', 'auto')
					.css(prop, value);
			}

			if (modalOverflow || this.options.modalOverflow) {
				this.$element
					.css('margin-top', 0)
					.addClass('modal-overflow');
			} else {
				this.$element
					.css('margin-top', 0 - this.$element.height() / 2)
					.removeClass('modal-overflow');
			}
		},

		tab: function () {
			var that = this;

			if (this.isShown && this.options.consumeTab) {
				this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
			    	if (e.keyCode && e.keyCode == 9){
						var $next = $(this),
							$rollover = $(this);

						that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) {
							if (!e.shiftKey){
						 		$next = $next.data('tabindex') < $(this).data('tabindex') ?
									$next = $(this) :
									$rollover = $(this);
							} else {
								$next = $next.data('tabindex') > $(this).data('tabindex') ?
									$next = $(this) :
									$rollover = $(this);
							}
						});

						$next[0] !== $(this)[0] ?
							$next.focus() : $rollover.focus();

						e.preventDefault();
					}
				});
			} else if (!this.isShown) {
				this.$element.off('keydown.tabindex.modal');
			}
		},

		escape: function () {
			var that = this;
			if (this.isShown && this.options.keyboard) {
				if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);

				this.$element.on('keyup.dismiss.modal', function (e) {
					e.which == 27 && that.hide();
				});
			} else if (!this.isShown) {
				this.$element.off('keyup.dismiss.modal')
			}
		},

		hideWithTransition: function () {
			var that = this
				, timeout = setTimeout(function () {
					that.$element.off($.support.transition.end);
					that.hideModal();
				}, 500);

			this.$element.one($.support.transition.end, function () {
				clearTimeout(timeout);
				that.hideModal();
			});
		},

		hideModal: function () {
			this.$element
				.hide()
				.triggerHandler('hidden');

			var prop = this.options.height ? 'height' : 'max-height';
			var value = this.options.height || this.options.maxHeight;

			if (value){
				this.$element.find('.modal-body')
					.css('overflow', '')
					.css(prop, '');
			}

		},

		removeLoading: function () {
			this.$loading.remove();
			this.$loading = null;
			this.isLoading = false;
		},

		loading: function (callback) {
			callback = callback || function () {};

			var animate = this.$element.hasClass('fade') ? 'fade' : '';

			if (!this.isLoading) {
				var doAnimate = $.support.transition && animate;

				this.$loading = $('
')
					.append(this.options.spinner)
					.appendTo(this.$element);

				if (doAnimate) this.$loading[0].offsetWidth; // force reflow

				this.$loading.addClass('in');

				this.isLoading = true;

				doAnimate ?
					this.$loading.one($.support.transition.end, callback) :
					callback();

			} else if (this.isLoading && this.$loading) {
				this.$loading.removeClass('in');

				var that = this;
				$.support.transition && this.$element.hasClass('fade')?
					this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
					that.removeLoading();

			} else if (callback) {
				callback(this.isLoading);
			}
		},

		focus: function () {
			var $focusElem = this.$element.find(this.options.focusOn);

			$focusElem = $focusElem.length ? $focusElem : this.$element;

			$focusElem.focus();
		},

		attention: function (){
			// NOTE: transitionEnd with keyframes causes odd behaviour

			if (this.options.attentionAnimation){
				this.$element
					.removeClass('animated')
					.removeClass(this.options.attentionAnimation);

				var that = this;

				setTimeout(function () {
					that.$element
						.addClass('animated')
						.addClass(that.options.attentionAnimation);
				}, 0);
			}

			this.focus();
		},

		destroy: function () {
			var e = $.Event('destroy');
			this.$element.triggerHandler(e);
			if (e.isDefaultPrevented()) return;

			this.teardown();
		},

		teardown: function () {
			if (!this.$parent.length){
				this.$element.remove();
				this.$element = null;
				return;
			}

			if (this.$parent !== this.$element.parent()){
				this.$element.appendTo(this.$parent);
			}

			this.$element.off('.modal');
			this.$element.removeData('modal');
			this.$element
				.removeClass('in')
				.attr('aria-hidden', true);
		}
	};

	/* MODAL PLUGIN DEFINITION
	* ======================= */

	$.fn.modal = function (option, args) {
		return this.each(function () {
			var $this = $(this),
				data = $this.data('modal'),
				options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);

			if (!data) $this.data('modal', (data = new Modal(this, options)));
			if (typeof option == 'string') data[option].apply(data, [].concat(args));
			else if (options.show) data.show()
		})
	};

	$.fn.modal.defaults = {
		keyboard: true,
		backdrop: true,
		loading: false,
		show: true,
		width: null,
		height: null,
		maxHeight: null,
		modalOverflow: false,
		consumeTab: true,
		focusOn: null,
		replace: false,
		resize: false,
		attentionAnimation: 'shake',
		manager: 'body',
		spinner: '

'
	};

	$.fn.modal.Constructor = Modal;

	/* MODAL DATA-API
	* ============== */

	$(function () {
		$(document).off('.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
			var $this = $(this),
				href = $this.attr('href'),
				$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
				option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());

			e.preventDefault();
			$target
				.modal(option)
				.one('hide', function () {
					$this.focus();
				})
		});
	});

}(window.jQuery);
<commit_msg>fix for 2.3 maximum callstack error<commit_after>/* ===========================================================
 * bootstrap-modal.js v2.1
 * ===========================================================
 * Copyright 2012 Jordan Schroter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

	"use strict"; // jshint ;_;

	/* MODAL CLASS DEFINITION
	* ====================== */

	var Modal = function (element, options) {
		this.init(element, options);
	};

	Modal.prototype = {

		constructor: Modal,

		init: function (element, options) {
			this.options = options;

			this.$element = $(element)
				.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));

			this.options.remote && this.$element.find('.modal-body').load(this.options.remote);

			var manager = typeof this.options.manager === 'function' ?
				this.options.manager.call(this) : this.options.manager;

			manager = manager.appendModal ?
				manager : $(manager).modalmanager().data('modalmanager');

			manager.appendModal(this);
		},

		toggle: function () {
			return this[!this.isShown ? 'show' : 'hide']();
		},

		show: function () {
			var e = $.Event('show');

			if (this.isShown) return;

			this.$element.triggerHandler(e);

			if (e.isDefaultPrevented()) return;

			this.escape();

			this.tab();

			this.options.loading && this.loading();
		},

		hide: function (e) {
			e && e.preventDefault();

			e = $.Event('hide');

			this.$element.triggerHandler(e);

			if (!this.isShown || e.isDefaultPrevented()) return (this.isShown = false);

			this.isShown = false;

			this.escape();

			this.tab();

			this.isLoading && this.loading();

			$(document).off('focusin.modal');

			this.$element
				.removeClass('in')
				.removeClass('animated')
				.removeClass(this.options.attentionAnimation)
				.removeClass('modal-overflow')
				.attr('aria-hidden', true);

			$.support.transition && this.$element.hasClass('fade') ?
				this.hideWithTransition() :
				this.hideModal();
		},

		layout: function () {
			var prop = this.options.height ? 'height' : 'max-height',
				value = this.options.height || this.options.maxHeight;

			if (this.options.width){
				this.$element.css('width', this.options.width);

				var that = this;
				this.$element.css('margin-left', function () {
					if (/%/ig.test(that.options.width)){
						return -(parseInt(that.options.width) / 2) + '%';
					} else {
						return -($(this).width() / 2) + 'px';
					}
				});
			} else {
				this.$element.css('width', '');
				this.$element.css('margin-left', '');
			}

			this.$element.find('.modal-body')
				.css('overflow', '')
				.css(prop, '');

			var modalOverflow = $(window).height() - 10 < this.$element.height();

			if (value){
				this.$element.find('.modal-body')
					.css('overflow', 'auto')
					.css(prop, value);
			}

			if (modalOverflow || this.options.modalOverflow) {
				this.$element
					.css('margin-top', 0)
					.addClass('modal-overflow');
			} else {
				this.$element
					.css('margin-top', 0 - this.$element.height() / 2)
					.removeClass('modal-overflow');
			}
		},

		tab: function () {
			var that = this;

			if (this.isShown && this.options.consumeTab) {
				this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
			    	if (e.keyCode && e.keyCode == 9){
						var $next = $(this),
							$rollover = $(this);

						that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) {
							if (!e.shiftKey){
						 		$next = $next.data('tabindex') < $(this).data('tabindex') ?
									$next = $(this) :
									$rollover = $(this);
							} else {
								$next = $next.data('tabindex') > $(this).data('tabindex') ?
									$next = $(this) :
									$rollover = $(this);
							}
						});

						$next[0] !== $(this)[0] ?
							$next.focus() : $rollover.focus();

						e.preventDefault();
					}
				});
			} else if (!this.isShown) {
				this.$element.off('keydown.tabindex.modal');
			}
		},

		escape: function () {
			var that = this;
			if (this.isShown && this.options.keyboard) {
				if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);

				this.$element.on('keyup.dismiss.modal', function (e) {
					e.which == 27 && that.hide();
				});
			} else if (!this.isShown) {
				this.$element.off('keyup.dismiss.modal')
			}
		},

		hideWithTransition: function () {
			var that = this
				, timeout = setTimeout(function () {
					that.$element.off($.support.transition.end);
					that.hideModal();
				}, 500);

			this.$element.one($.support.transition.end, function () {
				clearTimeout(timeout);
				that.hideModal();
			});
		},

		hideModal: function () {
			this.$element
				.hide()
				.triggerHandler('hidden');

			var prop = this.options.height ? 'height' : 'max-height';
			var value = this.options.height || this.options.maxHeight;

			if (value){
				this.$element.find('.modal-body')
					.css('overflow', '')
					.css(prop, '');
			}

		},

		removeLoading: function () {
			this.$loading.remove();
			this.$loading = null;
			this.isLoading = false;
		},

		loading: function (callback) {
			callback = callback || function () {};

			var animate = this.$element.hasClass('fade') ? 'fade' : '';

			if (!this.isLoading) {
				var doAnimate = $.support.transition && animate;

				this.$loading = $('
')
					.append(this.options.spinner)
					.appendTo(this.$element);

				if (doAnimate) this.$loading[0].offsetWidth; // force reflow

				this.$loading.addClass('in');

				this.isLoading = true;

				doAnimate ?
					this.$loading.one($.support.transition.end, callback) :
					callback();

			} else if (this.isLoading && this.$loading) {
				this.$loading.removeClass('in');

				var that = this;
				$.support.transition && this.$element.hasClass('fade')?
					this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
					that.removeLoading();

			} else if (callback) {
				callback(this.isLoading);
			}
		},

		focus: function () {
			var $focusElem = this.$element.find(this.options.focusOn);

			$focusElem = $focusElem.length ? $focusElem : this.$element;

			$focusElem.focus();
		},

		attention: function (){
			// NOTE: transitionEnd with keyframes causes odd behaviour

			if (this.options.attentionAnimation){
				this.$element
					.removeClass('animated')
					.removeClass(this.options.attentionAnimation);

				var that = this;

				setTimeout(function () {
					that.$element
						.addClass('animated')
						.addClass(that.options.attentionAnimation);
				}, 0);
			}

			this.focus();
		},

		destroy: function () {
			var e = $.Event('destroy');
			this.$element.triggerHandler(e);
			if (e.isDefaultPrevented()) return;

			this.teardown();
		},

		teardown: function () {
			if (!this.$parent.length){
				this.$element.remove();
				this.$element = null;
				return;
			}

			if (this.$parent !== this.$element.parent()){
				this.$element.appendTo(this.$parent);
			}

			this.$element.off('.modal');
			this.$element.removeData('modal');
			this.$element
				.removeClass('in')
				.attr('aria-hidden', true);
		}
	};

	/* MODAL PLUGIN DEFINITION
	* ======================= */

	$.fn.modal = function (option, args) {
		return this.each(function () {
			var $this = $(this),
				data = $this.data('modal'),
				options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);

			if (!data) $this.data('modal', (data = new Modal(this, options)));
			if (typeof option == 'string') data[option].apply(data, [].concat(args));
			else if (options.show) data.show()
		})
	};

	$.fn.modal.defaults = {
		keyboard: true,
		backdrop: true,
		loading: false,
		show: true,
		width: null,
		height: null,
		maxHeight: null,
		modalOverflow: false,
		consumeTab: true,
		focusOn: null,
		replace: false,
		resize: false,
		attentionAnimation: 'shake',
		manager: 'body',
		spinner: '

'
	};

	$.fn.modal.Constructor = Modal;

	/* MODAL DATA-API
	* ============== */

	$(function () {
		$(document).off('click.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
			var $this = $(this),
				href = $this.attr('href'),
				$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
				option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());

			e.preventDefault();
			$target
				.modal(option)
				.one('hide', function () {
					$this.focus();
				})
		});
	});

}(window.jQuery);
<|endoftext|>


<commit_before>function Character(level, pickups, enemies, background, viewport){

	//Inherit event manager
	FF.EventManager.call(this);

	//Create sprite
	var sprite = new FF.SpriteSheet({ image : "res/img/charsets/player.png", frame_size : [98,66], bounds : [39,25,44,41] });
	var animation = new FF.SpriteAnimation({frames : sprite.frames, frame_duration : 100 });

	//Set default animations
	sprite.anim_default_left = animation.slice(0,3);
	sprite.anim_left = animation.slice(8,11);
	sprite.anim_default_right = animation.slice(4,7);
	sprite.anim_right = animation.slice(12,15);
	sprite.anim_jump_left = animation.slice(16,17);
	sprite.anim_jump_right = animation.slice(22,23);
	sprite.setFrame(sprite.anim_default_right.next());

	//Setup player start
	var actions = level.getObjectGroup("actions").objects;
	for(var i in actions)
		if(actions[i].properties["action"] == "start")
			sprite.x = actions[i].x, sprite.y = actions[i].y - actions[i].rect().height * 3;

	//Setup move vars
	var
		direction = "right",
		vx = 0,
		vy = 0,
		can_jump = true,
		character_speed = 10,
		character_jump_height = 25;

	//Setup player stats
	var
		coins = 0,
		score = 0,
		hearts = 6,
		lives = 3,
		can_be_touched = true,
		score_multiplier = { coins : 10, lives : 100 };

	//Setup touched timer (when you crash onto an enemy, to make you blink a little)
	var timer = new FF.Timer({ timeout : 2000, interval : 200 });
	timer.addEventListener("tick",function(){ sprite.alpha = (sprite.alpha == 0.5) ? 1 : 0.5; });
	timer.addEventListener("start",function(){ sprite.alpha = 0.5, can_be_touched = false; });
	timer.addEventListener("timeout",function(){ sprite.alpha = 1, can_be_touched = true; });

	this.update = function(){

		//Update touched timer
		timer.update();

		//Check movements
		vx = 0;

		if(FF.InputManager.pressed(["left","gamepad_left"]) || FF.InputManager.gamepad_axis_values.left.x <= -0.5)
			vx = -character_speed, sprite.setFrame(sprite.anim_left.next()), direction = "left";

	    else if(FF.InputManager.pressed(["right", "gamepad_right"]) || FF.InputManager.gamepad_axis_values.left.x >= 0.5)
			vx = character_speed, sprite.setFrame(sprite.anim_right.next()), direction = "right";

		else
			sprite.setFrame((direction == "left") ? sprite.anim_default_left.next() : sprite.anim_default_right.next());

		if(FF.InputManager.pressedWithoutRepeat(["up", "gamepad_face_button_1"]))
			if(can_jump)
				vy = -(character_jump_height), can_jump = false;

		vy += 1;

		//Update position on X
		sprite.x += vx;

		if(viewport.moving)
			background.camera_x+=vx*10;
		var block = level.itemCollideWithSomethingInMap(sprite, { obj_group : "obstacles" })[0];

		if(sprite.rect().x <= level.x || sprite.rect().x + sprite.rect().width >= level.rect().width || (block && block.rect().height > sprite.rect().height / 2)){
			sprite.x -= vx;
			if(viewport.moving)
				background.camera_x-=vx*10;
		}
		vx = 0;

		//Update position on y
		can_jump = false, sprite.y += vy;
		var block = level.itemCollideWithSomethingInMap(sprite, { obj_group : "obstacles" })[0];

		if(block && block.properties && block.properties["jumping"]) //Jumping on a spring
			vy = -parseInt(block.properties["jumping"]);

		else if(block && vy > 0 && sprite.rect().y < block.rect().y) //Blocked going down
			can_jump = true, sprite.y = block.rect().y - sprite.rect().height - 1, vy = 0;

		else if(block && vy < 0 && block.rect().height >= sprite.rect().height / 2) //Blocked going up
			sprite.y = block.rect().y + block.rect().height, vy = 0, sprite.setFrame((direction == "left") ? sprite.anim_jump_left.next() : sprite.anim_jump_right.next());

		else //FUCKING JUMPING MAN, MUCH HIGH, SO HEIGHT, WOW, DOGE
			sprite.setFrame((direction == "left") ? sprite.anim_jump_left.next() : sprite.anim_jump_right.next());

		//Check collisions with monsters
		var monsters = FF.Util.collideOneWithMany(sprite, enemies.values);
		if(monsters.length > 0 && can_be_touched == true){
			if(sprite.rect().y + sprite.rect().height < monsters[0].rect().y + 10 && sprite.rect().y + sprite.rect().height > monsters[0].rect().y && !can_jump)
				vy = -parseInt(25), monsters[0].die(enemies);
			else
				hearts--, can_be_touched = false, timer.restart();
		}

		//Check player hearts
		if(hearts <= 0){
			if(lives > 0)
				this.die();
			else
				this.gameover();

			return;
		}

		//Check player lives
		if(lives <= 0)
			return this.gameover();

		//Check collisions with pickups
		var items = FF.Util.collideOneWithMany(sprite, pickups.values);
		for(var i in items){
			pickups.del(items[i]);

			switch(items[i].getType()){
				case "coin":
					coins++;
					score+= score_multiplier.coins;
					break;
				case "extra_life":
					lives++;
					score+= score_multiplier.lives;
					break;
				default:
					break;
			}
		}

		//Check collisions with end of level
		var actions = FF.Util.collideOneWithMany(sprite, level.getObjectGroup("actions").objects);
		for(var i in actions)
			if(actions[i].properties["action"] == "end")
				this.dispatchEvent({ type : "endlevel" });

		//Check if player is still in the world
		if(sprite.rect().y > level.rect().height)
			this.die();
	};

	this.draw = function(){
		sprite.draw();
	};

	this.getSprite = function(){
		return sprite;
	};

	this.changeLevel = function(m){
		level = m;
		this.setup();
	};

	this.die = function(){
		hearts = 6;
		lives--;
		can_be_touched = true;
		timer.reset();
		this.dispatchEvent({ type : "dead" });
	};

	this.gameover = function(){
		hearts = 6;
		lives = 3;
		coins = 0;
		score = 0;
		can_be_touched = true;
		timer.reset();
		this.dispatchEvent({ type : "gameover" });
	};

	this.getHearts = function(){
		return hearts;
	};

	this.getLives = function(){
		return lives;
	};

	this.getCoins = function(){
		return coins;
	};

	this.getScore = function(){
		return score;
	};

};
<commit_msg>Add score on kill<commit_after>function Character(level, pickups, enemies, background, viewport){

	//Inherit event manager
	FF.EventManager.call(this);

	//Create sprite
	var sprite = new FF.SpriteSheet({ image : "res/img/charsets/player.png", frame_size : [98,66], bounds : [39,25,44,41] });
	var animation = new FF.SpriteAnimation({frames : sprite.frames, frame_duration : 100 });

	//Set default animations
	sprite.anim_default_left = animation.slice(0,3);
	sprite.anim_left = animation.slice(8,11);
	sprite.anim_default_right = animation.slice(4,7);
	sprite.anim_right = animation.slice(12,15);
	sprite.anim_jump_left = animation.slice(16,17);
	sprite.anim_jump_right = animation.slice(22,23);
	sprite.setFrame(sprite.anim_default_right.next());

	//Setup player start
	var actions = level.getObjectGroup("actions").objects;
	for(var i in actions)
		if(actions[i].properties["action"] == "start")
			sprite.x = actions[i].x, sprite.y = actions[i].y - actions[i].rect().height * 3;

	//Setup move vars
	var
		direction = "right",
		vx = 0,
		vy = 0,
		can_jump = true,
		character_speed = 10,
		character_jump_height = 25;

	//Setup player stats
	var
		coins = 0,
		score = 0,
		hearts = 6,
		lives = 3,
		can_be_touched = true,
		score_multiplier = { coins : 10, lives : 100, kill : 300 };

	//Setup touched timer (when you crash onto an enemy, to make you blink a little)
	var timer = new FF.Timer({ timeout : 2000, interval : 200 });
	timer.addEventListener("tick",function(){ sprite.alpha = (sprite.alpha == 0.5) ? 1 : 0.5; });
	timer.addEventListener("start",function(){ sprite.alpha = 0.5, can_be_touched = false; });
	timer.addEventListener("timeout",function(){ sprite.alpha = 1, can_be_touched = true; });

	this.update = function(){

		//Update touched timer
		timer.update();

		//Check movements
		vx = 0;

		if(FF.InputManager.pressed(["left","gamepad_left"]) || FF.InputManager.gamepad_axis_values.left.x <= -0.5)
			vx = -character_speed, sprite.setFrame(sprite.anim_left.next()), direction = "left";

	    else if(FF.InputManager.pressed(["right", "gamepad_right"]) || FF.InputManager.gamepad_axis_values.left.x >= 0.5)
			vx = character_speed, sprite.setFrame(sprite.anim_right.next()), direction = "right";

		else
			sprite.setFrame((direction == "left") ? sprite.anim_default_left.next() : sprite.anim_default_right.next());

		if(FF.InputManager.pressedWithoutRepeat(["up", "gamepad_face_button_1"]))
			if(can_jump)
				vy = -(character_jump_height), can_jump = false;

		vy += 1;

		//Update position on X
		sprite.x += vx;

		if(viewport.moving)
			background.camera_x+=vx*10;
		var block = level.itemCollideWithSomethingInMap(sprite, { obj_group : "obstacles" })[0];

		if(sprite.rect().x <= level.x || sprite.rect().x + sprite.rect().width >= level.rect().width || (block && block.rect().height > sprite.rect().height / 2)){
			sprite.x -= vx;
			if(viewport.moving)
				background.camera_x-=vx*10;
		}
		vx = 0;

		//Update position on y
		can_jump = false, sprite.y += vy;
		var block = level.itemCollideWithSomethingInMap(sprite, { obj_group : "obstacles" })[0];

		if(block && block.properties && block.properties["jumping"]) //Jumping on a spring
			vy = -parseInt(block.properties["jumping"]);

		else if(block && vy > 0 && sprite.rect().y < block.rect().y) //Blocked going down
			can_jump = true, sprite.y = block.rect().y - sprite.rect().height - 1, vy = 0;

		else if(block && vy < 0 && block.rect().height >= sprite.rect().height / 2) //Blocked going up
			sprite.y = block.rect().y + block.rect().height, vy = 0, sprite.setFrame((direction == "left") ? sprite.anim_jump_left.next() : sprite.anim_jump_right.next());

		else //FUCKING JUMPING MAN, MUCH HIGH, SO HEIGHT, WOW, DOGE
			sprite.setFrame((direction == "left") ? sprite.anim_jump_left.next() : sprite.anim_jump_right.next());

		//Check collisions with monsters
		var monsters = FF.Util.collideOneWithMany(sprite, enemies.values);
		if(monsters.length > 0 && can_be_touched == true){
			if(sprite.rect().y + sprite.rect().height < monsters[0].rect().y + 10 && sprite.rect().y + sprite.rect().height > monsters[0].rect().y && !can_jump)
				vy = -parseInt(25), monsters[0].die(enemies), score+= score_multiplier.kill;
			else
				hearts--, can_be_touched = false, timer.restart();
		}

		//Check player hearts
		if(hearts <= 0){
			if(lives > 0)
				this.die();
			else
				this.gameover();

			return;
		}

		//Check player lives
		if(lives <= 0)
			return this.gameover();

		//Check collisions with pickups
		var items = FF.Util.collideOneWithMany(sprite, pickups.values);
		for(var i in items){
			pickups.del(items[i]);

			switch(items[i].getType()){
				case "coin":
					coins++;
					score+= score_multiplier.coins;
					break;
				case "extra_life":
					lives++;
					score+= score_multiplier.lives;
					break;
				default:
					break;
			}
		}

		//Check collisions with end of level
		var actions = FF.Util.collideOneWithMany(sprite, level.getObjectGroup("actions").objects);
		for(var i in actions)
			if(actions[i].properties["action"] == "end")
				this.dispatchEvent({ type : "endlevel" });

		//Check if player is still in the world
		if(sprite.rect().y > level.rect().height)
			this.die();
	};

	this.draw = function(){
		sprite.draw();
	};

	this.getSprite = function(){
		return sprite;
	};

	this.changeLevel = function(m){
		level = m;
		this.setup();
	};

	this.die = function(){
		hearts = 6;
		lives--;
		can_be_touched = true;
		timer.reset();
		this.dispatchEvent({ type : "dead" });
	};

	this.gameover = function(){
		hearts = 6;
		lives = 3;
		coins = 0;
		score = 0;
		can_be_touched = true;
		timer.reset();
		this.dispatchEvent({ type : "gameover" });
	};

	this.getHearts = function(){
		return hearts;
	};

	this.getLives = function(){
		return lives;
	};

	this.getCoins = function(){
		return coins;
	};

	this.getScore = function(){
		return score;
	};

};
<|endoftext|>


<commit_before>// Create the call to action banner component.
var callToAction = {

  // Create the view-model.
  vm: {
    init: function() {
      console.log ("home call to action banner vm init");
    }
  },

  // Create the controller.
  controller: function() {
    callToAction.vm.init ();
  },

  // Create the view.
  view: function() {
    return m("section", {class: "call-to-action hero"}, [
      m("div", [
        m("div", {class: "vertical-center col span_6_of_12"}, [
          m("div", [
            m("img", {class: "logo-image", src: "imgs/logos/adventure-guild.png", alt: "Adventure Guild"})
          ])
        ]),
        m("div", {class: "vertical-center col span_6_of_12"}, [
          m("div", [
            m("img", {class: "devices-image", src: "imgs/home/devices.png", alt: "Play Anytime, Anywhere"}),
            m("div", [
              m("a", {onclick: function (e) {m.route("/about");}}, [
                m("button", {type: "button"}, "Learn More")
              ])
            ]),
            m("div", [
              /*
              m("h2", "Stay Connected!"),
              m("a", {target: "_blank", href: "http://twitter.com/AdvGuildGame"}, m("span", {class: "fa fa-twitter fa-fw"})),
              m("a", {target: "_blank", href: "http://facebook.com/AdventureGuildGame"}, m("span", {class: "fa fa-facebook fa-fw"})),
              */
              m("a", {onclick: function (e) {m.route("/play");}}, [
                m("button", {type: "button"}, "Get Early Access")
              ])
            ])
          ])
        ]),
      ]),
      m("hr", {class: "hr-gradient"})
    ]);
  }
}

// Create the media reel component.
var mediaReel = {

  // Create the view-model.
  vm: {
    init: function() {
      console.log ("home media reel banner vm init");
    }
  },

  // Create the controller.
  controller: function() {
    mediaReel.vm.init ();
  },

  // Create the view.
  view: function() {
    return m("section", {class: "media-reel hero"}, [
      m("div", [
        m("div", {config: function(el, isInit) {$(el).slick({ dots: true, adaptiveHeight: true});}}, [
          m("div", [
            m("img", {src: "imgs/screenshots/combat.png", alt: "Combat"})
          ]),
          m("div", [
            m("img", {src: "imgs/screenshots/character.png", alt: "Character Customization"})
          ]),
          m("div", [
            m("img", {src: "imgs/screenshots/items.png", alt: "Procedural Items"})
          ])
        ])
      ])
    ]);
  }
}

// Create the home component.
var home = {};

// Create the home view-model.
home.vm = {
  init: function() {
    console.log("home vm init");
  }
}

// Create the home controller.
home.controller = function() {
  home.vm.init ();
}

// Create the home view.
home.view = function() {
  return [
    m.component(nav, {page: "home"}),
    m.component(callToAction),
    m.component(mediaReel),
    m.component(footer)
  ]
}

m.route.mode = "pathname";
m.route(document.body, "/", {
    "/": home,
    "/play": play,
    "/about": about,
    "/donations": shop,
    "/press": press,
    "/adventurers": characters,
    "/account": account,
  }
);
<commit_msg>home page manual linting<commit_after>// Create the call to action banner component.
var callToAction = {
  // Create the view.
  view: function() {
    return m("section", {class: "call-to-action hero"}, [
      m("div", [
        m("div", {class: "vertical-center col span_6_of_12"}, [
          m("div", [
            m("img", {class: "logo-image", src: "imgs/logos/adventure-guild.png", alt: "Adventure Guild"})
          ])
        ]),
        m("div", {class: "vertical-center col span_6_of_12"}, [
          m("div", [
            m("img", {class: "devices-image", src: "imgs/home/devices.png", alt: "Play Anytime, Anywhere"}),
            m("div", [
              m("a", {onclick: function (e) {m.route("/about");}}, [
                m("button", {type: "button"}, "Learn More")
              ])
            ]),
            m("div", [
              /*
              m("h2", "Stay Connected!"),
              m("a", {target: "_blank", href: "http://twitter.com/AdvGuildGame"}, m("span", {class: "fa fa-twitter fa-fw"})),
              m("a", {target: "_blank", href: "http://facebook.com/AdventureGuildGame"}, m("span", {class: "fa fa-facebook fa-fw"})),
              */
              m("a", {onclick: function (e) {m.route("/play");}}, [
                m("button", {type: "button"}, "Get Early Access")
              ])
            ])
          ])
        ]),
      ]),
      m("hr", {class: "hr-gradient"})
    ]);
  }
}

// Create the media reel component.
var mediaReel = {
  // Create the view.
  view: function() {
    return m("section", {class: "media-reel hero"}, [
      m("div", [
        m("div", {config: function(el, isInit) {$(el).slick({ dots: true, adaptiveHeight: true});}}, [
          m("div", [
            m("img", {src: "imgs/screenshots/combat.png", alt: "Combat"})
          ]),
          m("div", [
            m("img", {src: "imgs/screenshots/character.png", alt: "Character Customization"})
          ]),
          m("div", [
            m("img", {src: "imgs/screenshots/items.png", alt: "Procedural Items"})
          ])
        ])
      ])
    ]);
  }
}

// Create the home component.
var home = {

  // Create the home view.
  view: function() {
    return [
      m.component(nav, {page: "home"}),
      m.component(callToAction),
      m.component(mediaReel),
      m.component(footer)
    ]
  }
}

m.route.mode = "pathname";
m.route(document.body, "/", {
    "/": home,
    "/play": play,
    "/about": about,
    "/donations": shop,
    "/press": press,
    "/adventurers": characters,
    "/account": account,
  }
);
<|endoftext|>


<commit_before>var app = {
    inicializar: function() {
        // cria a instancia pixi stage
        this.stage = new PIXI.Stage(0xC6C6C6, true);

        //injetar todas as imagens para inserir uma unica vez
        this.gameInjecao = new PIXI.DisplayObjectContainer();
        this.gameInjecaoMar = new PIXI.DisplayObjectContainer();

        this.renderer = PIXI.autoDetectRenderer(900, 500);
        document.getElementById('center').appendChild(this.renderer.view);

        this.carregarOndas();
        this.carregarSurfista();

    },
    carregarOndas: function() {
        // MAR CONFIGURAÇAO
        var ttMar = PIXI.Texture.fromImage("img/mar/1-test.png");
        this.elMar = new PIXI.TilingSprite(ttMar, 1000, 71);

        this.elMar.position.y = 429;

        var ttMar1 = PIXI.Texture.fromImage("img/mar/2.png");
        this.elMar1 = new PIXI.TilingSprite(ttMar1, 1000, 124);

        this.elMar1.position.y = 376;

        var ttMar2 = PIXI.Texture.fromImage("img/mar/3.png");
        this.elMar2 = new PIXI.TilingSprite(ttMar2, 1000, 146);

        this.elMar2.position.y = 354;

        var ttMar3 = PIXI.Texture.fromImage("img/mar/4.png");
        this.elMar3 = new PIXI.TilingSprite(ttMar3, 1000, 170);

        this.elMar3.position.y = 330;

        this.gameInjecaoMar.addChild(this.elMar3);
        this.gameInjecaoMar.addChild(this.elMar2);
        this.gameInjecaoMar.addChild(this.elMar1);
        this.gameInjecaoMar.addChild(this.elMar);

    },
    carregarSurfista: function() {
        //SURFISTA CONFIGURACAO

        var ttSurfista = PIXI.Texture.fromImage("img/surfista.png");
        this.elSurfista = new PIXI.Sprite(ttSurfista);

        this.elSurfista.position.x = 30;
        this.elSurfista.position.y = 260;

        this.gameInjecao.addChild(this.elSurfista);
    },
    inserirStage: function() {
        //inserir imagens e elementos no stage
        this.stage.addChild(this.gameInjecaoMar);
        this.stage.addChild(this.gameInjecao);
    },
    iniciarAnimacao: function() {
        //INICIAR ANIMACAO JOGO
        requestAnimFrame(this.animate);
    },
    animate: function() {
        //MAR ANIMACAO CONSTANTE
        app.elMar.tilePosition.x += 1.5;
        app.elMar1.tilePosition.x += 1;
        app.elMar2.tilePosition.x += 1;
        app.elMar3.tilePosition.x += 0.5;
        //------------------------
        app.renderer.render(app.stage);
        requestAnimFrame(app.animate);
    }, carregarInicioJogo: function(){
        this.play = true;
        controlesJogo.controleSurfista();
    }
}

var controlesJogo = {
    controleSurfista: function(){
        Mousetrap.bind('right', function(){
            app.elSurfista.position.x += 1;
        });
    }
}

app.inicializar();
app.inserirStage();
app.iniciarAnimacao();
<commit_msg>adicionado movimentos basicos<commit_after>var app = {
    inicializar: function() {
        // cria a instancia pixi stage
        this.stage = new PIXI.Stage(0xC6C6C6, true);

        //injetar todas as imagens para inserir uma unica vez
        this.gameInjecao = new PIXI.DisplayObjectContainer();
        this.gameInjecaoMar = new PIXI.DisplayObjectContainer();

        this.renderer = PIXI.autoDetectRenderer(900, 500);
        document.getElementById('center').appendChild(this.renderer.view);

        this.carregarOndas();
        this.carregarSurfista();

    },
    carregarOndas: function() {
        // MAR CONFIGURAÇAO
        var ttMar = PIXI.Texture.fromImage("img/mar/1-test.png");
        this.elMar = new PIXI.TilingSprite(ttMar, 1000, 71);

        this.elMar.position.y = 429;

        var ttMar1 = PIXI.Texture.fromImage("img/mar/2.png");
        this.elMar1 = new PIXI.TilingSprite(ttMar1, 1000, 124);

        this.elMar1.position.y = 376;

        var ttMar2 = PIXI.Texture.fromImage("img/mar/3.png");
        this.elMar2 = new PIXI.TilingSprite(ttMar2, 1000, 146);

        this.elMar2.position.y = 354;

        var ttMar3 = PIXI.Texture.fromImage("img/mar/4.png");
        this.elMar3 = new PIXI.TilingSprite(ttMar3, 1000, 170);

        this.elMar3.position.y = 330;

        this.gameInjecaoMar.addChild(this.elMar3);
        this.gameInjecaoMar.addChild(this.elMar2);
        this.gameInjecaoMar.addChild(this.elMar1);
        this.gameInjecaoMar.addChild(this.elMar);

    },
    carregarSurfista: function() {
        //SURFISTA CONFIGURACAO

        var ttSurfista = PIXI.Texture.fromImage("img/surfista.png");
        this.elSurfista = new PIXI.Sprite(ttSurfista);

        this.elSurfista.position.x = 30;
        this.elSurfista.position.y = 260;

        this.gameInjecao.addChild(this.elSurfista);
    },
    inserirStage: function() {
        //inserir imagens e elementos no stage
        this.stage.addChild(this.gameInjecaoMar);
        this.stage.addChild(this.gameInjecao);
    },
    iniciarAnimacao: function() {
        //INICIAR ANIMACAO JOGO
        requestAnimFrame(this.animate);
    },
    animate: function() {
        //MAR ANIMACAO CONSTANTE
        app.elMar.tilePosition.x += 1.5;
        app.elMar1.tilePosition.x += 1;
        app.elMar2.tilePosition.x += 1;
        app.elMar3.tilePosition.x += 0.5;
        //------------------------
        app.renderer.render(app.stage);
        requestAnimFrame(app.animate);
    },
    carregarInicioJogo: function() {
        this.play = true;
        controlesJogo.controleSurfista();
    }
}

var controlesJogo = {
    controleSurfista: function() {
        Mousetrap.bind('right', function() {
            app.elSurfista.position.x += 5;
        });
        Mousetrap.bind('left', function() {
            app.elSurfista.position.x -= 5;
        });

        Mousetrap.bind('up', function() {
            for (var i = 0; i <= 10; i++) {
                   app.elSurfista.position.y -= 5;
            };
        });
        Mousetrap.bind('down', function() {
            for (var i = 0; i <= 10; i++) {
                   app.elSurfista.position.y += 5;
            };
        });
    }
}

app.inicializar();
app.inserirStage();
app.iniciarAnimacao();
app.carregarInicioJogo();<|endoftext|>


<commit_before>define(['require', "js/core/List", "js/data/Model", "flow", "underscore"], function (require, List, Model, flow, _) {

    var State = {
        CREATED: 0,
        LOADING: 1,
        LOADED: 2,
        ERROR: -1
    };

    var Collection = List.inherit("js.data.Collection", {

        $modelFactory: Model,

        ctor: function (items, options) {

            options = options || {};

            this.callBase(items);

            _.defaults(options, {
                rootCollection: null,
                pageSize: null,
                queryParameters: {},
                factory: this.$modelFactory || require('js/data/Model'),
                type: null,
                $itemsCount: null
            });

            this.$queryCollectionsCache = {};
            this.$pageCache = [];
            this.$options = options;
        },

        getRootCollection: function () {
            return this.$options.rootCollection ? this.$options.rootCollection : this;
        },

        createQueryCacheKey: function (queryParameters) {
            queryParameters = queryParameters || {};
            var ret = [];

            for (var key in queryParameters) {
                if (queryParameters.hasOwnProperty(key)) {
                    ret.push(key + "=" + queryParameters[key]);
                }
            }

            ret.sort();

            if (ret.length == 0) {
                return "root";
            }

            return ret.join("&");
        },

        createQueryCollection: function (queryParameters) {

            var options = {
                queryParameters: queryParameters,
                rootCollection: this.getRootCollection()
            };

            // different queryParameter, same options
            _.defaults(options, this.$options);

            var cacheKey = this.createQueryCacheKey(queryParameters);
            if(!this.$queryCollectionsCache[cacheKey]){
                var collection = new Collection(null, options);
                collection.$context = this.$context;
                this.$queryCollectionsCache[cacheKey] = collection;
            }
            return this.$queryCollectionsCache[cacheKey];
        },

        // fetches the complete list
        fetch: function (options, callback) {
            options = options || {};

            var self = this;

            function fetchPages(pageCount) {
                var delegates = [];

                function addFetchPageDelegate(pageIndex) {
                    delegates.push(function (cb) {
                        self.fetchPage(pageIndex, options, cb);
                    });
                }

                for (var i = 0; i < pageCount; i++) {
                    addFetchPageDelegate(i);
                }

                // execute loading parallel
                flow()
                    .par(delegates)
                    .exec(function (err) {
                        if (callback) {
                            callback(err, self);
                        }
                    });
            }

            if (!this.$options.pageSize) {
                // unlimited pageSize -> create one and only page and fetch
                this.fetchPage(0, options, callback);
            } else {
                // determinate pages
                var pageCount = this.pageCount();

                if (!isNaN(pageCount)) {
                    // we know how many page are there
                    fetchPages(pageCount);
                } else {
                    // load first page in order to get the available itemCount
                    // to calculate the pageCount
                    this.fetchPage(0, options, function (err) {
                        if (!err) {
                            // we now should calculate a page count
                            pageCount = self.pageCount();

                            if (isNaN(pageCount)) {
                                if (callback) {
                                    callback("Count for collection couldn't be fetched.", self);
                                }
                            } else {
                                fetchPages(pageCount);
                            }
                        } else {
                            if (callback) {
                                callback(err, self);
                            }
                        }
                    })
                }
            }

        },

        pageCount: function () {
            if (this.$.$itemsCount) {
                return Math.ceil(this.$.$itemsCount / this.$options.pageSize);
            } else {
                // we actually don't know how many pages there will be
                return NaN;
            }
        },

        getContextForChildren: function(childFactory) {
            if (childFactory.prototype.$cacheInRootContext) {
                return this.$context.$datasource.getContext();
            }

            return this.$context;
        },

        parse: function(data, type) {
            if (!(data instanceof Array)) {
                throw "data has to be an array";
            }

            var factory = this.$modelFactory;
            var alias = (factory === this.$context.$datasource.$entityFactory ||
                factory === this.$context.$datasource.$modelFactory) ? type : this.$alias;

            for (var i = 0; i < data.length; i++) {
                var value = data[i];
                var entity = this.getContextForChildren(factory).createEntity(factory, value.id, alias, type);
                entity.set(entity.parse(value));

                data[i] = entity;
            }

            return data;
        },

        createItem: function(id, type) {
            return this.getContextForChildren(this.$modelFactory).createEntity(this.$modelFactory, id, type);
        },

        fetchPage: function (pageIndex, options, callback) {

            if (pageIndex < 0) {
                throw "pageIndex must be >= 0";
            }

            var page = this.$pageCache[pageIndex];
            if (!page) {
                page = this.$pageCache[pageIndex] = new Page(null, this, pageIndex);
            }

            var self = this;
            options = _.extend(this.$options, options);
            page.fetch(options, function (err, page) {
                // insert data into items if not already inserted
                if (!err && !page.itemsInsertedIntoCollection) {
                    page.itemsInsertedIntoCollection = true;

                    // add items to collection
                    self.add(page.$items, {
                        index: (pageIndex || 0) * self.$options.pageSize
                    });
                }

                if (callback) {
                    callback(err, page, options);
                }
            });
        },

        // returns a new collections
        find: function (parameters) {
            var queryKey = this.createQueryCacheKey(parameters);

            if (!this.$queryCollectionsCache.hasOwnProperty(queryKey)) {
                this.$queryCollectionsCache[queryKey] = this.createQueryCollection(parameters);
            }

            return this.$queryCollectionsCache[queryKey];
        },

        size: function() {
            return this.$.$itemsCount;
        }.onChange('$itemsCount'),

        getQueryParameters: function(method){
            return this.$options.queryParameters;
        }
    });

    var Page = Collection.Page = List.inherit({

        ctor: function (items, collection, pageIndex) {
            if (!collection.$options.pageSize && pageIndex !== 0) {
                throw "Cannot create page for index '" + pageIndex + "' with pageSize '" + collection.options.pageSize + "'";
            }

            var options = collection.$options;

            if (options.pageSize) {
                this.$offset = pageIndex * options.pageSize;
                this.$limit = options.pageSize;
            }

            this.$pageIndex = pageIndex;
            this.$collection = collection;

            this.callBase(items);

            // stores the current fetch state
            this._fetch = {
                callbacks: [],
                state: State.CREATED
            };

        },

        parse: function (data, type) {
            return this.getRootCollection().parse(data, type);
        },

        getRootCollection: function(){
            return this.$collection.getRootCollection();
        },
        /***
         *
         * @param options
         * @param [Boolean] [options.fetchModels=false] fetch models inside collection
         * @param [Array] [options.fetchSubModels] fetch sub models
         * @param callback
         */
        fetch: function (options, callback) {
            options = options || {};

            var self = this;

            function pageFetchedComplete(err, page, originalCallback) {
                var callback = function (err, page) {
                    if (originalCallback) {
                        originalCallback(err, page, options)
                    }
                };

                if (options.fetchModels || options.fetchSubModels) {

                    // TODO: introduce poolSize parameter for par, and parEach

                    flow()
                        .parEach(page.$items, function(model, cb) {
                            model.fetch({
                                fetchSubModels: options.fetchSubModels
                            }, cb);
                        })
                        .exec(function (err) {
                            callback(err, page);
                        });

                } else {
                    callback(err, page);
                }

            }

            if (this._fetch.state === State.LOADING) {
                // currently fetching -> register callback
                this._fetch.callbacks.push(function (err, page) {
                    pageFetchedComplete(err, page, callback);
                });
            } else if (this._fetch.state == State.LOADED) {
                // completed loaded -> execute
                pageFetchedComplete(null, this, callback);
            } else {
                // set state and start loading
                self._fetch.state = State.LOADING;

                this.$collection.$context.$datasource.loadCollectionPage(this, options, function (err, page) {
                    self._fetch.state = err ? State.ERROR : State.LOADED;

                    // execute callbacks
                    pageFetchedComplete(err, page, callback);

                    _.each(self._fetch.callbacks, function (cb) {
                        cb(err, page);
                    });
                });
            }
        }
    });

    Collection.of = function(modelFactory) {

        if (modelFactory instanceof Function) {
            return Collection.inherit(Collection.prototype.constructor.name + '[' + modelFactory.prototype.constructor.name + ']', {
                $modelFactory: modelFactory
            });
        } else if (_.isString(modelFactory)) {
            return Collection.inherit(Collection.prototype.constructor.name + '[' + modelFactory + ']', {
                $alias: modelFactory,
                $modelFactory: Model || require('js/data/Model')
            });
        } else {
            throw "Cannot create Collection of '" + modelFactory + "'.";
        }

    };

    return Collection;
});<commit_msg>removed Alias<commit_after>define(['require', "js/core/List", "js/data/Model", "flow", "underscore"], function (require, List, Model, flow, _) {

    var State = {
        CREATED: 0,
        LOADING: 1,
        LOADED: 2,
        ERROR: -1
    };

    var Collection = List.inherit("js.data.Collection", {

        $modelFactory: Model,

        ctor: function (items, options) {

            options = options || {};

            this.callBase(items);

            _.defaults(options, {
                rootCollection: null,
                pageSize: null,
                queryParameters: {},
                factory: this.$modelFactory || require('js/data/Model'),
                type: null,
                $itemsCount: null
            });

            this.$queryCollectionsCache = {};
            this.$pageCache = [];
            this.$options = options;
        },

        getRootCollection: function () {
            return this.$options.rootCollection ? this.$options.rootCollection : this;
        },

        createQueryCacheKey: function (queryParameters) {
            queryParameters = queryParameters || {};
            var ret = [];

            for (var key in queryParameters) {
                if (queryParameters.hasOwnProperty(key)) {
                    ret.push(key + "=" + queryParameters[key]);
                }
            }

            ret.sort();

            if (ret.length == 0) {
                return "root";
            }

            return ret.join("&");
        },

        createQueryCollection: function (queryParameters) {

            var options = {
                queryParameters: queryParameters,
                rootCollection: this.getRootCollection()
            };

            // different queryParameter, same options
            _.defaults(options, this.$options);

            var cacheKey = this.createQueryCacheKey(queryParameters);
            if(!this.$queryCollectionsCache[cacheKey]){
                var collection = new Collection(null, options);
                collection.$context = this.$context;
                this.$queryCollectionsCache[cacheKey] = collection;
            }
            return this.$queryCollectionsCache[cacheKey];
        },

        // fetches the complete list
        fetch: function (options, callback) {
            options = options || {};

            var self = this;

            function fetchPages(pageCount) {
                var delegates = [];

                function addFetchPageDelegate(pageIndex) {
                    delegates.push(function (cb) {
                        self.fetchPage(pageIndex, options, cb);
                    });
                }

                for (var i = 0; i < pageCount; i++) {
                    addFetchPageDelegate(i);
                }

                // execute loading parallel
                flow()
                    .par(delegates)
                    .exec(function (err) {
                        if (callback) {
                            callback(err, self);
                        }
                    });
            }

            if (!this.$options.pageSize) {
                // unlimited pageSize -> create one and only page and fetch
                this.fetchPage(0, options, callback);
            } else {
                // determinate pages
                var pageCount = this.pageCount();

                if (!isNaN(pageCount)) {
                    // we know how many page are there
                    fetchPages(pageCount);
                } else {
                    // load first page in order to get the available itemCount
                    // to calculate the pageCount
                    this.fetchPage(0, options, function (err) {
                        if (!err) {
                            // we now should calculate a page count
                            pageCount = self.pageCount();

                            if (isNaN(pageCount)) {
                                if (callback) {
                                    callback("Count for collection couldn't be fetched.", self);
                                }
                            } else {
                                fetchPages(pageCount);
                            }
                        } else {
                            if (callback) {
                                callback(err, self);
                            }
                        }
                    })
                }
            }

        },

        pageCount: function () {
            if (this.$.$itemsCount) {
                return Math.ceil(this.$.$itemsCount / this.$options.pageSize);
            } else {
                // we actually don't know how many pages there will be
                return NaN;
            }
        },

        getContextForChild: function(childFactory) {
            return this.$context;
        },

        parse: function(data) {
            if (!(data instanceof Array)) {
                throw "data has to be an array";
            }

            var factory = this.$modelFactory;

            for (var i = 0; i < data.length; i++) {
                var value = data[i];
                var entity = this.getContextForChild(factory).createEntity(factory, value.id);
                entity.set(entity.parse(value));

                data[i] = entity;
            }

            return data;
        },

        createItem: function(id) {
            return this.getContextForChild(this.$modelFactory).createEntity(this.$modelFactory, id);
        },

        fetchPage: function (pageIndex, options, callback) {

            if (pageIndex < 0) {
                throw "pageIndex must be >= 0";
            }

            var page = this.$pageCache[pageIndex];
            if (!page) {
                page = this.$pageCache[pageIndex] = new Page(null, this, pageIndex);
            }

            var self = this;
            options = _.extend(this.$options, options);
            page.fetch(options, function (err, page) {
                // insert data into items if not already inserted
                if (!err && !page.itemsInsertedIntoCollection) {
                    page.itemsInsertedIntoCollection = true;

                    // add items to collection
                    self.add(page.$items, {
                        index: (pageIndex || 0) * self.$options.pageSize
                    });
                }

                if (callback) {
                    callback(err, page, options);
                }
            });
        },

        // returns a new collections
        find: function (parameters) {
            var queryKey = this.createQueryCacheKey(parameters);

            if (!this.$queryCollectionsCache.hasOwnProperty(queryKey)) {
                this.$queryCollectionsCache[queryKey] = this.createQueryCollection(parameters);
            }

            return this.$queryCollectionsCache[queryKey];
        },

        size: function() {
            return this.$.$itemsCount;
        }.onChange('$itemsCount'),

        getQueryParameters: function(method){
            return this.$options.queryParameters;
        }
    });

    var Page = Collection.Page = List.inherit({

        ctor: function (items, collection, pageIndex) {
            if (!collection.$options.pageSize && pageIndex !== 0) {
                throw "Cannot create page for index '" + pageIndex + "' with pageSize '" + collection.options.pageSize + "'";
            }

            var options = collection.$options;

            if (options.pageSize) {
                this.$offset = pageIndex * options.pageSize;
                this.$limit = options.pageSize;
            }

            this.$pageIndex = pageIndex;
            this.$collection = collection;

            this.callBase(items);

            // stores the current fetch state
            this._fetch = {
                callbacks: [],
                state: State.CREATED
            };

        },

        parse: function (data, type) {
            return this.getRootCollection().parse(data, type);
        },

        getRootCollection: function(){
            return this.$collection.getRootCollection();
        },
        /***
         *
         * @param options
         * @param [Boolean] [options.fetchModels=false] fetch models inside collection
         * @param [Array] [options.fetchSubModels] fetch sub models
         * @param callback
         */
        fetch: function (options, callback) {
            options = options || {};

            var self = this;

            function pageFetchedComplete(err, page, originalCallback) {
                var callback = function (err, page) {
                    if (originalCallback) {
                        originalCallback(err, page, options)
                    }
                };

                if (options.fetchModels || options.fetchSubModels) {

                    // TODO: introduce poolSize parameter for par, and parEach

                    flow()
                        .parEach(page.$items, function(model, cb) {
                            model.fetch({
                                fetchSubModels: options.fetchSubModels
                            }, cb);
                        })
                        .exec(function (err) {
                            callback(err, page);
                        });

                } else {
                    callback(err, page);
                }

            }

            if (this._fetch.state === State.LOADING) {
                // currently fetching -> register callback
                this._fetch.callbacks.push(function (err, page) {
                    pageFetchedComplete(err, page, callback);
                });
            } else if (this._fetch.state == State.LOADED) {
                // completed loaded -> execute
                pageFetchedComplete(null, this, callback);
            } else {
                // set state and start loading
                self._fetch.state = State.LOADING;

                this.$collection.$context.$datasource.loadCollectionPage(this, options, function (err, page) {
                    self._fetch.state = err ? State.ERROR : State.LOADED;

                    // execute callbacks
                    pageFetchedComplete(err, page, callback);

                    _.each(self._fetch.callbacks, function (cb) {
                        cb(err, page);
                    });
                });
            }
        }
    });

    Collection.of = function(modelFactory) {

        if (modelFactory instanceof Function) {
            return Collection.inherit(Collection.prototype.constructor.name + '[' + modelFactory.prototype.constructor.name + ']', {
                $modelFactory: modelFactory
            });
        }  else {
            throw "Cannot create Collection of '" + modelFactory + "'.";
        }

    };

    return Collection;
});<|endoftext|>


<commit_before>(function(document, window, $, undefined){
	var dt = new Date().getTime();

	function serverpoll() {
		var rnd = Math.random().toString().split("0.").join(""),
			xhr = new XMLHttpRequest();

		xhr.open('GET', "/tmp/lastupdate?dt=" + dt + "&rnd=" + rnd, true); //&removelongpoll
		xhr.onreadystatechange = function(){
			if (xhr.readyState != 4) return;

			//console.log("serverpoll returned: " + xhr.status + "; " + xhr.responseText);
			if (xhr.responseText*1 !== parseInt(xhr.responseText)) {
				window.location.reload();
			}
			//serverpoll();
		}
		xhr.onerror = xhr.onabort = function(){
			//console.log("serverpoll aborting");
			setTimeout(serverpoll, 1000);
		}
		xhr.send(null);
	}
	serverpoll();
	console.log("time now: " + new Date(dt));
})(document, window, jQuery);
<commit_msg>an error with absent file of last server updating is resolved<commit_after>(function(document, window, $, undefined){
	var dt = new Date().getTime();

	function serverpoll() {
		var rnd = Math.random().toString().split("0.").join(""),
			xhr = new XMLHttpRequest();

		xhr.open('GET', "/tmp/lastupdate?dt=" + dt + "&rnd=" + rnd, true); //&removelongpoll
		xhr.onreadystatechange = function(){
			if (xhr.readyState != 4) return;

			//console.log("serverpoll returned: " + xhr.status + "; " + xhr.responseText);
			if (xhr.status !== 404) {
				if (xhr.responseText * 1 != parseInt(xhr.responseText)) {
					window.location.reload();
				}
			}
			//serverpoll();
		}
		xhr.onerror = xhr.onabort = function(){
			//console.log("serverpoll aborting");
			setTimeout(serverpoll, 1000);
		}
		xhr.send(null);
	}
	serverpoll();
	console.log("time now: " + new Date(dt));
})(document, window, jQuery);
<|endoftext|>


<commit_before>/**
 * Player Entity
 */
game.PlayerEntity = me.Entity.extend({

    /**
     * constructor
     */
    init:function (x, y, settings) {
        // call the constructor
        this._super(me.Entity, 'init', [x, y , settings]);
        this.name = 'player';

        // shift sprite so that collision box is its bottom
        this.renderable.translate(0, -4);

        // viewport must follow the player
        me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH);

        // we set the velocity of the player's body
        this.body.setVelocity(2, 9);

        // we always update the player, ALWAYS
        this.alwaysUpdate = true;

        // setting constants
        this.onAirTime = 100;
        this.JUMP_MAX_AIRBONRNE_TIME = 80;
        this.FLICKERING_TIME = 2000;

        // setting initial direction
        this.direction = new me.Vector2d(1, 0);
        this.knockbacked = false;

        // animations
        this.renderable.addAnimation('idle', [0, 1, 2], 150);
        this.renderable.addAnimation('walk', [3, 4, 5, 6, 7, 8], 100);
        this.renderable.addAnimation('run', [9, 10, 11, 12, 13, 14], 70);
        this.renderable.addAnimation('jump', [15, 16], 50);
        this.renderable.addAnimation('fall', [18, 19], 50);
        this.renderable.addAnimation('kick', [20, 21, 21, 21], 50);
        this.renderable.addAnimation('stun', [23, 24, 23, 24, 23, 24], 50); // Must blink
        this.renderable.addAnimation('win', [25, 26, 27, 26], 120);
        this.setCurrentAnimation('idle');
    },

    setCurrentAnimation: function(name, onComplete) {
        if (!this.renderable.isCurrentAnimation(name)) {
            this.renderable.setCurrentAnimation(name, onComplete);
        }
    },

    flipX: function(flipX) {
        // XXX Should we prevent flipping when kicking or move the kick collision shape?
        if (!this.kicking) {
            this.renderable.flipX(flipX);
        }
    },

    /**
     * knocks the player back
     */
     knockback: function (strength, direction) {
         // set state as currently knockbacked
         this.knockbacked = true;

         // set default strength
         strength = strength || 2;
         direction = direction || this.direction;

        // change the velocity
        this.body.vel = new me.Vector2d(-strength * 20 * direction.x, -strength);
    },

    /**
     * kick
     */
    kick: function() {
        if (!this.kicking) {
            this.kicking = true;
            this.body.addShape(new me.Rect(
                this.direction.x < 0 ? -20 : 20,
                15,
                17,
                7
            ));
        }
    },

    /**
     * hit
     */
     hit: function() {
        this.renderable.flicker(this.FLICKERING_TIME);
     },

    /**
     * update the entity
     */
    update : function (dt) {
        // handling movement on the side
        if(!this.knockbacked) {
            if (me.input.isKeyPressed('left')) {
                this.flipX(true);
                this.body.vel.x -= this.body.accel.x * me.timer.tick;
                this.direction = new me.Vector2d(-1, 0);
            } else if (me.input.isKeyPressed('right')) {
                this.flipX(false);
                this.body.vel.x += this.body.accel.x * me.timer.tick;
                this.direction = new me.Vector2d(1, 0);
            } else {
                this.body.vel.x = 0;
            }
        }

        //handling jump
        if (me.input.isKeyPressed('jump')) {
            if (!this.body.jumping &&
                !this.knockbacked &&
                (!this.body.falling ||
                 this.onAirTime < this.JUMP_MAX_AIRBONRNE_TIME)) {
                this.body.vel.y = -this.body.maxVel.y * me.timer.tick;
                this.body.jumping = true;
            }
        }
        this.onAirTime += dt;
        if (!this.body.falling && !this.body.jumping) {
            this.onAirTime = 0;
        }

        // apply physics to the body (this moves the entity)
        this.body.update(dt);

        // handle collisions against other shapes
        me.collision.check(this);

        // enable kicking
        if(me.input.isKeyPressed('kick')) {
            if(!this.knockbacked) {
                this.kick();
            }
        }

        // update animation
        if(!this.kicking){
            if (this.knockbacked) {
                this.setCurrentAnimation('stun');
            } else if (this.body.jumping) {
                this.setCurrentAnimation('jump');
            } else if (this.body.vel.x !== 0) {
                this.setCurrentAnimation('walk');
            } else if (this.body.falling) {
                this.setCurrentAnimation('fall');
            } else {
                this.setCurrentAnimation('idle');
            }
        }
        else {
            this.setCurrentAnimation('kick', (function() {
                this.kicking = false;
                this.body.removeShapeAt(1);
            }).bind(this));
        }

        // return true if we moved or if the renderable was updated
        return (this._super(me.Entity, 'update', [dt]) ||
                this.body.vel.x !== 0 ||
                this.body.vel.y !== 0);
    },

   /**
     * colision handler
     * (called when colliding with other objects)
     */
    onCollision : function (response, other) {
        var myShapeIndex = response.a.name === this.name ? response.indexShapeA
                                                         : response.indexShapeB;
        var otherShapeIndex = response.a.name === other.name ? response.indexShapeA
                                                              : response.indexShapeB;

        // kick collision shape must not be solid
        if (myShapeIndex > 0) {
            return false;
        }

        // handling custom collision
        if (other.name === 'ball') {
            // TODO if jumping ON ball, must `return true` to have a collision
            return false;
        } else if (other.name === 'piglet') {
            other.rescue();
            return false;
        } else if (other.name == 'boar') {
            //if our body (not the foot) touches the boar
            if(myShapeIndex == 0) {
                //if we touch its damage hitbox
                /*if(otherShapeIndex == 0) {
                    //If we're not invincible and not stunned
                    if(!this.renderable.isFlickering() && !other.stunned) {
                        //giving priority over stunning. way better
                        this.hit();
                        //this.knockback(8, new me.Vector2d((other.pos.x - this.pos.x) > 0 ? 1 : -1, 0));
                    }
                    return !this.renderable.isFlickering() && !other.stunned;
                } */

                if (otherShapeIndex == 0) {
                    return false;
                } else if (otherShapeIndex == 1) {
                    var relativeOverlapV = response.overlapV.clone().scale(this.name == response.a.name ? 1 : 0);
                    if(!this.knockbacked && relativeOverlapV.y > 0) {
                        console.log(this.body.vel.y);
                        if((this.bottom - relativeOverlapV.y) < other.top && this.body.vel.y > 0) {
                            //we bounce on the head
                            if(!other.stunned) {
                                this.body.vel = (new me.Vector2d(-8 * 10 * (other.pos.x - this.pos.x) > 0 ? 1 : -1, -8));
                            }
                            other.stun();
                        }
                    }
                    return !other.stunned && !this.knockbacked;
                } else {
                    //If we're not invincible and not stunned
                    if(!this.renderable.isFlickering() && !other.stunned) {
                        //giving priority over stunning. way better
                        this.hit();
                        this.knockback(8, new me.Vector2d((other.pos.x - this.pos.x) > 0 ? 1 : -1, 0));
                    }
                    return !this.renderable.isFlickering() && !other.stunned;
                }
            }
            else {
                return true;
            }
        }
        else {
            //we're not knockbacked anymore
            this.knockbacked = false;
        }

        // Make all other objects solid
        return true;
    }
});
<commit_msg>Revert "Fixed sliding animation bug when inside monster"<commit_after>/**
 * Player Entity
 */
game.PlayerEntity = me.Entity.extend({

    /**
     * constructor
     */
    init:function (x, y, settings) {
        // call the constructor
        this._super(me.Entity, 'init', [x, y , settings]);
        this.name = 'player';

        // shift sprite so that collision box is its bottom
        this.renderable.translate(0, -4);

        // viewport must follow the player
        me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH);

        // we set the velocity of the player's body
        this.body.setVelocity(2, 9);

        // we always update the player, ALWAYS
        this.alwaysUpdate = true;

        // setting constants
        this.onAirTime = 100;
        this.JUMP_MAX_AIRBONRNE_TIME = 80;
        this.FLICKERING_TIME = 2000;

        // setting initial direction
        this.direction = new me.Vector2d(1, 0);
        this.knockbacked = false;

        // animations
        this.renderable.addAnimation('idle', [0, 1, 2], 150);
        this.renderable.addAnimation('walk', [3, 4, 5, 6, 7, 8], 100);
        this.renderable.addAnimation('run', [9, 10, 11, 12, 13, 14], 70);
        this.renderable.addAnimation('jump', [15, 16], 50);
        this.renderable.addAnimation('fall', [18, 19], 50);
        this.renderable.addAnimation('kick', [20, 21, 21, 21], 50);
        this.renderable.addAnimation('stun', [23, 24, 23, 24, 23, 24], 50); // Must blink
        this.renderable.addAnimation('win', [25, 26, 27, 26], 120);
        this.setCurrentAnimation('idle');
    },

    setCurrentAnimation: function(name, onComplete) {
        if (!this.renderable.isCurrentAnimation(name)) {
            this.renderable.setCurrentAnimation(name, onComplete);
        }
    },

    flipX: function(flipX) {
        // XXX Should we prevent flipping when kicking or move the kick collision shape?
        if (!this.kicking) {
            this.renderable.flipX(flipX);
        }
    },

    /**
     * knocks the player back
     */
     knockback: function (strength, direction) {
         // set state as currently knockbacked
         this.knockbacked = true;

         // set default strength
         strength = strength || 2;
         direction = direction || this.direction;

        // change the velocity
        this.body.vel = new me.Vector2d(-strength * 20 * direction.x, -strength);
    },

    /**
     * kick
     */
    kick: function() {
        if (!this.kicking) {
            this.kicking = true;
            this.body.addShape(new me.Rect(
                this.direction.x < 0 ? -20 : 20,
                15,
                17,
                7
            ));
        }
    },

    /**
     * hit
     */
     hit: function() {
        this.renderable.flicker(this.FLICKERING_TIME);
     },

    /**
     * update the entity
     */
    update : function (dt) {
        // handling movement on the side
        if(!this.knockbacked) {
            if (me.input.isKeyPressed('left')) {
                this.flipX(true);
                this.body.vel.x -= this.body.accel.x * me.timer.tick;
                this.direction = new me.Vector2d(-1, 0);
            } else if (me.input.isKeyPressed('right')) {
                this.flipX(false);
                this.body.vel.x += this.body.accel.x * me.timer.tick;
                this.direction = new me.Vector2d(1, 0);
            } else {
                this.body.vel.x = 0;
            }
        }

        //handling jump
        if (me.input.isKeyPressed('jump')) {
            if (!this.body.jumping &&
                !this.knockbacked &&
                (!this.body.falling ||
                 this.onAirTime < this.JUMP_MAX_AIRBONRNE_TIME)) {
                this.body.vel.y = -this.body.maxVel.y * me.timer.tick;
                this.body.jumping = true;
            }
        }
        this.onAirTime += dt;
        if (!this.body.falling && !this.body.jumping) {
            this.onAirTime = 0;
        }

        // apply physics to the body (this moves the entity)
        this.body.update(dt);

        // handle collisions against other shapes
        me.collision.check(this);

        // enable kicking
        if(me.input.isKeyPressed('kick')) {
            if(!this.knockbacked) {
                this.kick();
            }
        }

        // update animation
        if(!this.kicking){
            if (this.knockbacked) {
                this.setCurrentAnimation('stun');
            } else if (this.body.jumping) {
                this.setCurrentAnimation('jump');
            } else if (this.body.falling) {
                this.setCurrentAnimation('fall');
            } else if (this.body.vel.x !== 0) {
                this.setCurrentAnimation('walk');
            } else {
                this.setCurrentAnimation('idle');
            }
        }
        else {
            this.setCurrentAnimation('kick', (function() {
                this.kicking = false;
                this.body.removeShapeAt(1);
            }).bind(this));
        }

        // return true if we moved or if the renderable was updated
        return (this._super(me.Entity, 'update', [dt]) ||
                this.body.vel.x !== 0 ||
                this.body.vel.y !== 0);
    },

   /**
     * colision handler
     * (called when colliding with other objects)
     */
    onCollision : function (response, other) {
        var myShapeIndex = response.a.name === this.name ? response.indexShapeA
                                                         : response.indexShapeB;
        var otherShapeIndex = response.a.name === other.name ? response.indexShapeA
                                                              : response.indexShapeB;

        // kick collision shape must not be solid
        if (myShapeIndex > 0) {
            return false;
        }

        // handling custom collision
        if (other.name === 'ball') {
            // TODO if jumping ON ball, must `return true` to have a collision
            return false;
        } else if (other.name === 'piglet') {
            other.rescue();
            return false;
        } else if (other.name == 'boar') {
            //if our body (not the foot) touches the boar
            if(myShapeIndex == 0) {
                //if we touch its damage hitbox
                /*if(otherShapeIndex == 0) {
                    //If we're not invincible and not stunned
                    if(!this.renderable.isFlickering() && !other.stunned) {
                        //giving priority over stunning. way better
                        this.hit();
                        //this.knockback(8, new me.Vector2d((other.pos.x - this.pos.x) > 0 ? 1 : -1, 0));
                    }
                    return !this.renderable.isFlickering() && !other.stunned;
                } */

                if (otherShapeIndex == 0) {
                    return false;
                } else if (otherShapeIndex == 1) {
                    var relativeOverlapV = response.overlapV.clone().scale(this.name == response.a.name ? 1 : 0);
                    if(!this.knockbacked && relativeOverlapV.y > 0) {
                        console.log(this.body.vel.y);
                        if((this.bottom - relativeOverlapV.y) < other.top && this.body.vel.y > 0) {
                            //we bounce on the head
                            if(!other.stunned) {
                                this.body.vel = (new me.Vector2d(-8 * 10 * (other.pos.x - this.pos.x) > 0 ? 1 : -1, -8));
                            }
                            other.stun();
                        }
                    }
                    return !other.stunned && !this.knockbacked;
                } else {
                    //If we're not invincible and not stunned
                    if(!this.renderable.isFlickering() && !other.stunned) {
                        //giving priority over stunning. way better
                        this.hit();
                        this.knockback(8, new me.Vector2d((other.pos.x - this.pos.x) > 0 ? 1 : -1, 0));
                    }
                    return !this.renderable.isFlickering() && !other.stunned;
                }
            }
            else {
                return true;
            }
        }
        else {
            //we're not knockbacked anymore
            this.knockbacked = false;
        }

        // Make all other objects solid
        return true;
    }
});
<|endoftext|>