diff --git a/assets/data/abilities.js b/assets/data/abilities.js index 12ac982..c4e8b64 100644 --- a/assets/data/abilities.js +++ b/assets/data/abilities.js @@ -51,8 +51,7 @@ module.exports = { } }, "weather_fog": { - onEachTurn: function(args) { - card = args[0] + onEachTurn: function(card) { var targetRow = card.constructor.TYPE.RANGED; var forcedPower = 1; var field1 = this.field[targetRow].get(); @@ -66,7 +65,6 @@ module.exports = { }); }, onEachCardPlace: function(card) { - card = args[0] var targetRow = card.constructor.TYPE.RANGED; var forcedPower = 1; var field1 = this.field[targetRow].get(); @@ -122,5 +120,13 @@ module.exports = { }, "decoy": { replaceWith: true + }, + "foltest_leader1": { + onActivate: function() { + var cards = this.deck.find("key", "impenetrable_fog") + if(!cards.length) return; + var card = this.deck.removeFromDeck(cards[0]); + this.placeCard(card); + } } } \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index cbf1ac8..43c0d8e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -26,7 +26,7 @@ gulp.task('browserify', function(){ }); gulp.task('sass', function(){ - gulp.src('./public/scss/*.scss') + gulp.src('./public/scss/main.scss') .pipe(sass({ outputStyle: 'compressed' }).on("error", function(err){ diff --git a/package.json b/package.json index cbb8435..28f86cb 100644 --- a/package.json +++ b/package.json @@ -10,17 +10,18 @@ "devDependencies": { "babelify": "^6.1.2", "browserify": "^10.2.4", + "connect": "3.0.1", + "express": "4.12.3", "gulp": "^3.9.0", "gulp-livereload": "^3.8.0", "gulp-sass": "^2.0.1", "handlebars": "^3.0.3", "jquery": "^2.1.4", - "promise": "^7.0.1", - "shortid": "^2.2.2", - "connect": "3.0.1", - "express": "4.12.3", "minimist": "1.1.0", + "promise": "^7.0.1", "serve-static": "1.8.0", + "shortid": "^2.2.2", + "underscore": "^1.8.3", "vinyl-source-stream": "^1.1.0" }, "scripts": { diff --git a/public/index.html b/public/index.html index 329c79d..33d7bda 100644 --- a/public/index.html +++ b/public/index.html @@ -131,11 +131,9 @@
- {{#if preview}}
- +
- {{/if}}
discard deck @@ -200,6 +198,24 @@
+ + diff --git a/public/js/backbone.modal-min.js b/public/js/backbone.modal-min.js new file mode 100644 index 0000000..3a79acc --- /dev/null +++ b/public/js/backbone.modal-min.js @@ -0,0 +1,123 @@ +(function(){ + var a = function(a, b){ + return function(){ + return a.apply(b, arguments) + } + }, b = {}.hasOwnProperty, c = function(a, c){ + function d(){ + this.constructor = a + } + + for(var e in c)b.call(c, e) && (a[e] = c[e]); + return d.prototype = c.prototype, a.prototype = new d, a.__super__ = c.prototype, a + }, d = [].indexOf || function(a){ + for(var b = 0, c = this.length; c > b; b++)if(b in this && this[b] === a)return b; + return -1 + }; + !function(a){ + return "function" == typeof define && define.amd ? define(["underscore", "backbone", "exports"], a) : "object" == typeof exports ? a(require("underscore"), require("backbone"), exports) : a(_, Backbone, {}) + }(function(b, e, f){ + return f = function(f){ + function g(){ + this.triggerCancel = a(this.triggerCancel, this), this.triggerSubmit = a(this.triggerSubmit, this), this.triggerView = a(this.triggerView, this), this.clickOutsideElement = a(this.clickOutsideElement, this), this.clickOutside = a(this.clickOutside, this), this.checkKey = a(this.checkKey, this), this.rendererCompleted = a(this.rendererCompleted, this), this.args = Array.prototype.slice.apply(arguments), e.View.prototype.constructor.apply(this, this.args), this.setUIElements() + } + + return c(g, f), g.prototype.prefix = "bbm", g.prototype.animate = !0, g.prototype.keyControl = !0, g.prototype.showViewOnRender = !0, g.prototype.render = function(a){ + var c, d; + return c = this.serializeData(), (!a || b.isEmpty(a)) && (a = 0), this.$el.addClass("" + this.prefix + "-wrapper"), this.modalEl = e.$("
").addClass("" + this.prefix + "-modal"), this.template && this.modalEl.html(this.buildTemplate(this.template, c)), this.$el.html(this.modalEl), this.viewContainer ? (this.viewContainerEl = this.modalEl.find(this.viewContainer), this.viewContainerEl.addClass("" + this.prefix + "-modal__views")) : this.viewContainerEl = this.modalEl, e.$(":focus").blur(), (null != (d = this.views) ? d.length : void 0) > 0 && this.showViewOnRender && this.openAt(a), "function" == typeof this.onRender && this.onRender(), this.delegateModalEvents(), this.$el.fadeIn && this.animate ? (this.modalEl.css({opacity: 0}), this.$el.fadeIn({ + duration: 100, + complete: this.rendererCompleted + })) : this.rendererCompleted(), this + }, g.prototype.rendererCompleted = function(){ + var a; + return this.keyControl && (e.$("body").on("keyup.bbm", this.checkKey), this.$el.on("mouseup.bbm", this.clickOutsideElement), this.$el.on("click.bbm", this.clickOutside)), this.modalEl.css({opacity: 1}).addClass("" + this.prefix + "-modal--open"), "function" == typeof this.onShow && this.onShow(), null != (a = this.currentView) && "function" == typeof a.onShow ? a.onShow() : void 0 + }, g.prototype.setUIElements = function(){ + var a; + if(this.template = this.getOption("template"), this.views = this.getOption("views"), null != (a = this.views) && (a.length = b.size(this.views)), this.viewContainer = this.getOption("viewContainer"), this.animate = this.getOption("animate"), b.isUndefined(this.template) && b.isUndefined(this.views))throw new Error("No template or views defined for Backbone.Modal"); + if(this.template && this.views && b.isUndefined(this.viewContainer))throw new Error("No viewContainer defined for Backbone.Modal") + }, g.prototype.getOption = function(a){ + return a ? this.options && d.call(this.options, a) >= 0 && null != this.options[a] ? this.options[a] : this[a] : void 0 + }, g.prototype.serializeData = function(){ + var a; + return a = {}, this.model && (a = b.extend(a, this.model.toJSON())), this.collection && (a = b.extend(a, {items: this.collection.toJSON()})), a + }, g.prototype.delegateModalEvents = function(){ + var a, c, d, e, f, g, h; + this.active = !0, a = this.getOption("cancelEl"), f = this.getOption("submitEl"), f && this.$el.on("click", f, this.triggerSubmit), a && this.$el.on("click", a, this.triggerCancel), h = []; + for(c in this.views)b.isString(c) && "length" !== c ? (d = c.match(/^(\S+)\s*(.*)$/), g = d[1], e = d[2], h.push(this.$el.on(g, e, this.views[c], this.triggerView))) : h.push(void 0); + return h + }, g.prototype.undelegateModalEvents = function(){ + var a, c, d, e, f, g, h; + this.active = !1, a = this.getOption("cancelEl"), f = this.getOption("submitEl"), f && this.$el.off("click", f, this.triggerSubmit), a && this.$el.off("click", a, this.triggerCancel), h = []; + for(c in this.views)b.isString(c) && "length" !== c ? (d = c.match(/^(\S+)\s*(.*)$/), g = d[1], e = d[2], h.push(this.$el.off(g, e, this.views[c], this.triggerView))) : h.push(void 0); + return h + }, g.prototype.checkKey = function(a){ + if(this.active)switch(a.keyCode) { + case 27: + return this.triggerCancel(a); + case 13: + return this.triggerSubmit(a) + } + }, g.prototype.clickOutside = function(){ + var a; + return (null != (a = this.outsideElement) ? a.hasClass("" + this.prefix + "-wrapper") : void 0) && this.active ? this.triggerCancel() : void 0 + }, g.prototype.clickOutsideElement = function(a){ + return this.outsideElement = e.$(a.target) + }, g.prototype.buildTemplate = function(a, c){ + var d; + return (d = "function" == typeof a ? a : b.template(e.$(a).html()))(c) + }, g.prototype.buildView = function(a, c){ + var d; + if(a)return c && b.isFunction(c) && (c = c()), b.isFunction(a) ? (d = new a(c || this.args[0]), d instanceof e.View ? { + el: d.render().$el, + view: d + } : {el: a(c || this.args[0])}) : {view: a, el: a.$el} + }, g.prototype.triggerView = function(a){ + var c, d, e, f, g, h, i; + if(null != a && "function" == typeof a.preventDefault && a.preventDefault(), f = a.data, d = this.buildView(f.view, f.viewOptions), this.currentView && (this.previousView = this.currentView, !(null != (i = f.openOptions) ? i.skipSubmit : void 0))){ + if(("function" == typeof(g = this.previousView).beforeSubmit ? g.beforeSubmit(a) : void 0) === !1)return; + "function" == typeof(h = this.previousView).submit && h.submit() + } + this.currentView = d.view || d.el, c = 0; + for(e in this.views)f.view === this.views[e].view && (this.currentIndex = c), c++; + return f.onActive && (b.isFunction(f.onActive) ? f.onActive(this) : b.isString(f.onActive) && this[f.onActive].call(this, f)), this.shouldAnimate ? this.animateToView(d.el) : (this.shouldAnimate = !0, this.$(this.viewContainerEl).html(d.el)) + }, g.prototype.animateToView = function(a){ + var b, c, d, f, g, h, i; + return f = { + position: "relative", + top: -9999, + left: -9999 + }, g = e.$("").css(f), g.html(this.$el.clone().css(f)), 0 !== e.$("tester").length ? e.$("tester").replaceWith(g) : e.$("body").append(g), b = g.find(this.viewContainer ? this.viewContainer : "." + this.prefix + "-modal"), b.removeAttr("style"), d = b.outerHeight(), b.html(a), c = b.outerHeight(), d === c ? (this.$(this.viewContainerEl).html(a), "function" == typeof(h = this.currentView).onShow && h.onShow(), null != (i = this.previousView) && "function" == typeof i.destroy ? i.destroy() : void 0) : this.animate ? (this.$(this.viewContainerEl).css({opacity: 0}), this.$(this.viewContainerEl).animate({height: c}, 100, function(b){ + return function(){ + var c, d; + return b.$(b.viewContainerEl).css({opacity: 1}).removeAttr("style"), b.$(b.viewContainerEl).html(a), "function" == typeof(c = b.currentView).onShow && c.onShow(), null != (d = b.previousView) && "function" == typeof d.destroy ? d.destroy() : void 0 + } + }(this))) : this.$(this.viewContainerEl).css({height: c}).html(a) + }, g.prototype.triggerSubmit = function(a){ + var b, c; + return null != a && a.preventDefault(), e.$(a.target).is("textarea") || this.beforeSubmit && this.beforeSubmit(a) === !1 || this.currentView && this.currentView.beforeSubmit && this.currentView.beforeSubmit(a) === !1 ? void 0 : this.submit || (null != (b = this.currentView) ? b.submit : void 0) || this.getOption("submitEl") ? (null != (c = this.currentView) && "function" == typeof c.submit && c.submit(), "function" == typeof this.submit && this.submit(), this.regionEnabled ? this.trigger("modal:destroy") : this.destroy()) : this.triggerCancel() + }, g.prototype.triggerCancel = function(a){ + return null != a && a.preventDefault(), this.beforeCancel && this.beforeCancel() === !1 ? void 0 : ("function" == typeof this.cancel && this.cancel(), this.regionEnabled ? this.trigger("modal:destroy") : this.destroy()) + }, g.prototype.destroy = function(){ + var a; + return e.$("body").off("keyup.bbm", this.checkKey), this.$el.off("mouseup.bbm", this.clickOutsideElement), this.$el.off("click.bbm", this.clickOutside), e.$("tester").remove(), "function" == typeof this.onDestroy && this.onDestroy(), this.shouldAnimate = !1, this.modalEl.addClass("" + this.prefix + "-modal--destroy"), a = function(a){ + return function(){ + var b; + return null != (b = a.currentView) && "function" == typeof b.remove && b.remove(), a.remove() + } + }(this), this.$el.fadeOut && this.animate ? (this.$el.fadeOut({duration: 200}), b.delay(function(){ + return a() + }, 200)) : a() + }, g.prototype.openAt = function(a){ + var c, d, e, f, g; + b.isNumber(a) ? c = a : b.isNumber(a._index) && (c = a._index), e = 0; + for(f in this.views)if("length" !== f)if(b.isNumber(c))e === c && (g = this.views[f]), e++; + else if(b.isObject(a))for(d in this.views[f])a[d] === this.views[f][d] && (g = this.views[f]); + return g && (this.currentIndex = b.indexOf(this.views, g), this.triggerView({data: b.extend(g, {openOptions: a})})), this + }, g.prototype.next = function(a){ + return null == a && (a = {}), this.currentIndex + 1 < this.views.length ? this.openAt(b.extend(a, {_index: this.currentIndex + 1})) : void 0 + }, g.prototype.previous = function(a){ + return null == a && (a = {}), this.currentIndex - 1 < this.views.length - 1 ? this.openAt(b.extend(a, {_index: this.currentIndex - 1})) : void 0 + }, g + }(e.View), e.Modal = f, e.Modal + }) +}).call(this); \ No newline at end of file diff --git a/public/js/client.js b/public/js/client.js index 0f797ca..aefd75a 100644 --- a/public/js/client.js +++ b/public/js/client.js @@ -1,6 +1,7 @@ /*("http://localhost:16918")*/ var socketCluster = require("socketcluster-client"); var Backbone = require("backbone"); +require("./backbone.modal-min"); var Handlebars = require("handlebars"); var $ = require("jquery"); //var Lobby = require("./client-lobby"); @@ -97,11 +98,11 @@ var App = Backbone.Router.extend({ var SideView = Backbone.View.extend({ el: ".container", - template: Handlebars.compile('
' + + template: Handlebars.compile('
' + '' + '
'), templateCards: Handlebars.compile('{{#each this}}' + - '
' + + '
' + '{{#if _boost}}+{{_boost}}{{/if}}' + '' + '
' + @@ -206,6 +207,7 @@ var SideView = Backbone.View.extend({ var BattleView = Backbone.View.extend({ className: "container", template: Handlebars.compile($("#battle-template").html()), + templatePreview: Handlebars.compile($("#preview-template").html()), initialize: function(options){ var self = this; var user = this.user = options.user; @@ -214,54 +216,14 @@ var BattleView = Backbone.View.extend({ $(this.el).prependTo('body'); - this.listenTo(user, "change:showPreview", this.render); + this.listenTo(user, "change:showPreview", this.renderPreview); this.listenTo(user, "change:waiting", this.render); this.listenTo(user, "change:passing", this.render); + this.listenTo(user, "change:openDiscard", this.render); this.$hand = this.$el.find(".field-hand"); this.$preview = this.$el.find(".card-preview"); - /*//this.battleChannel = app.socket.subscribe() - - app.receive("update:hand", function(data){ - if(user.get("roomSide") == data._roomSide){ - self.handCards = JSON.parse(data.cards); - self.render(); - } - }); - - app.receive("update:info", function(data){ - var _side = data._roomSide; - var infoData = data.info; - var leader = data.leader; - - - var side = yourSide; - if(user.get("roomSide") != _side){ - side = otherSide; - } - side.infoData = infoData; - side.leader = leader; - side.render(); - }); - - app.receive("update:fields", function(data){ - var close, ranged, siege; - var _side = data._roomSide; - - var side = yourSide; - if(user.get("roomSide") != _side){ - side = otherSide; - } - - - side.field.close = data.close; - side.field.ranged = data.ranged; - side.field.siege = data.siege; - side.field.weather = data.weather; - - side.render(); - })*/ var interval = setInterval(function(){ if(!user.get("room")) return; @@ -275,15 +237,15 @@ var BattleView = Backbone.View.extend({ yourSide = this.yourSide = new SideView({side: ".player", app: this.app, battleView: this}); otherSide = this.otherSide = new SideView({side: ".foe", app: this.app, battleView: this}); - /*yourSide = this.yourSide = new SideView({side: ".player", app: app, battleView: this}); - otherSide = this.otherSide = new SideView({side: ".foe", app: app, battleView: this});*/ }, events: { "mouseover .card": "onMouseover", "mouseleave .card": "onMouseleave", "click .field-hand": "onClick", "click .battleside.player": "onClickDecoy", - "click .button-pass": "onPassing" + "click .button-pass": "onPassing", + "click .field-discard": "openDiscard", + "click .field-leader": "clickLeader" }, onPassing: function(){ if(this.user.get("passing")) return; @@ -294,11 +256,21 @@ var BattleView = Backbone.View.extend({ onClick: function(e){ if(!!this.user.get("waiting")) return; if(!!this.user.get("passing")) return; + var self = this; var $card = $(e.target).closest(".card"); var id = $card.data("id"); var key = $card.data("key"); + if(!!this.user.get("waitForDecoy")){ + if(id === this.user.get("waitForDecoy")){ + this.user.set("waitForDecoy", false); + this.app.send("cancel:decoy"); + this.render(); + } + return; + } + this.app.send("play:cardFromHand", { id: id }); @@ -306,17 +278,7 @@ var BattleView = Backbone.View.extend({ if(key === "decoy"){ console.log("its decoy!!!"); this.user.set("waitForDecoy", id); - /* - this.$el.find(".battleside.player").on("click", ".card", function(e) { - console.log("replacement card found: "); - var $card = $(e.target).closest(".card"); - var _id = $card.data("id"); - self.app.send("decoy:replaceWith", { - oldCard: id, - newCard: _id - }) - self.$el.find(".battleside.player").off("click"); - });*/ + this.render(); } }, onClickDecoy: function(e){ @@ -336,22 +298,54 @@ var BattleView = Backbone.View.extend({ onMouseleave: function(e){ this.user.set("showPreview", null); }, + openDiscard: function(e){ + var $discard = $(e.target).closest(".field-discard"); + console.log("opened discard"); + var side; + if($discard.parent().hasClass("player")){ + side = this.yourSide; + } else { + side = this.otherSide; + } + this.user.set("openDiscard", { + discard: side.infoData.discard, + name: side.infoData.name + }); + }, render: function(){ var self = this; this.$el.html(this.template({ - cards: self.handCards, - preview: self.user.get("showPreview") + cards: self.handCards/*, + preview: self.user.get("showPreview")*/ })); if(!(this.otherSide && this.yourSide)) return; this.otherSide.render(); this.yourSide.render(); - /* this.$el() - if(!(this.yourSide && this.otherSide)) - return this; - this.yourSide.render(); - this.otherSide.render();*/ + + + if(this.user.get("openDiscard")){ + var modal = new Modal({model: this.user}); + this.$el.prepend(modal.render().el); + } + + if(this.user.get("waitForDecoy")){ + var id = this.user.get("waitForDecoy"); + this.$el.find("[data-id='" + id + "']").addClass("activeCard"); + } return this; }, + renderPreview: function(){ + this.$el.find(".card-preview").html(this.templatePreview({src: this.user.get("showPreview")})) + }, + clickLeader: function(e) { + var $card = $(e.target).closest(".field-leader"); + console.log("click leader"); + if(!$card.parent().hasClass("player")) return; + if($card.hasClass("disabled")) return; + + + this.app.send("activate:leader") + }, setUpBattleEvents: function(channelName){ this.battleChannel = this.app.socket.subscribe(channelName); var self = this; @@ -363,6 +357,7 @@ var BattleView = Backbone.View.extend({ if(event === "update:hand"){ if(user.get("roomSide") == data._roomSide){ self.handCards = JSON.parse(data.cards); + self.user.set("handCards", self.handCards); self.render(); } } @@ -377,6 +372,9 @@ var BattleView = Backbone.View.extend({ } side.infoData = infoData; side.leader = leader; + + side.infoData.discard = JSON.parse(side.infoData.discard); + side.render(); } else if(event === "update:fields"){ @@ -396,6 +394,14 @@ var BattleView = Backbone.View.extend({ } }); +var Modal = Backbone.Modal.extend({ + template: Handlebars.compile($("#modal-template").html()), + cancelEl: ".bbm-close", + cancel: function(){ + this.model.set("openDiscard", false); + } +}); + var User = Backbone.Model.extend({ defaults: { name: "" @@ -432,6 +438,7 @@ var User = Backbone.Model.extend({ var waiting = data.waiting; self.set("waiting", waiting); }) + app.receive("set:passing", function(data){ var passing = data.passing; self.set("passing", passing); diff --git a/public/scss/_backbone.modal.sass b/public/scss/_backbone.modal.sass new file mode 100644 index 0000000..8b1a6fe --- /dev/null +++ b/public/scss/_backbone.modal.sass @@ -0,0 +1,25 @@ +/* Modal positioning */ +.bbm-wrapper + box-sizing: border-box + position: fixed + left: 0 + top: 0 + width: 100% + height: 100% + z-index: 100 + padding: 50px 10px + + * + box-sizing: border-box + + overflow: auto + +.bbm-modal + border-radius: 3px + margin: auto + width: auto + max-width: 550px + +.bbm-views + width: 100% + box-sizing: border-box diff --git a/public/scss/_backbone.modal.theme.sass b/public/scss/_backbone.modal.theme.sass new file mode 100644 index 0000000..2832091 --- /dev/null +++ b/public/scss/_backbone.modal.theme.sass @@ -0,0 +1,130 @@ +.bbm-wrapper + background: rgba(0,0,0,.75) + -webkit-transition: background-color .3s + +.bbm-modal + background: white + box-shadow: 0 0px 6px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.9) + + +/* BLOCKS */ +.bbm-modal__topbar, +.bbm-modal__bottombar + padding: 0 30px + +.bbm-modal__topbar + border-bottom: 1px solid rgba(0,0,0,.1) + margin: + bottom: 30px + + >ul + list-style: none + text-align: center + padding: 0 + margin: 0 + +.bbm-modal__tab + display: inline-block + padding: 15px 10px + + a + font: + size: 16px + weight: bold + color: #999 + + &:hover, + &.active + color: #222 + +.bbm-modal__title + padding: 20px 0 19px + margin: 0 + font: + weight: normal + size: 22px + line-height: 1em + color: #312D3A + +.bbm-modal__section + padding: 0 30px + margin-top: 0px + font: + size: 16px + line-height: 26px + color: #575656 + + p + font: + size: 16px + line-height: 26px + color: #575656 + + &:last-child + padding: 0 + margin-bottom: 0 + + a + color: #FF643C + + h3 + margin: 0 + font-size: 20px + line-height: 1em + +.bbm-modal__bottombar + border-top: 1px solid rgba(0,0,0,.1) + padding: 18px + text-align: right + margin-top: 30px + + +/* MODULES */ +.bbm-group + content: "" + display: table + clear: both + +.bbm-button + display: inline-block + color: rgba(49,45,58,.8) + text-decoration: none + font: + size: 14px + weight: 500 + position: relative + line-height: 1em + padding: 10px 14px + border-radius: 3px + background: #FCFCFC + cursor: default + + background-image: -o-linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.15) 100%) + background-image: -moz-linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.15) 100%) + background-image: -webkit-linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.15) 100%) + background-image: -ms-linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.15) 100%) + background-image: linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.15) 100%) + + -moz-box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.10), inset 0px 0px 0px 1px rgba(0,0,0,0.20) + -webkit-box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.10), inset 0px 0px 0px 1px rgba(0,0,0,0.20) + box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.10), inset 0px 0px 0px 1px rgba(0,0,0,0.20) + + &.inactive + opacity: .5 + pointer-events: none + + &:active + background-image: -o-linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.25) 100%) + background-image: -moz-linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.25) 100%) + background-image: -webkit-linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.25) 100%) + background-image: -ms-linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.25) 100%) + background-image: linear-gradient(rgba(70,30,170,0) 0%, rgba(65,61,75,.25) 100%) + + -moz-box-shadow: inset 0px 1px 2px 0px rgba(0,0,0,0.50), inset 0px 0px 0px 1px rgba(0,0,0,0.20) + -webkit-box-shadow: inset 0px 1px 2px 0px rgba(0,0,0,0.50), inset 0px 0px 0px 1px rgba(0,0,0,0.20) + box-shadow: inset 0px 1px 2px 0px rgba(0,0,0,0.50), inset 0px 0px 0px 1px rgba(0,0,0,0.20) + + +/* ANIMATIONS */ + +/* Open modal */ diff --git a/public/scss/_style.sass b/public/scss/_style.sass new file mode 100644 index 0000000..7563485 --- /dev/null +++ b/public/scss/_style.sass @@ -0,0 +1,45 @@ +// Custom styling here + +a + text-decoration: none + font-style: normal + +// Add icons to tabs +.bbm-modal__tab + padding: 0 + + a + display: block + padding: + top: 55px + bottom: 10px + left: 20px + right: 20px + position: relative + font: + size: 13px + + &:before + position: absolute + content: "" + background: url(img/tab-icons.png) + left: 50% + top: 10px + margin: + left: -20px + width: 40px + height: 40px + opacity: .5 + + &.active + opacity: 1 + + &:before + opacity: 1 + + + &:last-child + margin-left: -5px + a + &:before + background-position: -40px \ No newline at end of file diff --git a/public/scss/main.scss b/public/scss/main.scss index cbe1eb0..b30cc86 100644 --- a/public/scss/main.scss +++ b/public/scss/main.scss @@ -1,3 +1,7 @@ +//@import "style"; +@import "backbone.modal"; +@import "backbone.modal.theme"; + $height: 600px; $game-height: 800px; @@ -91,12 +95,22 @@ $game-height: 800px; margin-left: 30px; cursor: default; } + + &.disabled { + opacity: 0.5; + } + + &.activeCard { + position: relative; + z-index: 11; + transform: scale(1.5,1.5) !important; + } } .card-preview { position: absolute;/* display: none;*/ - z-index: 10; + z-index: 110; } i { diff --git a/server/Battle.js b/server/Battle.js index e67d210..3f02d65 100644 --- a/server/Battle.js +++ b/server/Battle.js @@ -80,6 +80,10 @@ var Battle = (function(){ /*if(__flag instanceof Battleside) { side = __flag; }*/ + if(!(side instanceof Battleside)){ + console.trace("side is not a battleside!"); + return + } if(side.isPassing()){ if(__flag){ return this.startNextRound(); @@ -87,10 +91,7 @@ var Battle = (function(){ return this.switchTurn(side.foe, 1); } - /*PubSub.publish("onEachTurn");*/ this.runEvent("EachTurn"); - /* - PubSub.publish("turn/" + side.getID());*/ this.runEvent("Turn" + side.getID()); console.log("current Turn: ", side.getName()); @@ -100,6 +101,7 @@ var Battle = (function(){ var loser = this.checkRubies(); if(this.checkIfIsOver()){ console.log("its over!"); + this.update(); return; } @@ -153,6 +155,7 @@ var Battle = (function(){ obj.cb = obj.cb.bind(ctx) obj.cb.apply(ctx, obj.onArgs.concat(args)); }); + this.update(); } r.on = function(eventid, cb, ctx, args){ @@ -161,9 +164,10 @@ var Battle = (function(){ var event = "on" + eventid; var obj = {}; - if(!ctx) { + if(!ctx){ obj.cb = cb; - } else { + } + else { obj.cb = cb.bind(ctx); } obj.onArgs = args; @@ -187,6 +191,7 @@ var Battle = (function(){ r.off = function(eventid){ var event = "on" + eventid; + if(!this.events[event]) return; this.events[event].forEach(function(e){ e = null; }); @@ -215,7 +220,7 @@ var Battle = (function(){ //tie this.p1.removeRuby(); this.p2.removeRuby(); - return 0; + return Math.random() > 0.5 ? this.p1 : this.p2; } diff --git a/server/Battleside.js b/server/Battleside.js index 5360f04..9047ea8 100644 --- a/server/Battleside.js +++ b/server/Battleside.js @@ -4,7 +4,6 @@ var Deck = require("./Deck"); var Hand = require("./Hand"); var Card = require("./Card"); var Field = require("./Field"); -//var PubSub = require("pubsub-js"); var Battleside; @@ -37,6 +36,22 @@ Battleside = (function(){ this.off = this.battle.off.bind(this.battle); + this.receive("activate:leader", function(){ + if(self._isWaiting) return; + if(self.isPassing()) return; + + console.log("leader activated"); + + var leaderCard = self.getLeader(); + if(leaderCard.isDisabled()) return; + + + var ability = leaderCard.getAbility(); + + ability.onActivate.apply(self); + leaderCard.setDisabled(true); + self.update(); + }) this.receive("play:cardFromHand", function(data){ if(self._isWaiting) return; if(self.isPassing()) return; @@ -51,14 +66,15 @@ Battleside = (function(){ if(card === -1) throw new Error("decoy:replace | unknown card"); self.runEvent("Decoy:replaceWith", self, [card]); }) - this.receive("set:passing", function() { + this.receive("cancel:decoy", function(){ + self.off("Decoy:replaceWith"); + }) + this.receive("set:passing", function(){ self.setPassing(true); - self.update();/* - PubSub.publish("nextTurn");*/ + self.update(); self.runEvent("NextTurn", null, [self.foe]); }) - /*PubSub.subscribe("turn/" + this.getID(), this.onTurnStart.bind(this));*/ this.on("Turn" + this.getID(), this.onTurnStart, this); }; var r = Battleside.prototype; @@ -69,11 +85,7 @@ Battleside = (function(){ */ r._name = null; r._discard = null; - /*r.leaderField = null; - r.closeField = null; - r._range = null; - r._siege = null; - r._field = null;*/ + r._rubies = 2; r._score = 0; r._isWaiting = null; @@ -89,7 +101,7 @@ Battleside = (function(){ r.battle = null; r.deck = null; - r.isPassing = function() { + r.isPassing = function(){ return this._passing; } @@ -97,7 +109,7 @@ Battleside = (function(){ this.field[Card.TYPE.WEATHER] = p2.field[Card.TYPE.WEATHER] = Field(Card.TYPE.WEATHER); } - r.findCardOnFieldByID = function(id) { + r.findCardOnFieldByID = function(id){ for(var key in this.field) { var field = this.field[key]; var card = field.getCard(id); @@ -106,7 +118,7 @@ Battleside = (function(){ return -1; } - r.setPassing = function(b) { + r.setPassing = function(b){ this._passing = b; this.send("set:passing", {passing: this._passing}, true); } @@ -129,6 +141,10 @@ Battleside = (function(){ this.field[Card.TYPE.LEADER].add(leaderCard[0]); } + r.getLeader = function(){ + return this.field[Card.TYPE.LEADER].get()[0]; + } + r.getID = function(){ return this.n; } @@ -158,19 +174,20 @@ Battleside = (function(){ lives: this._rubies, score: this.calcScore(), hand: this.hand.length(), + discard: this.getDiscard(true), passing: this._passing } } - r.getRubies = function() { + r.getRubies = function(){ return this._rubies; } - r.getScore = function() { + r.getScore = function(){ return +this.calcScore(); } - r.removeRuby = function() { + r.removeRuby = function(){ this._rubies--; } @@ -210,14 +227,14 @@ Battleside = (function(){ r.playCard = function(card){ if(card === null || card === -1) return; - this.hand.remove(card); - if(!this.placeCard(card)) return; + this.hand.remove(card); + this.update(); - this.runEvent("NextTurn", this, [this.foe]); + this.runEvent("NextTurn", null, [this.foe]); } r.placeCard = function(card){ @@ -251,7 +268,7 @@ Battleside = (function(){ if(ability.replaceWith){ obj._canclePlacement = true; - this.on("Decoy:replaceWith", function(replaceCard) { + this.on("Decoy:replaceWith", function(replaceCard){ if(replaceCard.getType() == Card.TYPE.LEADER || replaceCard.getType() == Card.TYPE.WEATHER || replaceCard.getType() == Card.TYPE.SPECIAL){ @@ -261,11 +278,12 @@ Battleside = (function(){ self.off("Decoy:replaceWith"); var field = self.field[replaceCard.getType()]; + field.replaceWith(replaceCard, card); self.hand.add(replaceCard); -/* - self.update();*/ + self.hand.remove(card); + self.update(); self.runEvent("NextTurn", null, [self.foe]); }) @@ -278,6 +296,7 @@ Battleside = (function(){ this.on("EachCardPlace", ability.onEachCardPlace, this, [card]); } + this.update(); } } @@ -290,7 +309,7 @@ Battleside = (function(){ } } - r.clearMainFields = function() { + r.clearMainFields = function(){ var cards1 = this.field[Card.TYPE.CLOSE_COMBAT].removeAll(); var cards2 = this.field[Card.TYPE.RANGED].removeAll(); var cards3 = this.field[Card.TYPE.SIEGE].removeAll(); @@ -299,14 +318,21 @@ Battleside = (function(){ this.addToDiscard(cards); } - r.addToDiscard = function(cards) { + r.addToDiscard = function(cards){ var self = this; - cards.forEach(function(card) { + cards.forEach(function(card){ self._discard.push(card); }); } - r.resetNewRound = function() { + r.getDiscard = function(json){ + if(json){ + return JSON.stringify(this._discard); + } + return this._discard; + } + + r.resetNewRound = function(){ this.clearMainFields(); this.setPassing(false); } diff --git a/server/Card.js b/server/Card.js index dca0d1b..a096643 100644 --- a/server/Card.js +++ b/server/Card.js @@ -9,9 +9,11 @@ var Card = (function(){ /** * constructor here */ + this.setDisabled(false); this.channel = {}; this._key = key; this._data = CardData[key]; + this._data.key = key; this._boost = 0; this._forcedPower = -1; this._init(); @@ -29,6 +31,7 @@ var Card = (function(){ r._owner = null; r._boost = null; r._forcedPower = null; + r._disabled = null; Card.__id = 0; Card.TYPE = { CLOSE_COMBAT: 0, @@ -97,6 +100,14 @@ var Card = (function(){ this._boost += nr; } + r.isDisabled = function() { + return this._disabled; + } + + r.setDisabled = function(b) { + this._disabled = b; + } + r.getProperty = function(prop){ return this._data[prop]; } diff --git a/server/Deck.js b/server/Deck.js index e657a1e..2978da8 100644 --- a/server/Deck.js +++ b/server/Deck.js @@ -44,19 +44,12 @@ var Deck = (function(){ return this._deck; } - r.draw = function(times){ + r.draw = function(){ if(!this._deck.length) return 0; var card = this.pop(); return card; } - /* - r._loadCards = function(){ - var n = this._originalDeck.length; - for(var i = 0; i < n; i++) { - this._deck.push(CardManager().add(this._originalDeck[i], this._owner)); - } - }*/ r._loadCards = function(){ this._deck = this.getDeck().map(function(cardkey){ @@ -77,7 +70,6 @@ var Deck = (function(){ if(card.getProperty(key) == val){ res.push(card); } - }); return res; } @@ -93,7 +85,7 @@ var Deck = (function(){ }*/ var c = this.getDeck()[i]; if(c.getID() === card.getID()){ - return this.getDeck().splice(i, 1); + return this.getDeck().splice(i, 1)[0]; } } return -1; diff --git a/server/Hand.js b/server/Hand.js index 06e9a94..95323d0 100644 --- a/server/Hand.js +++ b/server/Hand.js @@ -42,6 +42,7 @@ var Hand = (function(){ r.remove = function(id){ var n = this.length(); + //console.trace(id); id = id instanceof Card ? id.getID() : id; for(var i = 0; i < n; i++) { diff --git a/server/Room.js b/server/Room.js index 83fd37e..d17529d 100644 --- a/server/Room.js +++ b/server/Room.js @@ -56,23 +56,6 @@ var Room = (function(){ r.isOpen = function(){ return !(this._users.length >= 2); } -/* - - r.send = function(event, data){ - */ -/*this.socket.publish(this._id + "|" + event, data); - this.socket.publish(this._id, { - event: event, - data: data - }); - var subs = this.socket.subscriptions(); - subs.forEach(function(sub) { - - });*//* - - this._channel.publish(event, data); - } -*/ r.getPlayers = function(){ return this._users; @@ -92,26 +75,13 @@ var Room = (function(){ if(this.bothReady()){ this._battle.init(); } - /* - if(!this.checkIfReady()) return; - this._users[0].send("init:battle", {side: "p1"}); - this._users[1].send("init:battle", {side: "p2"}); - if(!this.checkIfReady()) return; - this._battle.init();*/ } r.bothReady = function(){ return !!this._ready[this._users[0].getID()] && !!this._ready[this._users[1].getID()]; } - /* - r.checkIfReady = function(){ - for(var i = 0; i < this._users.length; i++) { - if(!this._ready[this._users[i].getID()]) return false; - } - return true; - }*/ - + return Room; })(); diff --git a/server/_server.js b/server/_server.js deleted file mode 100644 index d00d4a7..0000000 --- a/server/_server.js +++ /dev/null @@ -1,2 +0,0 @@ -var socket = require("./Socket")(); -