diff --git a/app/lib/Router.coffee b/app/lib/Router.coffee index 7c12e1cb8..603e4a7d0 100644 --- a/app/lib/Router.coffee +++ b/app/lib/Router.coffee @@ -17,7 +17,8 @@ module.exports = class CocoRouter extends Backbone.Router 'editor/:model(/:slug_or_id)(/:subview)': 'editorModelView' # Experimenting with direct links -# 'play/ladder/:levelID/team/:team': go('play/ladder/team_view') + 'play/ladder/:levelID': go('play/ladder/ladder_view') + 'play/ladder': go('play/ladder_home') # db and file urls call the server directly 'db/*path': 'routeToServer' diff --git a/app/lib/surface/CocoSprite.coffee b/app/lib/surface/CocoSprite.coffee index d80d8705a..2e45c10f4 100644 --- a/app/lib/surface/CocoSprite.coffee +++ b/app/lib/surface/CocoSprite.coffee @@ -84,14 +84,18 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass AudioPlayer.preloadSoundReference sound for sound in sounds @stillLoading = false if @thangType.get('raster') + @actions = {} @isRaster = true @setUpRasterImage() - @actions = {} else @actions = @thangType.getActions() @buildFromSpriteSheet @buildSpriteSheet() @createMarks() + finishSetup: -> + return unless @thang + @update true # Reflect initial scale and other state + setUpRasterImage: -> raster = @thangType.get('raster') image = new createjs.Bitmap('/file/'+raster) @@ -106,7 +110,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass reg = @getOffset 'registration' @imageObject.regX = -reg.x @imageObject.regY = -reg.y - @updateScale() + @finishSetup() destroy: -> mark.destroy() for name, mark of @marks @@ -150,6 +154,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass @imageObject.layerPriority = @thangType.get 'layerPriority' @imageObject.name = @thang?.spriteName or @thangType.get 'name' @imageObject.on 'animationend', @playNextAction + @finishSetup() ################################################## # QUEUEING AND PLAYING ACTIONS @@ -251,7 +256,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass return if @destroyed @options.groundLayer.removeChild circle delete @handledDisplayEvents[event] - + showTextEvents: -> return unless @thang?.currentEvents for event in @thang.currentEvents @@ -342,6 +347,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass scaleX *= scale scaleY *= scale + console.error "No thang for", @ unless @thang scaleFactorX = @thang.scaleFactorX ? @scaleFactor scaleFactorY = @thang.scaleFactorY ? @scaleFactor @imageObject.scaleX = @originalScaleX * scaleX * scaleFactorX diff --git a/app/lib/surface/WizardSprite.coffee b/app/lib/surface/WizardSprite.coffee index f8d7b5b1b..e8762d08b 100644 --- a/app/lib/surface/WizardSprite.coffee +++ b/app/lib/surface/WizardSprite.coffee @@ -29,10 +29,9 @@ module.exports = class WizardSprite extends IndieSprite 'right': 'onMoveKey' constructor: (thangType, options) -> - if options?.isSelf + if @isSelf = options.isSelf options.colorConfig = $.extend(true, {}, me.get('wizard')?.colorConfig) or {} super thangType, options - @isSelf = options.isSelf @targetPos = @thang.pos if @isSelf @setNameLabel me.displayName() @@ -40,6 +39,8 @@ module.exports = class WizardSprite extends IndieSprite else if options.name @setNameLabel options.name + finishSetup: -> # No initial setup update needed. + makeIndieThang: (thangType, thangID, pos) -> thang = super thangType, thangID, pos thang.isSelectable = false diff --git a/app/locale/en.coffee b/app/locale/en.coffee index ec04add0f..36ae1aa16 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -214,7 +214,6 @@ candidate_active: "Them?" play_level: - level_load_error: "Level could not be loaded: " done: "Done" grid: "Grid" customize_wizard: "Customize Wizard" diff --git a/app/styles/play.sass b/app/styles/play.sass index e3e31d8fa..900207ca9 100644 --- a/app/styles/play.sass +++ b/app/styles/play.sass @@ -46,6 +46,3 @@ color: black text-shadow: 0 1px 0 white - .alert-warning h2 - color: black - text-align: center diff --git a/app/styles/play/ladder.sass b/app/styles/play/ladder/ladder.sass similarity index 100% rename from app/styles/play/ladder.sass rename to app/styles/play/ladder/ladder.sass diff --git a/app/styles/play/ladder_home.sass b/app/styles/play/ladder_home.sass new file mode 100644 index 000000000..805c0376e --- /dev/null +++ b/app/styles/play/ladder_home.sass @@ -0,0 +1,54 @@ +@import "app/styles/bootstrap/mixins" +@import "app/styles/bootstrap/variables" + +#ladder-home-view + .level + width: 100% + position: relative + margin-bottom: 20px + text-shadow: 2px 2px 5px black + + &:hover div + color: lighten($yellow, 20%) + + &:hover img + filter: brightness(1.2) + -webkit-filter: brightness(1.2) + box-shadow: 0 0 5px black + + .level-image + width: 100% + + .overlay-text + color: $yellow + font-family: Bangers + @include transition(color .10s linear) + + .level-difficulty + position: absolute + left: 0px + bottom: 0px + font-size: 25px + padding-right: 10px + background-color: rgba(255, 255, 255, 0.75) + border-radius: 6px + + .play-text-container + position: absolute + left: 50% + bottom: -10px + + .play-text + margin-left: -50% + font-size: 50px + + a[disabled] .level + opacity: 0.7 + + a.complete .level-difficulty:after + content: " - Complete!" + color: $yellow + + a.started .level-difficulty:after + content: " - Started" + color: desaturate($yellow, 50%) diff --git a/app/styles/play/level.sass b/app/styles/play/level.sass index f63b43650..64ea6e43a 100644 --- a/app/styles/play/level.sass +++ b/app/styles/play/level.sass @@ -16,6 +16,7 @@ body.is-playing #canvas-wrapper width: 55% position: relative + overflow: hidden canvas#surface background-color: #333 diff --git a/app/styles/play/level/goals.sass b/app/styles/play/level/goals.sass index 6ad657253..aeda71bbc 100644 --- a/app/styles/play/level/goals.sass +++ b/app/styles/play/level/goals.sass @@ -1,25 +1,24 @@ +@import "../../bootstrap/mixins" + #goals-view position: absolute left: 10px - top: 42px + top: -100px + @include transition(top 0.5s ease-in-out) background-color: rgba(200,200,200,0.8) &.brighter background-color: rgba(200,200,200,1.0) border: black - padding: 5px 7px 5px 5px + padding: 15px 7px 5px 5px box-sizing: border-box border: 1px solid #333 border-radius: 5px - cursor: pointer - user-select: none - -webkit-user-select: none h3 - font-size: 16px + font-size: 14px margin: 0 - line-height: 20px color: black i diff --git a/app/templates/home.jade b/app/templates/home.jade index 0fa7022e5..e790d40bf 100644 --- a/app/templates/home.jade +++ b/app/templates/home.jade @@ -50,7 +50,7 @@ block content h4(data-i18n="home.for_beginners") For Beginners .play-text(data-i18n="home.play") Play - a#multiplayer(href="/play/ladder/dungeon-arena") + a#multiplayer(href="/play/ladder") div.game-mode-wrapper if isEnglish img(src="/images/pages/home/multiplayer.jpg").img-rounded diff --git a/app/templates/play.jade b/app/templates/play.jade index 911f14c92..f8d07e62f 100644 --- a/app/templates/play.jade +++ b/app/templates/play.jade @@ -2,12 +2,6 @@ extends /templates/base block content - if notFound - div(class="alert alert-warning") - h2 - span(data-i18n="play_level.level_load_error") Level could not be loaded: - | #{notFound} - h1(data-i18n="play.choose_your_level") Choose Your Level p span(data-i18n="play.adventurer_prefix") You can jump to any level below, or discuss the levels on diff --git a/app/templates/play/ladder.jade b/app/templates/play/ladder/ladder.jade similarity index 100% rename from app/templates/play/ladder.jade rename to app/templates/play/ladder/ladder.jade diff --git a/app/templates/play/ladder_home.jade b/app/templates/play/ladder_home.jade new file mode 100644 index 000000000..e3b976ae6 --- /dev/null +++ b/app/templates/play/ladder_home.jade @@ -0,0 +1,23 @@ +extends /templates/base + +block content + + each campaign in campaigns + .campaign-container + h1 + a(href="/play/#{campaign.levels[0].levelPath || 'level'}/#{campaign.levels[0].id}", data-i18n="play.campaign_#{campaign.id}")= campaign.name + p.campaign-description(data-i18n="[html]play.campaign_#{campaign.id}_description")!= campaign.description + each level in campaign.levels + a(href=level.disabled ? "/play/ladder" : "/play/ladder/#{level.id}", disabled=level.disabled, class=levelStatusMap[level.id] || '', title=level.description) + .level + if level.image + img.level-image(src="#{level.image}", alt="#{level.name}").img-rounded + else + img.level-image(src="/images/pages/home/multiplayer_notext.jpg", alt="#{level.name}").img-rounded + //h3= level.name + (level.disabled ? " (Coming soon!)" : "") + .overlay-text.level-difficulty + span(data-i18n="play.level_difficulty") Difficulty: + each i in Array(level.difficulty) + | ★ + .play-text-container + .overlay-text.play-text(data-i18n="home.play") Play diff --git a/app/templates/play/level.jade b/app/templates/play/level.jade index 3b22ef4a1..89418e365 100644 --- a/app/templates/play/level.jade +++ b/app/templates/play/level.jade @@ -11,8 +11,7 @@ canvas(width=924, height=589)#surface #canvas-left-gradient.gradient #canvas-top-gradient.gradient - - #goals-view.secret + #goals-view.secret #gold-view.secret.expanded diff --git a/app/templates/play/level/goals.jade b/app/templates/play/level/goals.jade index 150edf34c..f52931b0d 100644 --- a/app/templates/play/level/goals.jade +++ b/app/templates/play/level/goals.jade @@ -1,5 +1,3 @@ -h3 - i.icon-plus-sign.expanded - i.icon-minus-sign.collapsed +ul#primary-goals-list +h3 span(data-i18n="play_level.goals") Goals -ul#primary-goals-list \ No newline at end of file diff --git a/app/views/play/ladder_view.coffee b/app/views/play/ladder/ladder_view.coffee similarity index 91% rename from app/views/play/ladder_view.coffee rename to app/views/play/ladder/ladder_view.coffee index 26038ea81..dc9730009 100644 --- a/app/views/play/ladder_view.coffee +++ b/app/views/play/ladder/ladder_view.coffee @@ -2,14 +2,14 @@ RootView = require 'views/kinds/RootView' Level = require 'models/Level' LevelSession = require 'models/LevelSession' CocoCollection = require 'collections/CocoCollection' -{teamDataFromLevel} = require './ladder/utils' +{teamDataFromLevel} = require './utils' {me} = require 'lib/auth' application = require 'application' -LadderTabView = require './ladder/ladder_tab' -MyMatchesTabView = require './ladder/my_matches_tab' -SimulateTabView = require './ladder/simulate_tab' -LadderPlayModal = require './ladder/play_modal' +LadderTabView = require './ladder_tab' +MyMatchesTabView = require './my_matches_tab' +SimulateTabView = require './simulate_tab' +LadderPlayModal = require './play_modal' CocoClass = require 'lib/CocoClass' @@ -25,7 +25,7 @@ class LevelSessionsCollection extends CocoCollection module.exports = class LadderView extends RootView id: 'ladder-view' - template: require 'templates/play/ladder' + template: require 'templates/play/ladder/ladder' subscriptions: 'application:idle-changed': 'onIdleChanged' diff --git a/app/views/play/ladder_home.coffee b/app/views/play/ladder_home.coffee new file mode 100644 index 000000000..0150b2284 --- /dev/null +++ b/app/views/play/ladder_home.coffee @@ -0,0 +1,72 @@ +View = require 'views/kinds/RootView' +template = require 'templates/play/ladder_home' +LevelSession = require 'models/LevelSession' +CocoCollection = require 'collections/CocoCollection' + +class LevelSessionsCollection extends CocoCollection + url: '' + model: LevelSession + + constructor: (model) -> + super() + @url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID" + +module.exports = class LadderHomeView extends View + id: "ladder-home-view" + template: template + + constructor: (options) -> + super options + @levelStatusMap = {} + @sessions = new LevelSessionsCollection() + @sessions.fetch() + @listenToOnce @sessions, 'sync', @onSessionsLoaded + + onSessionsLoaded: (e) -> + for session in @sessions.models + @levelStatusMap[session.get('levelID')] = if session.get('state')?.complete then 'complete' else 'started' + @render() + + getRenderData: (context={}) -> + context = super(context) + arenas = [ + { + name: 'Greed' + difficulty: 4 + id: 'greed' + image: '/file/db/level/53558b5a9914f5a90d7ccddb/greed_banner.jpg' + description: "Liked Dungeon Arena and Gold Rush? Put them together in this economic arena!" + } + { + name: 'Dungeon Arena' + difficulty: 3 + id: 'dungeon-arena' + image: '/file/db/level/53173f76c269d400000543c2/Level%20Banner%20Dungeon%20Arena.jpg' + description: "Play head-to-head against fellow Wizards in a dungeon melee!" + } + { + name: 'Gold Rush' + difficulty: 3 + id: 'gold-rush' + image: '/file/db/level/533353722a61b7ca6832840c/Gold-Rush.png' + description: "Prove you are better at collecting gold than your opponent!" + } + { + name: 'Brawlwood' + difficulty: 4 + id: 'brawlwood' + image: '/file/db/level/52d97ecd32362bc86e004e87/Level%20Banner%20Brawlwood.jpg' + description: "Combat the armies of other Wizards in a strategic forest arena! (Fast computer required.)" + } + ] + + context.campaigns = [ + {id: "multiplayer", name: "Multiplayer Arenas", description: "... in which you code head-to-head against other players.", levels: arenas} + ] + context.levelStatusMap = @levelStatusMap + context + + afterRender: -> + super() + @$el.find('.modal').on 'shown.bs.modal', -> + $('input:visible:first', @).focus() diff --git a/app/views/play/level/goals_view.coffee b/app/views/play/level/goals_view.coffee index 85d7436ac..2f0264184 100644 --- a/app/views/play/level/goals_view.coffee +++ b/app/views/play/level/goals_view.coffee @@ -19,7 +19,8 @@ module.exports = class GoalsView extends View 'surface:playback-ended': 'onSurfacePlaybackEnded' events: - 'click': 'toggleCollapse' + 'mouseenter': -> @$el.css('top', -10) + 'mouseleave': -> @updateTop() toggleCollapse: (e) -> @$el.toggleClass('expanded').toggleClass('collapsed') @@ -60,6 +61,14 @@ module.exports = class GoalsView extends View render: -> super() @$el.addClass('secret').addClass('expanded') + + afterRender: -> + super() + @updateTop() + + updateTop: -> + @$el.css('top', 26 - @$el.outerHeight()) onSetLetterbox: (e) -> @$el.toggle not e.on + @updateTop() diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee index 63fd25f36..8662ecef4 100644 --- a/app/views/play_view.coffee +++ b/app/views/play_view.coffee @@ -143,6 +143,14 @@ module.exports = class PlayView extends View ] arenas = [ + { + name: 'Greed' + difficulty: 4 + id: 'greed' + image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png' + description: "Liked Dungeon Arena and Gold Rush? Put them together in this economic arena!" + levelPath: 'ladder' + } { name: 'Dungeon Arena' difficulty: 3 @@ -159,14 +167,6 @@ module.exports = class PlayView extends View description: "Prove you are better at collecting gold than your opponent!" levelPath: 'ladder' } - { - name: 'Greed' - difficulty: 4 - id: 'greed' - image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png' - description: "Liked Dungeon Arena and Gold Rush? Put them together in this economic arena!" - levelPath: 'ladder' - } { name: 'Brawlwood' difficulty: 4 diff --git a/headless_client.coffee b/headless_client.coffee index 88e38975c..bdd7eeded 100644 --- a/headless_client.coffee +++ b/headless_client.coffee @@ -13,7 +13,7 @@ headlessClientPath = "./headless_client/" options = workerCode: require headlessClientPath + 'worker_world' debug: false # Enable logging of ajax calls mainly - testing: true # Instead of simulating 'real' games, use the same one over and over again. Good for leak hunting. + testing: false # Instead of simulating 'real' games, use the same one over and over again. Good for leak hunting. testFile: require headlessClientPath + 'test.js' leakTest: false # Install callback that tries to find leaks automatically exitOnLeak: false # Exit if leak is found. Only useful if leaktest is set to true, obviously. diff --git a/scripts/simulate.coffee b/scripts/simulate.coffee index 346b0c196..01eccb5f9 100644 --- a/scripts/simulate.coffee +++ b/scripts/simulate.coffee @@ -1,12 +1,12 @@ spawn = require("child_process").spawn [sessionOne, sessionTwo] = [process.argv[2],process.argv[3]] - +homeDirectory = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE unless sessionOne and sessionTwo and sessionOne.length is 24 and sessionTwo.length is 24 console.log "Not enough games to continue!" process.exit(1) run = (cb) -> - command = spawn("coffee",["headless_client.coffee","one-game",sessionOne,sessionTwo],{cwd:"/Users/schmatz/codecombat/"}) + command = spawn("coffee",["headless_client.coffee","one-game",sessionOne,sessionTwo],{cwd: homeDirectory + "/codecombat/"}) result = "" command.stdout.on 'data', (data) -> result += data.toString()