From 01b91eb7e21f48f8c1f140262594274801100893 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Mon, 24 Feb 2014 16:59:17 -0800 Subject: [PATCH 01/32] Lowered the bob height for the wizard a bit. --- app/lib/surface/WizardSprite.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/surface/WizardSprite.coffee b/app/lib/surface/WizardSprite.coffee index 9f56b5c8a..665a93bf4 100644 --- a/app/lib/surface/WizardSprite.coffee +++ b/app/lib/surface/WizardSprite.coffee @@ -37,7 +37,7 @@ module.exports = class WizardSprite extends IndieSprite makeIndieThang: (thangType, thangID, pos) -> thang = super thangType, thangID, pos thang.isSelectable = false - thang.bobHeight = 1.5 + thang.bobHeight = 0.75 thang.bobTime = 2 thang.pos.z += thang.bobHeight thang From 242342315ff4338154f0bebb48a4bf0f5266a462 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Mon, 24 Feb 2014 19:49:05 -0800 Subject: [PATCH 02/32] Can now drag the mouse to move around the map. --- app/lib/surface/Camera.coffee | 17 +++++++++++++++++ app/lib/surface/SpriteBoss.coffee | 9 +++++++-- app/views/editor/level/thangs_tab_view.coffee | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/lib/surface/Camera.coffee b/app/lib/surface/Camera.coffee index 86994dca0..6c5ec946f 100644 --- a/app/lib/surface/Camera.coffee +++ b/app/lib/surface/Camera.coffee @@ -40,6 +40,8 @@ module.exports = class Camera extends CocoClass 'camera-zoom-out': 'onZoomOut' 'surface:mouse-scrolled': 'onMouseScrolled' 'level:restarted': 'onLevelRestarted' + 'sprite:mouse-down': 'onMouseDown' + 'sprite:dragged': 'onMouseDragged' # TODO: Fix tests to not use mainLayer constructor: (@canvasWidth, @canvasHeight, angle=Math.asin(0.75), hFOV=d2r(30)) -> @@ -164,6 +166,21 @@ module.exports = class Camera extends CocoClass target = @target @zoomTo target, newZoom, 0 + onMouseDown: (e) -> + return if @dragDisabled + @lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY} + + onMouseDragged: (e) -> + return if @dragDisabled + target = @boundTarget(@target, @zoom) + newPos = { + x: target.x + (@lastPos.x - e.originalEvent.rawX) / @zoom + y: target.y + (@lastPos.y - e.originalEvent.rawY) / @zoom + } + @zoomTo newPos, @zoom, 0 + @lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY} + Backbone.Mediator.publish 'camera:dragged' + onLevelRestarted: -> @setBounds(@firstBounds, false) diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index 7358b25a9..35d97ba59 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -13,7 +13,7 @@ module.exports = class SpriteBoss extends CocoClass 'bus:player-left': 'onPlayerLeft' 'level-set-debug': 'onSetDebug' 'level-highlight-sprites': 'onHighlightSprites' - 'sprite:mouse-down': 'onSpriteMouseDown' + 'sprite:mouse-up': 'onSpriteMouseUp' 'surface:stage-mouse-down': 'onStageMouseDown' 'level-select-sprite': 'onSelectSprite' 'level-suppress-selection-sounds': 'onSuppressSelectionSounds' @@ -21,6 +21,7 @@ module.exports = class SpriteBoss extends CocoClass 'level:restarted': 'onLevelRestarted' 'god:new-world-created': 'onNewWorld' 'tome:cast-spells': 'onCastSpells' + 'camera:dragged': 'onCameraDragged' constructor: (@options) -> super() @@ -226,8 +227,12 @@ module.exports = class SpriteBoss extends CocoClass onSelectSprite: (e) -> @selectThang e.thangID, e.spellName - onSpriteMouseDown: (e) -> + onCameraDragged: -> + @dragged = true + + onSpriteMouseUp: (e) -> return if key.shift and @options.choosing + return @dragged = false if @dragged sprite = if e.sprite?.thang?.isSelectable then e.sprite else null @selectSprite e, sprite diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee index 33d703b77..7fedf7d8f 100644 --- a/app/views/editor/level/thangs_tab_view.coffee +++ b/app/views/editor/level/thangs_tab_view.coffee @@ -144,6 +144,7 @@ module.exports = class ThangsTabView extends View @surface.playing = false @surface.setWorld @world @surface.camera.zoomTo({x:262, y:-164}, 1.66, 0) + @surface.camera.dragDisabled = true destroy: -> @selectAddThangType null From e63763d539ef3cc4d95d28e6a80c2168f8dcf02e Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Mon, 24 Feb 2014 20:27:38 -0800 Subject: [PATCH 03/32] Made the server resistant to req.user being undefined sometimes. --- package.json | 2 +- server/commons/Handler.coffee | 8 +++---- server/levels/level_handler.coffee | 2 ++ server/routes/contact.coffee | 1 + server/routes/db.coffee | 1 + server/routes/file.coffee | 2 +- server/users/user_handler.coffee | 10 +++++---- test/server/common.coffee | 29 +++++++++++++++---------- test/server/functional/auth.spec.coffee | 8 ++++--- test/server/functional/user.spec.coffee | 20 ++++++++--------- 10 files changed, 47 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 20c2e90da..ba88e3940 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "clean-css-brunch": "> 1.0 < 1.8", "auto-reload-brunch": "> 1.0 < 1.8", "brunch": "~1.7.4", - "jasmine-node": "1.12.x", + "jasmine-node": "1.13.x", "nodemon": "0.7.5", "marked": "0.2.x", "telepath-brunch": "https://github.com/nwinter/telepath-brunch/tarball/master", diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index 510da37e1..2f81d0acd 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -16,7 +16,7 @@ module.exports = class Handler # subclasses should override these methods hasAccess: (req) -> true hasAccessToDocument: (req, document, method=null) -> - return true if req.user.isAdmin() + return true if req.user?.isAdmin() if @modelClass.schema.uses_coco_permissions return document.hasPermissionsForMethod(req.user, method or req.method) return true @@ -32,7 +32,7 @@ module.exports = class Handler # can only edit permissions if this is a brand new property, # or you are an owner of the old one isOwner = document.getAccessForUserObjectId(req.user._id) is 'owner' - if isBrandNew or isOwner or req.user.isAdmin() + if isBrandNew or isOwner or req.user?.isAdmin() props.push 'permissions' if @modelClass.schema.uses_coco_versions @@ -57,7 +57,7 @@ module.exports = class Handler # generic handlers get: (req, res) -> # by default, ordinary users never get unfettered access to the database - return @sendUnauthorizedError(res) unless req.user.isAdmin() + return @sendUnauthorizedError(res) unless req.user?.isAdmin() # admins can send any sort of query down the wire, though conditions = JSON.parse(req.query.conditions || '[]') @@ -97,7 +97,7 @@ module.exports = class Handler term = req.query.term matchedObjects = [] filters = [{filter: {index: true}}] - if @modelClass.schema.uses_coco_permissions + if @modelClass.schema.uses_coco_permissions and req.user filters.push {filter: {index: req.user.get('id')}} for filter in filters callback = (err, results) => diff --git a/server/levels/level_handler.coffee b/server/levels/level_handler.coffee index c30633ab1..b26e729bd 100644 --- a/server/levels/level_handler.coffee +++ b/server/levels/level_handler.coffee @@ -39,6 +39,7 @@ LevelHandler = class LevelHandler extends Handler callback err, level getSession: (req, res, id) -> + return @sendNotFoundError(res) unless req.user @fetchLevelByIDAndHandleErrors id, req, res, (err, level) => sessionQuery = level: @@ -150,6 +151,7 @@ LevelHandler = class LevelHandler extends Handler req.query.limit = parseInt(req.query.limit) ? 20 getFeedback: (req, res, id) -> + return @sendNotFoundError(res) unless req.user @fetchLevelByIDAndHandleErrors id, req, res, (err, level) => feedbackQuery = creator: mongoose.Types.ObjectId(req.user.id.toString()) diff --git a/server/routes/contact.coffee b/server/routes/contact.coffee index 5b1664bc2..51aaa78fc 100644 --- a/server/routes/contact.coffee +++ b/server/routes/contact.coffee @@ -4,6 +4,7 @@ mail = require '../commons/mail' module.exports.setup = (app) -> app.post '/contact', (req, res) -> + return res.end() unless req.user log.info "Sending mail from #{req.body.email} saying #{req.body.message}" if config.isProduction options = createMailOptions req.body.email, req.body.message, req.user diff --git a/server/routes/db.coffee b/server/routes/db.coffee index 36fec7cbd..8bf2ef7eb 100644 --- a/server/routes/db.coffee +++ b/server/routes/db.coffee @@ -11,6 +11,7 @@ module.exports.setup = (app) -> parts = module.split('/') module = parts[0] return getSchema(req, res, module) if parts[1] is 'schema' + return errors.unauthorized(res, 'Must have an identity to do anything with the db.') unless req.user try moduleName = module.replace '.', '_' diff --git a/server/routes/file.coffee b/server/routes/file.coffee index a4a4e2dc3..ce9f4ca7c 100644 --- a/server/routes/file.coffee +++ b/server/routes/file.coffee @@ -69,7 +69,7 @@ postFileSchema = required: ['filename', 'mimetype', 'path'] filePost = (req, res) -> - return errors.forbidden(res) unless req.user.isAdmin() + return errors.forbidden(res) unless req.user?.isAdmin() options = req.body tv4 = require('tv4').tv4 valid = tv4.validate(options, postFileSchema) diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index c755a7c33..480c7def0 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -31,7 +31,7 @@ UserHandler = class UserHandler extends Handler return null unless document? obj = document.toObject() delete obj[prop] for prop in serverProperties - includePrivates = req.user and (req.user.isAdmin() or req.user._id.equals(document._id)) + includePrivates = req.user and (req.user?.isAdmin() or req.user?._id.equals(document._id)) delete obj[prop] for prop in privateProperties unless includePrivates # emailHash is used by gravatar @@ -105,7 +105,7 @@ UserHandler = class UserHandler extends Handler ] getById: (req, res, id) -> - if req.user and req.user._id.equals(id) + if req.user?._id.equals(id) return @sendSuccess(res, @formatEntity(req, req.user)) super(req, res, id) @@ -132,14 +132,15 @@ UserHandler = class UserHandler extends Handler post: (req, res) -> return @sendBadInputError(res, 'No input.') if _.isEmpty(req.body) + return @sendBadInputError(res, 'Must have an anonymous user to post with.') unless req.user return @sendBadInputError(res, 'Existing users cannot create new ones.') unless req.user.get('anonymous') req.body._id = req.user._id if req.user.get('anonymous') @put(req, res) hasAccessToDocument: (req, document) -> if req.route.method in ['put', 'post', 'patch'] - return true if req.user.isAdmin() - return req.user._id.equals(document._id) + return true if req.user?.isAdmin() + return req.user?._id.equals(document._id) return true getByRelationship: (req, res, args...) -> @@ -149,6 +150,7 @@ UserHandler = class UserHandler extends Handler return @sendNotFoundError(res) agreeToCLA: (req, res) -> + return @sendUnauthorizedError(res) unless req.user doc = user: req.user._id+'' email: req.user.get 'email' diff --git a/test/server/common.coffee b/test/server/common.coffee index 16f0982bc..d88fa21e8 100644 --- a/test/server/common.coffee +++ b/test/server/common.coffee @@ -1,6 +1,9 @@ # import this at the top of every file so we're not juggling connections # and common libraries are available +console.log 'IT BEGINS' + + GLOBAL._ = require('lodash') _.str = require('underscore.string') _.mixin(_.str.exports()) @@ -71,20 +74,22 @@ unittest.getUser = (email, password, done, force) -> return done(unittest.users[email]) if unittest.users[email] and not force request = require 'request' request.post getURL('/auth/logout'), -> - req = request.post(getURL('/db/user'), (err, response, body) -> - throw err if err - User.findOne({email:email}).exec((err, user) -> - if password is '80yqxpb38j' - user.set('permissions', [ 'admin' ]) - user.save (err) -> + request.get getURL('/auth/whoami'), -> + req = request.post(getURL('/db/user'), (err, response, body) -> + throw err if err + User.findOne({email:email}).exec((err, user) -> + if password is '80yqxpb38j' + user.set('permissions', [ 'admin' ]) + user.save (err) -> + wrapUpGetUser(email, user, done) + else wrapUpGetUser(email, user, done) - else - wrapUpGetUser(email, user, done) + ) ) - ) - form = req.form() - form.append('email', email) - form.append('password', password) + form = req.form() + form.append('email', email) + form.append('password', password) + wrapUpGetUser = (email, user, done) -> unittest.users[email] = user diff --git a/test/server/functional/auth.spec.coffee b/test/server/functional/auth.spec.coffee index 45f070972..18c3c7fc8 100644 --- a/test/server/functional/auth.spec.coffee +++ b/test/server/functional/auth.spec.coffee @@ -17,8 +17,9 @@ describe '/auth/login', -> it 'clears Users first', (done) -> User.remove {}, (err) -> - throw err if err - done() + request.get getURL('/auth/whoami'), -> + throw err if err + done() it 'finds no user', (done) -> req = request.post(urlLogin, (error, response) -> @@ -92,9 +93,10 @@ describe '/auth/reset', -> form = req.form() form.append('email', 'unknow') - it 'reset user password', (done) -> + it 'resets user password', (done) -> req = request.post(urlReset, (error, response) -> expect(response).toBeDefined() + console.log 'status code is', response.statusCode expect(response.statusCode).toBe(200) expect(response.body).toBeDefined() passwordReset = response.body diff --git a/test/server/functional/user.spec.coffee b/test/server/functional/user.spec.coffee index 4bb616ba2..29e1360a9 100644 --- a/test/server/functional/user.spec.coffee +++ b/test/server/functional/user.spec.coffee @@ -54,18 +54,16 @@ describe 'POST /db/user', -> describe 'PUT /db/user', -> - it 'denies requests without any data', (done) -> - req = request.post getURL('/auth/logout'), - (err, res) -> - expect(res.statusCode).toBe(200) - req = request.put getURL(urlUser), - (err, res) -> - expect(res.statusCode).toBe(422) - expect(res.body).toBe('No input.') - done() - it 'logs in as normal joe', (done) -> - loginJoe -> done() + request.post getURL('/auth/logout'), + loginJoe -> done() + + it 'denies requests without any data', (done) -> + request.put getURL(urlUser), + (err, res) -> + expect(res.statusCode).toBe(422) + expect(res.body).toBe('No input.') + done() it 'denies requests to edit someone who is not joe', (done) -> unittest.getAdmin (admin) -> From f538ff542fd4038155a4015db3d51d62022ab3f4 Mon Sep 17 00:00:00 2001 From: Michael Schmatz Date: Tue, 25 Feb 2014 09:12:37 -0800 Subject: [PATCH 04/32] Removed hiredis --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index ba88e3940..665ac0131 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "sendwithus": "2.0.x", "aws-sdk":"~2.0.0", "bayesian-battle":"0.0.x", - "hiredis":"", "redis": "" }, "devDependencies": { From 0380a3052226cc02454873402d0486218448adb4 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 25 Feb 2014 10:48:23 -0800 Subject: [PATCH 05/32] Fixes for not storing default code in other sessions. sass-brunch 1.8. Removed tutorial link for now. Round wizards. --- app/lib/LevelBus.coffee | 14 +++++--------- app/lib/surface/IndieSprite.coffee | 1 + app/templates/play/ladder.jade | 2 +- app/views/play/level_view.coffee | 2 +- package.json | 2 +- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/lib/LevelBus.coffee b/app/lib/LevelBus.coffee index 520631559..a9c669bf1 100644 --- a/app/lib/LevelBus.coffee +++ b/app/lib/LevelBus.coffee @@ -87,6 +87,9 @@ module.exports = class LevelBus extends Bus # LevelSession object. Either break this off into a separate class # or have the LevelSession object listen for all these events itself. + setSpells: (spells) -> + @onSpellCreated spell: spell for spellKey, spell of spells + onSpellChanged: (e) -> return unless @onPoint() code = @session.get('code') @@ -102,6 +105,7 @@ module.exports = class LevelBus extends Bus onSpellCreated: (e) -> return unless @onPoint() spellTeam = e.spell.team + @teamSpellMap ?= {} @teamSpellMap[spellTeam] ?= [] unless e.spell.spellKey in @teamSpellMap[spellTeam] @@ -109,8 +113,7 @@ module.exports = class LevelBus extends Bus @changedSessionProperties.teamSpells = true @session.set({'teamSpells': @teamSpellMap}) @saveSession() - - + @onSpellChanged e # Save the new spell to the session, too. onScriptStateChanged: (e) -> return unless @onPoint() @@ -236,10 +239,3 @@ module.exports = class LevelBus extends Bus destroy: -> @session.off 'change:multiplayer', @onMultiplayerChanged, @ super() - - setTeamSpellMap: (spellMap) -> - @teamSpellMap = spellMap - console.log @teamSpellMap - @changedSessionProperties.teamSpells = true - @session.set({'teamSpells': @teamSpellMap}) - @saveSession() diff --git a/app/lib/surface/IndieSprite.coffee b/app/lib/surface/IndieSprite.coffee index 8e3f65dc3..ab7f2efda 100644 --- a/app/lib/surface/IndieSprite.coffee +++ b/app/lib/surface/IndieSprite.coffee @@ -22,6 +22,7 @@ module.exports = IndieSprite = class IndieSprite extends CocoSprite thang.width = thang.height = thang.depth = 4 thang.pos = pos ? @defaultPos() thang.pos.z = thang.depth / 2 + thang.shape = 'ellipsoid' thang.rotation = 0 thang.action = 'idle' thang.setAction = (action) -> thang.action = action diff --git a/app/templates/play/ladder.jade b/app/templates/play/ladder.jade index 14a46c52a..66e05ff1b 100644 --- a/app/templates/play/ladder.jade +++ b/app/templates/play/ladder.jade @@ -7,7 +7,7 @@ block content !{description} if !me.get('anonymous') - a(href="http://www.youtube.com/watch?v=IFvfZiJGDsw&list=HL1392928835&feature=mh_lolz").intro-button.btn.btn-primary.btn-lg Watch the Video + //a(href="http://www.youtube.com/watch?v=IFvfZiJGDsw&list=HL1392928835&feature=mh_lolz").intro-button.btn.btn-primary.btn-lg Watch the Video a(href="/play/level/ladder-tutorial").intro-button.btn.btn-primary.btn-lg Play the Tutorial diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee index 453e4f7c7..008c119a4 100644 --- a/app/views/play/level_view.coffee +++ b/app/views/play/level_view.coffee @@ -393,7 +393,7 @@ module.exports = class PlayLevelView extends View register: -> @bus = LevelBus.get(@levelID, @session.id) @bus.setSession(@session) - @bus.setTeamSpellMap @tome.teamSpellMap + @bus.setSpells @tome.spells @bus.connect() if @session.get('multiplayer') onSessionWillSave: (e) -> diff --git a/package.json b/package.json index 20c2e90da..8a7dd9ec6 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "javascript-brunch": "> 1.0 < 1.8", "coffee-script-brunch": "https://github.com/brunch/coffee-script-brunch/tarball/master", "coffeelint-brunch": "> 1.0 < 1.8", - "sass-brunch": "1.7.0", + "sass-brunch": "~1.8.0", "css-brunch": "> 1.0 < 1.8", "jade-brunch": "> 1.0 < 1.8", "uglify-js-brunch": "~1.7.4", From a1a5d5eea0f5dab70beec38d6f8e3ba22fcea878 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Tue, 25 Feb 2014 10:50:12 -0800 Subject: [PATCH 06/32] Fixed some script handling by not having playback changed when the first world is built. --- app/lib/surface/Surface.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee index f42720101..6a7a96ddf 100644 --- a/app/lib/surface/Surface.coffee +++ b/app/lib/surface/Surface.coffee @@ -311,7 +311,10 @@ module.exports = Surface = class Surface extends CocoClass onNewWorld: (event) -> return unless event.world.name is @world.name @casting = false - Backbone.Mediator.publish 'level-set-playing', { playing: @wasPlayingWhenCastingBegan } + + # This has a tendency to break scripts that are waiting for playback to change when the level is loaded + # so only run it after the first world is created. + Backbone.Mediator.publish 'level-set-playing', { playing: @wasPlayingWhenCastingBegan } unless event.firstWorld fastForwardTo = null if @playing From 45e6fadfe27497f0476ec4fcde31a0b2330894b8 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Tue, 25 Feb 2014 10:50:40 -0800 Subject: [PATCH 07/32] Added a property to prevent scripts from running after certain other scripts have run. --- app/lib/scripts/ScriptManager.coffee | 9 +++++++++ server/levels/level_schema.coffee | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/lib/scripts/ScriptManager.coffee b/app/lib/scripts/ScriptManager.coffee index a1011b534..fea1de010 100644 --- a/app/lib/scripts/ScriptManager.coffee +++ b/app/lib/scripts/ScriptManager.coffee @@ -132,6 +132,15 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass continue unless script.channel is channel continue if alreadyTriggered and not script.repeats continue if script.lastTriggered? and new Date().getTime() - script.lastTriggered < 1 + continue if script.neverRun + + if script.notAfter + for scriptID in script.notAfter + if scriptID in @triggered + script.neverRun = true + break + continue if script.neverRun + continue unless @scriptPrereqsSatisfied(script) continue unless scriptMatchesEventPrereqs(script, event) # everything passed! diff --git a/server/levels/level_schema.coffee b/server/levels/level_schema.coffee index 32a5f60b9..9b82c2446 100644 --- a/server/levels/level_schema.coffee +++ b/server/levels/level_schema.coffee @@ -147,7 +147,9 @@ ScriptSchema = c.object { eventPrereqs: c.array {title: "Event Checks", description: "Logical checks on the event for this script to trigger.", format:'event-prereqs'}, EventPrereqSchema repeats: {title: "Repeats", description: "Whether this script can trigger more than once during a level.", type: 'boolean', "default": false} scriptPrereqs: c.array {title: "Happens After", description: "Scripts that need to fire first."}, - c.shortString(title: "ID", description: "A unique ID of a script that must have triggered before the parent script can trigger.") + c.shortString(title: "ID", description: "A unique ID of a script.") + notAfter: c.array {title: "Not After", description: "Do not run this script if any of these scripts have run."}, + c.shortString(title: "ID", description: "A unique ID of a script.") noteChain: c.array {title: "Actions", description: "A list of things that happen when this script triggers."}, NoteGroupSchema LevelThangSchema = c.object { From 356d1b55ed65f449fe110bd927498ce1dd3f76c4 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Tue, 25 Feb 2014 11:59:23 -0800 Subject: [PATCH 08/32] Added a property to prevent scripts from running after certain other scripts have run. --- app/lib/surface/SpriteBoss.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index 9adec0f61..5e9df2af3 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -184,6 +184,11 @@ module.exports = class SpriteBoss extends CocoClass sprite.hasMoved = false @removeSprite sprite if missing @cache true if updateCache and @cached + + # mainly for handling selecting thangs from session when the thang is not always in existence + if @willSelectThang and @sprites[@willSelectThang[0]] + @selectThang @willSelectThang... + @willSelectThang = null cache: (update=false) -> return if @cached and not update @@ -241,6 +246,7 @@ module.exports = class SpriteBoss extends CocoClass @selectSprite e if e.onBackground selectThang: (thangID, spellName=null) -> + return @willSelectThang = [thangID, spellName] unless @sprites[thangID] @selectSprite null, @sprites[thangID], spellName selectSprite: (e, sprite=null, spellName=null) -> From 8930d79e615e3a3bf34dea3d6b3cb029ba24f93a Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 25 Feb 2014 12:31:49 -0800 Subject: [PATCH 09/32] Back to 1.7.0 for sass-brunch. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0bd82ddf7..665ac0131 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "javascript-brunch": "> 1.0 < 1.8", "coffee-script-brunch": "https://github.com/brunch/coffee-script-brunch/tarball/master", "coffeelint-brunch": "> 1.0 < 1.8", - "sass-brunch": "~1.8.0", + "sass-brunch": "1.7.0", "css-brunch": "> 1.0 < 1.8", "jade-brunch": "> 1.0 < 1.8", "uglify-js-brunch": "~1.7.4", From eee434ab511053c1b6a99d5f13838192e768955a Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Tue, 25 Feb 2014 12:38:47 -0800 Subject: [PATCH 10/32] Tweaked the coordinate display position to be a bit more above the mouse. --- app/lib/surface/CoordinateDisplay.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee index fc188a970..7fe570b4e 100644 --- a/app/lib/surface/CoordinateDisplay.coffee +++ b/app/lib/surface/CoordinateDisplay.coffee @@ -55,7 +55,7 @@ module.exports = class CoordinateDisplay extends createjs.Container @label.regY = height / 2 sup = @camera.worldToSurface @lastPos @x = sup.x - @y = sup.y + @y = sup.y - 7 @addChild @label @cache -width / 2, -height / 2, width, height Backbone.Mediator.publish 'surface:coordinates-shown', {} From 1b4699556a9ca5503f95110cd75db05c21461311 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Tue, 25 Feb 2014 12:39:22 -0800 Subject: [PATCH 11/32] Fixed a bug where sometimes new worlds would hide the hud speaker unnecessarily. --- app/views/play/level/hud_view.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee index 1e273b7ef..2b1c84531 100644 --- a/app/views/play/level/hud_view.coffee +++ b/app/views/play/level/hud_view.coffee @@ -66,8 +66,9 @@ module.exports = class HUDView extends View @clearSpeaker() onNewWorld: (e) -> + hadThang = @thang @thang = e.world.thangMap[@thang.id] if @thang - if not @thang + if hadThang and not @thang @setThang null, null setThang: (thang, thangType) -> From 8a24407d3e1fdf2c2fa81e95408ad9690e19f3d3 Mon Sep 17 00:00:00 2001 From: Tay Yang Shun Date: Wed, 26 Feb 2014 04:59:35 +0800 Subject: [PATCH 12/32] Redirect to play page for non-existent levels. Fixes issue #396 --- app/lib/God.coffee | 2 +- app/lib/LevelLoader.coffee | 6 +++--- app/styles/play.sass | 3 +++ app/templates/play.jade | 4 ++++ app/views/play/level_view.coffee | 9 +++++---- app/views/play_view.coffee | 2 +- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app/lib/God.coffee b/app/lib/God.coffee index f9981bd18..5ad7f1c59 100644 --- a/app/lib/God.coffee +++ b/app/lib/God.coffee @@ -132,7 +132,7 @@ module.exports = class God angel.destroy() for angel in @angels @dead = true Backbone.Mediator.unsubscribe('tome:cast-spells', @onTomeCast, @) - @goalManager.destroy() + @goalManager?.destroy() @goalManager = null @fillWorkerPool = null @simulateWorld = null diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index 873da7d48..aeafb0789 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -93,9 +93,9 @@ module.exports = class LevelLoader extends CocoClass @supermodel.populateModel @level onSupermodelError: -> - msg = $.i18n.t('play_level.level_load_error', - defaultValue: "Level could not be loaded.") - $('body').append('
' + msg + '
') + # msg = $.i18n.t('play_level.level_load_error', + # defaultValue: "Level could not be loaded.") + # $('body').append('
' + msg + '
') onSupermodelLoadedOne: (e) -> @update() diff --git a/app/styles/play.sass b/app/styles/play.sass index 7f0818516..83611f8b8 100644 --- a/app/styles/play.sass +++ b/app/styles/play.sass @@ -38,3 +38,6 @@ color: black text-shadow: 0 1px 0 white + .alert-warning h2 + color: black + text-align: center \ No newline at end of file diff --git a/app/templates/play.jade b/app/templates/play.jade index 469192da4..89dd37049 100644 --- a/app/templates/play.jade +++ b/app/templates/play.jade @@ -2,6 +2,10 @@ extends /templates/base block content + if notFound + div(class="alert alert-warning") + h2 Oops, the level "#{notFound}" was not found! + 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/views/play/level_view.coffee b/app/views/play/level_view.coffee index 453e4f7c7..bbce6c637 100644 --- a/app/views/play/level_view.coffee +++ b/app/views/play/level_view.coffee @@ -97,8 +97,9 @@ module.exports = class PlayLevelView extends View localStorage["lastLevel"] = @levelID onLevelLoadError: (e) => - msg = $.i18n.t('play_level.level_load_error', defaultValue: "Level could not be loaded.") - @$el.html('
' + msg + '
') + application.router.navigate "/play?not_found=#{@levelID}", {trigger: true} + # msg = $.i18n.t('play_level.level_load_error', defaultValue: "Level could not be loaded.") + # @$el.html('

Whoops we were not able to find ' + @levelID + '!

' + msg + '

Please select a valid level from the levels page.

') setLevel: (@level, @supermodel) -> @god?.level = @level.serialize @supermodel @@ -423,7 +424,7 @@ module.exports = class PlayLevelView extends View AudioPlayer.preloadSoundReference sound destroy: -> - @supermodel.off 'error', @onLevelLoadError + @supermodel?.off 'error', @onLevelLoadError @levelLoader?.off 'loaded-all', @onLevelLoaderLoaded @levelLoader?.destroy() @surface?.destroy() @@ -436,7 +437,7 @@ module.exports = class PlayLevelView extends View @bus?.destroy() #@instance.save() unless @instance.loading console.profileEnd?() if PROFILE_ME - @session.off 'change:multiplayer', @onMultiplayerChanged, @ + @session?.off 'change:multiplayer', @onMultiplayerChanged, @ @onLevelLoadError = null @onLevelLoaderLoaded = null @onSupermodelLoadedOne = null diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee index 554f4a171..32e6d3bf1 100644 --- a/app/views/play_view.coffee +++ b/app/views/play_view.coffee @@ -8,7 +8,7 @@ module.exports = class PlayView extends View getRenderData: (context={}) -> context = super(context) context.home = true - + context.notFound = @getQueryVariable 'not_found' tutorials = [ { name: 'Rescue Mission' From a53498224c18f524e89383900b93f8cbd2814e86 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Tue, 25 Feb 2014 13:27:02 -0800 Subject: [PATCH 13/32] Tweaked sprite scripts to use given response buttons even if the script is not skippable. --- app/lib/scripts/SpriteScriptModule.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/scripts/SpriteScriptModule.coffee b/app/lib/scripts/SpriteScriptModule.coffee index 8bd2af6dd..bc4514061 100644 --- a/app/lib/scripts/SpriteScriptModule.coffee +++ b/app/lib/scripts/SpriteScriptModule.coffee @@ -33,7 +33,7 @@ module.exports = class SpritesScriptModule extends ScriptModule spriteSayNote: (sprite, script) -> return if @speakingSprites[sprite.id] responses = sprite.say.responses - responses = [] unless script.skippable + responses = [] unless script.skippable or responses for response in responses ? [] response.text = response.i18n?[me.lang()]?.text ? response.text text = sprite.say.i18n?[me.lang()]?.text or sprite.say.text From e3a81137e0fab860f02e5d273651231bd1172cd4 Mon Sep 17 00:00:00 2001 From: Tay Yang Shun Date: Wed, 26 Feb 2014 05:52:49 +0800 Subject: [PATCH 14/32] Modified locale messages for "level_load_error" --- app/locale/ar.coffee | 2 +- app/locale/bg.coffee | 2 +- app/locale/cs.coffee | 2 +- app/locale/da.coffee | 2 +- app/locale/de.coffee | 2 +- app/locale/el.coffee | 2 +- app/locale/en-AU.coffee | 2 +- app/locale/en-GB.coffee | 2 +- app/locale/en-US.coffee | 2 +- app/locale/en.coffee | 2 +- app/locale/es-419.coffee | 2 +- app/locale/es-ES.coffee | 2 +- app/locale/es.coffee | 2 +- app/locale/fa.coffee | 2 +- app/locale/fi.coffee | 2 +- app/locale/fr.coffee | 2 +- app/locale/he.coffee | 2 +- app/locale/hi.coffee | 2 +- app/locale/hu.coffee | 2 +- app/locale/id.coffee | 2 +- app/locale/it.coffee | 2 +- app/locale/ja.coffee | 2 +- app/locale/ko.coffee | 2 +- app/locale/lt.coffee | 2 +- app/locale/ms-BA.coffee | 2 +- app/locale/nb.coffee | 2 +- app/locale/nl.coffee | 2 +- app/locale/nn.coffee | 2 +- app/locale/no.coffee | 2 +- app/locale/pl.coffee | 2 +- app/locale/pt-BR.coffee | 2 +- app/locale/pt-PT.coffee | 2 +- app/locale/pt.coffee | 2 +- app/locale/ro.coffee | 2 +- app/locale/ru.coffee | 2 +- app/locale/sk.coffee | 2 +- app/locale/sl.coffee | 2 +- app/locale/sr.coffee | 2 +- app/locale/sv.coffee | 2 +- app/locale/th.coffee | 2 +- app/locale/tr.coffee | 2 +- app/locale/uk.coffee | 2 +- app/locale/ur.coffee | 2 +- app/locale/vi.coffee | 2 +- app/locale/zh-HANS.coffee | 2 +- app/locale/zh-HANT.coffee | 2 +- app/locale/zh.coffee | 2 +- 47 files changed, 47 insertions(+), 47 deletions(-) diff --git a/app/locale/ar.coffee b/app/locale/ar.coffee index 2228af051..b1d899a65 100644 --- a/app/locale/ar.coffee +++ b/app/locale/ar.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/bg.coffee b/app/locale/bg.coffee index 3515c5fa2..72ca47fca 100644 --- a/app/locale/bg.coffee +++ b/app/locale/bg.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "български език", englishDescri # gravatar_profile_link: "Full Gravatar Profile" play_level: - level_load_error: "Нивото не може да бъде заредено." + level_load_error: "Нивото не може да бъде заредено: " done: "Готово" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/cs.coffee b/app/locale/cs.coffee index a3e45a0d5..aa32f0aa2 100644 --- a/app/locale/cs.coffee +++ b/app/locale/cs.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr gravatar_profile_link: "Účet Gravatar" play_level: - level_load_error: "Úroveň se nepodařilo otevřít." + level_load_error: "Úroveň se nepodařilo otevřít: " done: "Hotovo" grid: "Mřížka" customize_wizard: "Upravit Kouzelníka" diff --git a/app/locale/da.coffee b/app/locale/da.coffee index a657a5d2f..727e8d713 100644 --- a/app/locale/da.coffee +++ b/app/locale/da.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans gravatar_profile_link: "Fuld Gravatar Profil" play_level: - level_load_error: "Banen kunne ikke indlæses." + level_load_error: "Banen kunne ikke indlæses: " done: "Færdig" grid: "Gitter" customize_wizard: "Tilpas troldmand" diff --git a/app/locale/de.coffee b/app/locale/de.coffee index 5f01fbc1a..aebfcccbb 100644 --- a/app/locale/de.coffee +++ b/app/locale/de.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra gravatar_profile_link: "Gravatar Profil" play_level: - level_load_error: "Level konnte nicht geladen werden." + level_load_error: "Level konnte nicht geladen werden: " done: "Fertig" grid: "Raster" customize_wizard: "Bearbeite den Zauberer" diff --git a/app/locale/el.coffee b/app/locale/el.coffee index fc0c8bd50..5425164b7 100644 --- a/app/locale/el.coffee +++ b/app/locale/el.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre gravatar_profile_link: "Πλήρη προφίλ \"Gravatar\"" play_level: - level_load_error: "Το επίπεδο δεν μπόρεσε να φορτωθεί" + level_load_error: "Το επίπεδο δεν μπόρεσε να φορτωθεί: " done: "Έτοιμο" grid: "Πλέγμα" customize_wizard: "Προσαρμόστε τον Μάγο" diff --git a/app/locale/en-AU.coffee b/app/locale/en-AU.coffee index 0841de5b1..9c115d83d 100644 --- a/app/locale/en-AU.coffee +++ b/app/locale/en-AU.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/en-GB.coffee b/app/locale/en-GB.coffee index e317ffce4..12bac5e6f 100644 --- a/app/locale/en-GB.coffee +++ b/app/locale/en-GB.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/en-US.coffee b/app/locale/en-US.coffee index 64de2e706..e34074395 100644 --- a/app/locale/en-US.coffee +++ b/app/locale/en-US.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 9e8ee2787..63b228460 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr gravatar_profile_link: "Full Gravatar Profile" play_level: - level_load_error: "Level could not be loaded." + level_load_error: "Level could not be loaded: " done: "Done" grid: "Grid" customize_wizard: "Customize Wizard" diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index 226763a97..476b9fa7d 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip gravatar_profile_link: "Perfil Gravatar Completo" play_level: - level_load_error: "El nivel no puede ser cargado." + level_load_error: "El nivel no puede ser cargado: " done: "Listo" grid: "Cuadricula" customize_wizard: "Personalizar Hechicero" diff --git a/app/locale/es-ES.coffee b/app/locale/es-ES.coffee index 216f34235..5b911e4b1 100644 --- a/app/locale/es-ES.coffee +++ b/app/locale/es-ES.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis gravatar_profile_link: "Perfil de Gravatar completo" play_level: - level_load_error: "No se pudo cargar el nivel." + level_load_error: "No se pudo cargar el nivel: " done: "Hecho" grid: "Cuadrícrula" customize_wizard: "Personalizar Mago" diff --git a/app/locale/es.coffee b/app/locale/es.coffee index 53e69ed7b..fabd7b970 100644 --- a/app/locale/es.coffee +++ b/app/locale/es.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t gravatar_profile_link: "Prefil de Gravatar completo" play_level: - level_load_error: "No se pudo cargar el nivel." + level_load_error: "No se pudo cargar el nivel: " done: "Hecho" grid: "Cuadrícrula" customize_wizard: "Personalizar Mago" diff --git a/app/locale/fa.coffee b/app/locale/fa.coffee index 6eb55a890..36d6b4991 100644 --- a/app/locale/fa.coffee +++ b/app/locale/fa.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian", # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/fi.coffee b/app/locale/fi.coffee index 43f258a27..35af0bb25 100644 --- a/app/locale/fi.coffee +++ b/app/locale/fi.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/fr.coffee b/app/locale/fr.coffee index 0d448b867..c869fbe8b 100644 --- a/app/locale/fr.coffee +++ b/app/locale/fr.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t gravatar_profile_link: "Profil Gravatar complet" play_level: - level_load_error: "Le niveau ne peut pas être chargé." + level_load_error: "Le niveau ne peut pas être chargé: " done: "Fait" grid: "Grille" customize_wizard: "Personnaliser le magicien" diff --git a/app/locale/he.coffee b/app/locale/he.coffee index febb2cf84..5d39d1b87 100644 --- a/app/locale/he.coffee +++ b/app/locale/he.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew", # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/hi.coffee b/app/locale/hi.coffee index 5ebaa9a68..abaae44c6 100644 --- a/app/locale/hi.coffee +++ b/app/locale/hi.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee index 5a8a9cce8..39fb5c38d 100644 --- a/app/locale/hu.coffee +++ b/app/locale/hu.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t # gravatar_profile_link: "Full Gravatar Profile" play_level: - level_load_error: "A pályát nem sikerült betölteni." + level_load_error: "A pályát nem sikerült betölteni: " done: "Kész" grid: "Rács" customize_wizard: "Varázsló testreszabása" diff --git a/app/locale/id.coffee b/app/locale/id.coffee index 08b74838f..4c21ab17c 100644 --- a/app/locale/id.coffee +++ b/app/locale/id.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/it.coffee b/app/locale/it.coffee index 69e8b9260..e1ecb580f 100644 --- a/app/locale/it.coffee +++ b/app/locale/it.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "italiano", englishDescription: "Italian", t gravatar_profile_link: "Profilo Gravatar completo" play_level: - level_load_error: "Il livello non può essere caricato." + level_load_error: "Il livello non può essere caricato: " done: "Fatto" grid: "Griglia" customize_wizard: "Personalizza stregone" diff --git a/app/locale/ja.coffee b/app/locale/ja.coffee index 85bb6dcba..47b10f118 100644 --- a/app/locale/ja.coffee +++ b/app/locale/ja.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese", # gravatar_profile_link: "Full Gravatar Profile" play_level: - level_load_error: "レベルがロード出来ませんでした。" + level_load_error: "レベルがロード出来ませんでした: " done: "完了" grid: "グリッド" customize_wizard: "魔法使いの設定" diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee index b9e202082..9b0f4c9c4 100644 --- a/app/locale/ko.coffee +++ b/app/locale/ko.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/lt.coffee b/app/locale/lt.coffee index ceb1f746d..4a0c28fbc 100644 --- a/app/locale/lt.coffee +++ b/app/locale/lt.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/ms-BA.coffee b/app/locale/ms-BA.coffee index 2de5fcbb2..c02026e4c 100644 --- a/app/locale/ms-BA.coffee +++ b/app/locale/ms-BA.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/nb.coffee b/app/locale/nb.coffee index 1fc73e8f0..92ac6f932 100644 --- a/app/locale/nb.coffee +++ b/app/locale/nb.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg gravatar_profile_link: "Full Gravatar Profil" play_level: - level_load_error: "Nivået kunne ikke bli lastet." + level_load_error: "Nivået kunne ikke bli lastet: " done: "Ferdig" grid: "Grid" customize_wizard: "Spesiallag Trollmann" diff --git a/app/locale/nl.coffee b/app/locale/nl.coffee index 7f606f12e..bf9d9d650 100644 --- a/app/locale/nl.coffee +++ b/app/locale/nl.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t gravatar_profile_link: "Volledig Gravatar Profiel" play_level: - level_load_error: "Level kon niet geladen worden." + level_load_error: "Level kon niet geladen worden: " done: "Klaar" grid: "Raster" customize_wizard: "Pas Tovenaar aan" diff --git a/app/locale/nn.coffee b/app/locale/nn.coffee index fc89e693f..1ef0bce27 100644 --- a/app/locale/nn.coffee +++ b/app/locale/nn.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/no.coffee b/app/locale/no.coffee index 91ebf0f1f..4dcd77714 100644 --- a/app/locale/no.coffee +++ b/app/locale/no.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr gravatar_profile_link: "Full Gravatar Profil" play_level: - level_load_error: "Nivået kunne ikke bli lastet." + level_load_error: "Nivået kunne ikke bli lastet: " done: "Ferdig" grid: "Grid" customize_wizard: "Spesiallag Trollmann" diff --git a/app/locale/pl.coffee b/app/locale/pl.coffee index 9caa0bf88..826e5669c 100644 --- a/app/locale/pl.coffee +++ b/app/locale/pl.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish gravatar_profile_link: "Profil Gravatar" play_level: - level_load_error: "Nie udało się wczytać poziomu." + level_load_error: "Nie udało się wczytać poziomu: " done: "Zrobione" grid: "Siatka" customize_wizard: "Spersonalizuj Czarodzieja" diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee index 994024d03..e6a285655 100644 --- a/app/locale/pt-BR.coffee +++ b/app/locale/pt-BR.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: gravatar_profile_link: "Perfil Completo do Gravatar" play_level: - level_load_error: "O estágio não pôde ser carregado." + level_load_error: "O estágio não pôde ser carregado: " done: "Pronto" grid: "Grade" customize_wizard: "Personalize o feiticeiro" diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index d39bbd27c..1ce48a42f 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Português europeu", englishDescription: "P gravatar_profile_link: "Perfil Gravatar completo" play_level: - level_load_error: "O nível não pôde ser carregado." + level_load_error: "O nível não pôde ser carregado: " done: "Concluir" grid: "Grelha" customize_wizard: "Personalizar Feiticeiro" diff --git a/app/locale/pt.coffee b/app/locale/pt.coffee index 104c1978d..9aedeae92 100644 --- a/app/locale/pt.coffee +++ b/app/locale/pt.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "português", englishDescription: "Portugues gravatar_profile_link: "Perfil Completo do Gravatar" play_level: - level_load_error: "O estágio não pôde ser carregado." + level_load_error: "O estágio não pôde ser carregado: " done: "Pronto" grid: "Grade" customize_wizard: "Personalize o feiticeiro" diff --git a/app/locale/ro.coffee b/app/locale/ro.coffee index 59e81f1b1..454278097 100644 --- a/app/locale/ro.coffee +++ b/app/locale/ro.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee index d178ebf3f..d6d593c3e 100644 --- a/app/locale/ru.coffee +++ b/app/locale/ru.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi gravatar_profile_link: "Полный профиль на Gravatar" play_level: - level_load_error: "Уровень не может быть загружен." + level_load_error: "Уровень не может быть загружен: " done: "Готово" grid: "Сетка" customize_wizard: "Настройки волшебника" diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee index 91e73e060..9050f2181 100644 --- a/app/locale/sk.coffee +++ b/app/locale/sk.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak", # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/sl.coffee b/app/locale/sl.coffee index 5f290bc77..97559521a 100644 --- a/app/locale/sl.coffee +++ b/app/locale/sl.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/sr.coffee b/app/locale/sr.coffee index 87f1bb675..179b74906 100644 --- a/app/locale/sr.coffee +++ b/app/locale/sr.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian gravatar_profile_link: "Цео Граватар налог" play_level: - level_load_error: "Ниво није могао бити учитан." + level_load_error: "Ниво није могао бити учитан: " done: "Урађено" grid: "Мрежа" customize_wizard: "Прилагоди Чаробњака" diff --git a/app/locale/sv.coffee b/app/locale/sv.coffee index 2c0a67971..b3868e937 100644 --- a/app/locale/sv.coffee +++ b/app/locale/sv.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr gravatar_profile_link: "Hela Gravatar profilen" play_level: - level_load_error: "Nivån kunde inte laddas." + level_load_error: "Nivån kunde inte laddas: " done: "Klar" grid: "Rutnät" customize_wizard: "Finjustera Trollkarl" diff --git a/app/locale/th.coffee b/app/locale/th.coffee index 7adf56e41..03960ffd0 100644 --- a/app/locale/th.coffee +++ b/app/locale/th.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra # gravatar_profile_link: "Full Gravatar Profile" play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " done: "เสร็จสิ้น" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/tr.coffee b/app/locale/tr.coffee index dcf52c761..297c9f50d 100644 --- a/app/locale/tr.coffee +++ b/app/locale/tr.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t gravatar_profile_link: "Tam Gravatar Profili" play_level: - level_load_error: "Seviye yüklenemedi" + level_load_error: "Seviye yüklenemedi: " done: "Tamamdır" grid: "Harita Bölmeleri" customize_wizard: "Sihirbazı Düzenle" diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee index ad8e4c2db..3f3a375c7 100644 --- a/app/locale/uk.coffee +++ b/app/locale/uk.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "українська мова", englishDesc gravatar_profile_link: "Повний профіль Gravatar" play_level: - level_load_error: "Неможливо завантажити рівень." + level_load_error: "Неможливо завантажити рівень: " done: "Готово" grid: "Решітка" customize_wizard: "Налаштування персонажа" diff --git a/app/locale/ur.coffee b/app/locale/ur.coffee index d0376431e..d36ce12ec 100644 --- a/app/locale/ur.coffee +++ b/app/locale/ur.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu", # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/vi.coffee b/app/locale/vi.coffee index 4410752ed..99992f8c5 100644 --- a/app/locale/vi.coffee +++ b/app/locale/vi.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee index c7060bab1..8cb34d1f3 100644 --- a/app/locale/zh-HANS.coffee +++ b/app/locale/zh-HANS.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese gravatar_profile_link: "完善 Gravatar 资料" play_level: - level_load_error: "关卡不能载入。" + level_load_error: "关卡不能载入: " done: "完成" grid: "格子" customize_wizard: "自定义向导" diff --git a/app/locale/zh-HANT.coffee b/app/locale/zh-HANT.coffee index 410460a1f..aad8bbbf9 100644 --- a/app/locale/zh-HANT.coffee +++ b/app/locale/zh-HANT.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese gravatar_profile_link: "完善 Gravatar 資料" play_level: - level_load_error: "載入關卡時發生錯誤。" + level_load_error: "載入關卡時發生錯誤: " done: "完成" grid: "格子" customize_wizard: "自定義巫師" diff --git a/app/locale/zh.coffee b/app/locale/zh.coffee index 26d5794aa..f0afbd64b 100644 --- a/app/locale/zh.coffee +++ b/app/locale/zh.coffee @@ -158,7 +158,7 @@ module.exports = nativeDescription: "中文", englishDescription: "Chinese", tra # gravatar_profile_link: "Full Gravatar Profile" # play_level: -# level_load_error: "Level could not be loaded." +# level_load_error: "Level could not be loaded: " # done: "Done" # grid: "Grid" # customize_wizard: "Customize Wizard" From 11c5f7419a5c66308e0bc2be609f8698b4551fc1 Mon Sep 17 00:00:00 2001 From: Tay Yang Shun Date: Wed, 26 Feb 2014 05:54:33 +0800 Subject: [PATCH 15/32] Used internationalised strings for level not found message --- app/lib/LevelLoader.coffee | 3 --- app/templates/play.jade | 2 +- app/views/play/level_view.coffee | 2 -- app/views/play_view.coffee | 1 + 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index aeafb0789..8afc6577a 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -93,9 +93,6 @@ module.exports = class LevelLoader extends CocoClass @supermodel.populateModel @level onSupermodelError: -> - # msg = $.i18n.t('play_level.level_load_error', - # defaultValue: "Level could not be loaded.") - # $('body').append('
' + msg + '
') onSupermodelLoadedOne: (e) -> @update() diff --git a/app/templates/play.jade b/app/templates/play.jade index 89dd37049..c8e4570d6 100644 --- a/app/templates/play.jade +++ b/app/templates/play.jade @@ -4,7 +4,7 @@ block content if notFound div(class="alert alert-warning") - h2 Oops, the level "#{notFound}" was not found! + h2 #{notFoundMessage} h1(data-i18n="play.choose_your_level") Choose Your Level p diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee index bbce6c637..874bdb93d 100644 --- a/app/views/play/level_view.coffee +++ b/app/views/play/level_view.coffee @@ -98,8 +98,6 @@ module.exports = class PlayLevelView extends View onLevelLoadError: (e) => application.router.navigate "/play?not_found=#{@levelID}", {trigger: true} - # msg = $.i18n.t('play_level.level_load_error', defaultValue: "Level could not be loaded.") - # @$el.html('

Whoops we were not able to find ' + @levelID + '!

' + msg + '

Please select a valid level from the levels page.

') setLevel: (@level, @supermodel) -> @god?.level = @level.serialize @supermodel diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee index 32e6d3bf1..1bb13bbe9 100644 --- a/app/views/play_view.coffee +++ b/app/views/play_view.coffee @@ -9,6 +9,7 @@ module.exports = class PlayView extends View context = super(context) context.home = true context.notFound = @getQueryVariable 'not_found' + context.notFoundMessage = $.i18n.t('play_level.level_load_error') + context.notFound tutorials = [ { name: 'Rescue Mission' From 373a618cff861e017cc02fa01b7f86dea11051f8 Mon Sep 17 00:00:00 2001 From: Tay Yang Shun Date: Wed, 26 Feb 2014 06:14:29 +0800 Subject: [PATCH 16/32] Moved internationalisation of level load error message into template file --- app/templates/play.jade | 4 +++- app/views/play_view.coffee | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/templates/play.jade b/app/templates/play.jade index c8e4570d6..454ea8ca0 100644 --- a/app/templates/play.jade +++ b/app/templates/play.jade @@ -4,7 +4,9 @@ block content if notFound div(class="alert alert-warning") - h2 #{notFoundMessage} + 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 diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee index 1bb13bbe9..32e6d3bf1 100644 --- a/app/views/play_view.coffee +++ b/app/views/play_view.coffee @@ -9,7 +9,6 @@ module.exports = class PlayView extends View context = super(context) context.home = true context.notFound = @getQueryVariable 'not_found' - context.notFoundMessage = $.i18n.t('play_level.level_load_error') + context.notFound tutorials = [ { name: 'Rescue Mission' From 3c5902a1d270d85bb2e14c5854fd30523d02ab91 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 25 Feb 2014 14:46:48 -0800 Subject: [PATCH 17/32] Trying to get session code merging to work again. --- app/lib/LevelBus.coffee | 4 +++- app/lib/simulator/Simulator.coffee | 2 +- app/views/play/level/hud_view.coffee | 1 + app/views/play/level_view.coffee | 12 +++++++++--- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/lib/LevelBus.coffee b/app/lib/LevelBus.coffee index a9c669bf1..287110f98 100644 --- a/app/lib/LevelBus.coffee +++ b/app/lib/LevelBus.coffee @@ -113,7 +113,9 @@ module.exports = class LevelBus extends Bus @changedSessionProperties.teamSpells = true @session.set({'teamSpells': @teamSpellMap}) @saveSession() - @onSpellChanged e # Save the new spell to the session, too. + console.log spellTeam, me.team, e.spell.spellKey + if spellTeam is me.team + @onSpellChanged e # Save the new spell to the session, too. onScriptStateChanged: (e) -> return unless @onPoint() diff --git a/app/lib/simulator/Simulator.coffee b/app/lib/simulator/Simulator.coffee index 12b679c86..5a08eadfe 100644 --- a/app/lib/simulator/Simulator.coffee +++ b/app/lib/simulator/Simulator.coffee @@ -220,7 +220,7 @@ module.exports = class Simulator #functionParameters: # TODOOOOO if methodName is 'hear' aetherOptions.functionParameters = ['speaker', 'message', 'data'] - console.log "creating aether with options", aetherOptions + #console.log "creating aether with options", aetherOptions return new Aether aetherOptions class SimulationTask diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee index 2b1c84531..09059d20b 100644 --- a/app/views/play/level/hud_view.coffee +++ b/app/views/play/level/hud_view.coffee @@ -342,4 +342,5 @@ module.exports = class HUDView extends View @addMoreMessage = null @animateEnterButton = null clearInterval(@messageInterval) if @messageInterval + clearTimeout @hintNextSelectionTimeout if @hintNextSelectionTimeout super() diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee index e583489c8..7e90832c8 100644 --- a/app/views/play/level_view.coffee +++ b/app/views/play/level_view.coffee @@ -135,17 +135,23 @@ module.exports = class PlayLevelView extends View team = @getQueryVariable("team") ? @world.teamForPlayer(0) opponentSpells = [] - for spellTeam, spells of @session.get('teamSpells') or {} + for spellTeam, spells of @session.get('teamSpells') ? otherSession?.get('teamSpells') ? {} continue if spellTeam is team or not team opponentSpells = opponentSpells.concat spells otherSession = @levelLoader.opponentSession opponentCode = otherSession?.get('submittedCode') or {} + console.log "otherSession", otherSession, "opponentSpells", opponentSpells myCode = @session.get('code') or {} for spell in opponentSpells - c = opponentCode[spell] - if c then myCode[spell] = c else delete myCode[spell] + [thang, spell] = spell.split '/' + c = opponentCode[thang]?[spell] + console.log "Got opponent code", c, "for", spell, "and had my code", myCode[spell] + myCode[thang] ?= {} + if c then myCode[thang][spell] = c else delete myCode[thang][spell] + console.log "Going to set session code from", _.cloneDeep(myCode) @session.set('code', myCode) + console.log "Just set session code to", _.cloneDeep(@session.get('code')) if @session.get('multiplayer') and otherSession? # For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet. @session.set 'multiplayer', false From 02d1dc2445adf6f09e76f1e3b2291056124c12d3 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Tue, 25 Feb 2014 17:14:39 -0800 Subject: [PATCH 18/32] Added a screen for when playback ends. --- app/lib/surface/PlaybackOverScreen.coffee | 40 +++++++++++++++++++++++ app/lib/surface/SpriteBoss.coffee | 9 +++-- app/lib/surface/Surface.coffee | 19 +++++++++-- app/styles/play/level/goals.sass | 4 +++ app/views/play/level/goals_view.coffee | 8 +++++ 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 app/lib/surface/PlaybackOverScreen.coffee diff --git a/app/lib/surface/PlaybackOverScreen.coffee b/app/lib/surface/PlaybackOverScreen.coffee new file mode 100644 index 000000000..b92691795 --- /dev/null +++ b/app/lib/surface/PlaybackOverScreen.coffee @@ -0,0 +1,40 @@ +CocoClass = require 'lib/CocoClass' + +module.exports = class PlaybackoverScreen extends CocoClass + constructor: (options) -> + super() + options ?= {} + @camera = options.camera + @layer = options.layer + console.error @toString(), "needs a camera." unless @camera + console.error @toString(), "needs a layer." unless @layer + @build() + + toString: -> "" + + build: -> + @dimLayer = new createjs.Container() + @dimLayer.mouseEnabled = @dimLayer.mouseChildren = false + @dimLayer.layerIndex = -12 + @dimLayer.addChild @dimScreen = new createjs.Shape() + @dimScreen.graphics.beginFill("rgba(0,0,0,0.4)").rect 0, 0, @camera.canvasWidth, @camera.canvasHeight + @dimLayer.cache 0, 0, @camera.canvasWidth, @camera.canvasHeight + @dimLayer.alpha = 0 + @layer.addChild @dimLayer + + show: -> + console.log 'show playback over screen', @showing + return if @showing + @showing = true + + @dimLayer.alpha = 0 + createjs.Tween.removeTweens @dimLayer + createjs.Tween.get(@dimLayer).to({alpha:1}, 500) + + hide: -> + console.log 'hide playback over screen', @showing + return unless @showing + @showing = false + + createjs.Tween.removeTweens @dimLayer + createjs.Tween.get(@dimLayer).to({alpha:0}, 500) diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index 5e9df2af3..b5adf175c 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -212,11 +212,16 @@ module.exports = class SpriteBoss extends CocoClass onNewWorld: (e) -> @world = @options.world = e.world + @play() + + onCastSpells: -> @stop() + + play: -> sprite.imageObject.play() for thangID, sprite of @sprites @selectionMark?.play() @targetMark?.play() - - onCastSpells: -> + + stop: -> sprite.imageObject.stop() for thangID, sprite of @sprites @selectionMark?.stop() @targetMark?.stop() diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee index 6a7a96ddf..5d44faa62 100644 --- a/app/lib/surface/Surface.coffee +++ b/app/lib/surface/Surface.coffee @@ -9,6 +9,7 @@ Layer = require './Layer' Letterbox = require './Letterbox' Dimmer = require './Dimmer' CastingScreen = require './CastingScreen' +PlaybackOverScreen = require './PlaybackOverScreen' DebugDisplay = require './DebugDisplay' CoordinateDisplay = require './CoordinateDisplay' SpriteBoss = require './SpriteBoss' @@ -90,6 +91,7 @@ module.exports = Surface = class Surface extends CocoClass @chooser?.destroy() @dimmer?.destroy() @castingScreen?.destroy() + @playbackOverScreen?.destroy() @stage.clear() @musicPlayer?.destroy() @stage.removeAllChildren() @@ -179,7 +181,7 @@ module.exports = Surface = class Surface extends CocoClass container.addChild shape setProgress: (progress, scrubDuration=500) -> - progress = Math.max(Math.min(progress, 0.99), 0.0) + progress = Math.max(Math.min(progress, 1), 0.0) @scrubbing = true onTweenEnd = => @@ -193,7 +195,7 @@ module.exports = Surface = class Surface extends CocoClass createjs.Tween.removeTweens(@) @currentFrame = @scrubbingTo - @scrubbingTo = Math.floor(progress * @world.totalFrames) + @scrubbingTo = Math.min(Math.floor(progress * @world.totalFrames), @world.totalFrames) @scrubbingPlaybackSpeed = Math.sqrt(Math.abs(@scrubbingTo - @currentFrame) * @world.dt / (scrubDuration or 0.5)) if scrubDuration t = createjs.Tween @@ -298,6 +300,18 @@ module.exports = Surface = class Surface extends CocoClass frame: @currentFrame world: @world ) + + if @lastFrame < @world.totalFrames and @currentFrame >= @world.totalFrames + @spriteBoss.stop() + @playbackOverScreen.show() + @ended = true + Backbone.Mediator.publish 'surface:playback-ended' + else if @currentFrame < @world.totalFrames and @ended + @spriteBoss.play() + @playbackOverScreen.hide() + @ended = false + Backbone.Mediator.publish 'surface:playback-restarted' + @lastFrame = @currentFrame onCastSpells: (event) -> @@ -353,6 +367,7 @@ module.exports = Surface = class Surface extends CocoClass @screenLayer.addChild new Letterbox canvasWidth: canvasWidth, canvasHeight: canvasHeight @spriteBoss = new SpriteBoss camera: @camera, surfaceLayer: @surfaceLayer, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible @castingScreen ?= new CastingScreen camera: @camera, layer: @screenLayer + @playbackOverScreen ?= new PlaybackOverScreen camera: @camera, layer: @screenLayer @stage.enableMouseOver(10) @stage.addEventListener 'stagemousemove', @onMouseMove @stage.addEventListener 'stagemousedown', @onMouseDown diff --git a/app/styles/play/level/goals.sass b/app/styles/play/level/goals.sass index cb8f843d8..6ad657253 100644 --- a/app/styles/play/level/goals.sass +++ b/app/styles/play/level/goals.sass @@ -3,6 +3,10 @@ left: 10px top: 42px background-color: rgba(200,200,200,0.8) + + &.brighter + background-color: rgba(200,200,200,1.0) + border: black padding: 5px 7px 5px 5px box-sizing: border-box diff --git a/app/views/play/level/goals_view.coffee b/app/views/play/level/goals_view.coffee index e314bee5e..b9eb3f89f 100644 --- a/app/views/play/level/goals_view.coffee +++ b/app/views/play/level/goals_view.coffee @@ -14,6 +14,8 @@ module.exports = class GoalsView extends View subscriptions: 'goal-manager:new-goal-states': 'onNewGoalStates' 'level-set-letterbox': 'onSetLetterbox' + 'surface:playback-restarted': 'onSurfacePlaybackRestarted' + 'surface:playback-ended': 'onSurfacePlaybackEnded' events: 'click': 'toggleCollapse' @@ -48,6 +50,12 @@ module.exports = class GoalsView extends View goals.push goal @$el.removeClass('secret') if goals.length > 0 + onSurfacePlaybackRestarted: -> + @$el.removeClass 'brighter' + + onSurfacePlaybackEnded: -> + @$el.addClass 'brighter' + render: -> super() @$el.addClass('secret').addClass('expanded') From bb76fb241c42c6d6b32bcd1008b705e3d2f55875 Mon Sep 17 00:00:00 2001 From: Michael Schmatz Date: Wed, 26 Feb 2014 09:21:41 -0800 Subject: [PATCH 19/32] Fixed simulator The format of something must have suddenly changed? --- app/lib/simulator/Simulator.coffee | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/app/lib/simulator/Simulator.coffee b/app/lib/simulator/Simulator.coffee index 5a08eadfe..cbaf95c4a 100644 --- a/app/lib/simulator/Simulator.coffee +++ b/app/lib/simulator/Simulator.coffee @@ -178,7 +178,6 @@ module.exports = class Simulator generateSpellKeyToSourceMapPropertiesFromThang: (thang) => for component in thang.components continue unless @componentHasProgrammableMethods component - for methodName, method of component.config.programmableMethods spellKey = @generateSpellKeyFromThangIDAndMethodName thang.id, methodName @@ -187,9 +186,11 @@ module.exports = class Simulator @transpileSpell thang, spellKey, methodName generateSpellKeyFromThangIDAndMethodName: (thang, methodName) -> - spellKeyComponents = [thang.id, methodName] + spellKeyComponents = [thang, methodName] spellKeyComponents[0] = _.string.slugify spellKeyComponents[0] - spellKeyComponents.join '/' + spellKey = spellKeyComponents.join '/' + spellKey + createSpellAndAssignName: (spellKey, spellName) -> @spells[spellKey] ?= {} @@ -202,7 +203,7 @@ module.exports = class Simulator transpileSpell: (thang, spellKey, methodName) -> slugifiedThangID = _.string.slugify thang.id - source = @currentUserCodeMap[slugifiedThangID]?[methodName] ? "" + source = @currentUserCodeMap[[slugifiedThangID,methodName].join '/'] ? "" @spells[spellKey].thangs[thang.id].aether.transpile source createAether: (methodName, method) -> @@ -253,12 +254,18 @@ class SimulationTask generateSpellKeyToSourceMap: -> spellKeyToSourceMap = {} - for session in @rawData.sessions teamSpells = session.teamSpells[session.team] - _.merge spellKeyToSourceMap, _.pick(session.code, teamSpells) - + teamCode = {} + for thangName, thangSpells of session.code + for spellName, spell of thangSpells + fullSpellName = [thangName,spellName].join '/' + if _.contains(teamSpells, fullSpellName) + teamCode[fullSpellName]=spell + + _.merge spellKeyToSourceMap, teamCode commonSpells = session.teamSpells["common"] _.merge spellKeyToSourceMap, _.pick(session.code, commonSpells) if commonSpells? + spellKeyToSourceMap From a0521802505a8045d6dfc3c74bf19973254310e3 Mon Sep 17 00:00:00 2001 From: Michael Schmatz Date: Wed, 26 Feb 2014 12:14:02 -0800 Subject: [PATCH 20/32] Improved match scheduling --- app/lib/simulator/Simulator.coffee | 7 +- server/queues/scoring.coffee | 107 ++++++++++++++++++++++++----- 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/app/lib/simulator/Simulator.coffee b/app/lib/simulator/Simulator.coffee index cbaf95c4a..723c0cab3 100644 --- a/app/lib/simulator/Simulator.coffee +++ b/app/lib/simulator/Simulator.coffee @@ -108,17 +108,22 @@ module.exports = class Simulator taskResults = taskID: @task.getTaskID() receiptHandle: @task.getReceiptHandle() + originalSessionID: @task.getFirstSessionID() + originalSessionRank: -1 calculationTime: 500 sessions: [] for session in @task.getSessions() + sessionResult = sessionID: session.sessionID submitDate: session.submitDate creator: session.creator metrics: rank: @calculateSessionRank session.sessionID, simulationResults.goalStates, @task.generateTeamToSessionMap() - + if session.sessionID is taskResults.originalSessionID + taskResults.originalSessionRank = sessionResult.metrics.rank + taskResults.originalSessionTeam = session.team taskResults.sessions.push sessionResult return taskResults diff --git a/server/queues/scoring.coffee b/server/queues/scoring.coffee index 4592ec74c..c691c235b 100644 --- a/server/queues/scoring.coffee +++ b/server/queues/scoring.coffee @@ -24,24 +24,27 @@ connectToScoringQueue = -> scoringTaskQueue = data log.info "Connected to scoring task queue!" -module.exports.addPairwiseTaskToQueue = (req, res) -> +module.exports.addPairwiseTaskToQueueFromRequest = (req, res) -> taskPair = req.body.sessions - #unless isUserAdmin req then return errors.forbidden res, "You do not have the permissions to submit that game to the leaderboard" - #fetch both sessions + addPairwiseTaskToQueue req.body.sessions (err, success) -> + if err? then return errors.serverError res, "There was an error adding pairwise tasks: #{err}" + sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"} + + +addPairwiseTaskToQueue = (taskPair, cb) -> LevelSession.findOne(_id:taskPair[0]).lean().exec (err, firstSession) => - if err? then return errors.serverError res, "There was an error fetching the first session in the pair" + if err? then return cb err, false LevelSession.find(_id:taskPair[1]).exec (err, secondSession) => - if err? then return errors.serverError res, "There was an error fetching the second session" + if err? then return cb err, false try taskPairs = generateTaskPairs(secondSession, firstSession) catch e - if e then return errors.serverError res, "There was an error generating the task pairs" - - sendEachTaskPairToTheQueue taskPairs, (taskPairError) -> - if taskPairError? then return errors.serverError res, "There was an error sending the task pairs to the queue" + if e then return cb e, false - sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"} - + sendEachTaskPairToTheQueue taskPairs, (taskPairError) -> + if taskPairError? then return cb taskPairError,false + cb null, true + module.exports.createNewTask = (req, res) -> requestSessionID = req.body.session @@ -56,8 +59,8 @@ module.exports.createNewTask = (req, res) -> updateSessionToSubmit sessionToSubmit, (err, data) -> if err? then return errors.serverError res, "There was an error updating the session" - - fetchSessionsToRankAgainst (err, sessionsToRankAgainst) -> + opposingTeam = calculateOpposingTeam(sessionToSubmit.team) + fetchInitialSessionsToRankAgainst opposingTeam, (err, sessionsToRankAgainst) -> if err? then return errors.serverError res, "There was an error fetching the sessions to rank against" taskPairs = generateTaskPairs(sessionsToRankAgainst, sessionToSubmit) @@ -114,9 +117,64 @@ module.exports.processTaskResult = (req, res) -> addMatchToSessions clientResponseObject, newScoresObject, (err, data) -> if err? then return errors.serverError res, "There was an error updating the sessions with the match! #{JSON.stringify err}" - console.log "Sending response object" - sendResponseObject req, res, {"message":"The scores were updated successfully!"} + originalSessionID = clientResponseObject.originalSessionID + originalSessionTeam = clientResponseObject.originalSessionTeam + originalSessionRank = parseInt clientResponseObject.originalSessionRank + console.log "The player #{originalSessionID} just achieved rank #{clientResponseObject.originalSessionRank}" + if originalSessionRank is 0 + console.log "Should submit another session into the queue!" + #fetch next session + opposingTeam = calculateOpposingTeam(originalSessionTeam) + opponentID = _.pull(_.keys(newScoresObject), originalSessionID) + sessionNewScore = newScoresObject[originalSessionID].totalScore + opponentNewScore = newScoresObject[opponentID].totalScore + findNearestBetterSessionID sessionNewScore, opponentNewScore ,opposingTeam, (err, opponentSessionID) -> + if err? then return errors.serverError res, "There was an error finding the nearest sessionID!" + unless opponentSessionID then return sendResponseObject req, res, {"message":"There were no more games to rank(game is at top!"} + + addPairwiseTaskToQueue [originalSessionID, opponentSessionID], (err, success) -> + if err? then return errors.serverError res, "There was an error sending the pairwise tasks to the queue!" + sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"} + else + console.log "Player lost, achieved rank #{originalSessionRank}" + sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"} +findNearestBetterSessionID = (sessionTotalScore, opponentSessionTotalScore, opposingTeam, cb) -> + queryParameters = + totalScore: + $gt:Math.max(10,opponentSessionTotalScore) + levelID: "project-dota" + submitted: true + submittedCode: + $exists: true + team: opposingTeam + + limitNumber = 1 + + sortParameters = + totalScore: 1 + + selectString = '_id totalScore' + + query = LevelSession.findOne(queryParameters) + .sort(sortParameters) + .limit(limitNumber) + .select(selectString) + .lean() + + console.log "Finding session with score near #{sessionTotalScore}" + query.exec (err, session) -> + if err? then return cb err, session + unless session then return cb err, null + console.log "Found session with score #{session.totalScore}" + cb err, session._id + +calculateOpposingTeam = (sessionTeam) -> + teams = ['ogres','humans'] + opposingTeams = _.pull teams, sessionTeam + return opposingTeams[0] + + validatePermissions = (req, sessionID, callback) -> if isUserAnonymous req then return callback null, false if isUserAdmin req then return callback null, true @@ -179,13 +237,26 @@ updateSessionToSubmit = (sessionToUpdate, callback) -> totalScore: 10 LevelSession.update {_id: sessionToUpdate._id}, sessionUpdateObject, callback -fetchSessionsToRankAgainst = (callback) -> - submittedSessionsQuery = +fetchInitialSessionsToRankAgainst = (opposingTeam, callback) -> + console.log "Fetching sessions to rank against for opposing team #{opposingTeam}" + findParameters = levelID: "project-dota" submitted: true submittedCode: $exists: true - LevelSession.find submittedSessionsQuery, callback + team: opposingTeam + + sortParameters = + totalScore: 1 + + limitNumber = 1 + + query = LevelSession.find(findParameters) + .sort(sortParameters) + .limit(limitNumber) + + + query.exec callback generateTaskPairs = (submittedSessions, sessionToScore) -> taskPairs = [] From b648098c953eb59df1dca7719019d6a9d4b101c4 Mon Sep 17 00:00:00 2001 From: Michael Schmatz Date: Wed, 26 Feb 2014 14:14:43 -0800 Subject: [PATCH 21/32] Implemented espionage mode --- app/templates/admin.jade | 12 ++++++++++++ app/views/admin_view.coffee | 29 +++++++++++++++++++++++++++++ server/routes/auth.coffee | 25 ++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/app/templates/admin.jade b/app/templates/admin.jade index 43d6769c6..feb9d9347 100644 --- a/app/templates/admin.jade +++ b/app/templates/admin.jade @@ -2,6 +2,18 @@ extends /templates/base block content + h3 Espionage mode + h5 Please enter the email/username of the person you want to spy on + .form + .form-group + label.control-label Email + input#user-email + .form-group + label.control-label Username + input#user-username + + button.btn.btn-primary.btn-large#enter-espionage-mode 007 + h3(data-i18n="admin.av_title") Admin Views h4(data-i18n="admin.av_entities_sub_title") Entities diff --git a/app/views/admin_view.coffee b/app/views/admin_view.coffee index 941136574..e71c9acaf 100644 --- a/app/views/admin_view.coffee +++ b/app/views/admin_view.coffee @@ -1,6 +1,35 @@ +{backboneFailure, genericFailure} = require 'lib/errors' View = require 'views/kinds/RootView' template = require 'templates/admin' +storage = require 'lib/storage' module.exports = class AdminView extends View id: "admin-view" template: template + + events: + 'click #enter-espionage-mode': 'enterEspionageMode' + + enterEspionageMode: -> + userEmail = $("#user-email").val().toLowerCase() + username = $("#user-username").val().toLowerCase() + + userIdentifier = userEmail || username + postData = + usernameLower: username + emailLower: userEmail + + $.ajax + type: "POST", + url: "/auth/spy" + data: postData + success: @espionageSuccess + error: @espionageFailure + + espionageSuccess: (model) -> + storage.save('whoami',model) + window.location.reload() + espionageFailure: (jqxhr, status,error)-> + console.log "There was an error entering espionage mode: #{error}" + + \ No newline at end of file diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee index e5d3f9367..2e6dbf72d 100644 --- a/server/routes/auth.coffee +++ b/server/routes/auth.coffee @@ -28,7 +28,30 @@ module.exports.setup = (app) -> return done(null, user) ) )) - + app.post '/auth/spy', (req, res, next) -> + if req?.user?.isAdmin() + + username = req.body.usernameLower + emailLower = req.body.emailLower + if emailLower + query = {"emailLower":emailLower} + else if username + query = {"nameLower":username} + else + return errors.badInput res, "You need to supply one of emailLower or username" + + User.findOne query, (err, user) -> + if err? then return errors.serverError res, "There was an error finding the specified user" + + unless user then return errors.badInput res, "The specified user couldn't be found" + + req.logIn user, (err) -> + if err? then return errors.serverError res, "There was an error logging in with the specified" + res.send(UserHandler.formatEntity(req, user)) + return res.end() + else + return errors.unauthorized res, "You must be an admin to enter espionage mode" + app.post('/auth/login', (req, res, next) -> authentication.authenticate('local', (err, user, info) -> return next(err) if err From ea73d91a6b07f15dd51f804129c70c6f2d3789c4 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Wed, 26 Feb 2014 15:44:46 -0800 Subject: [PATCH 22/32] Made the docs modal larger. --- app/styles/play/level/modal/docs.sass | 2 ++ app/views/play/level/modal/docs_modal.coffee | 1 + 2 files changed, 3 insertions(+) create mode 100644 app/styles/play/level/modal/docs.sass diff --git a/app/styles/play/level/modal/docs.sass b/app/styles/play/level/modal/docs.sass new file mode 100644 index 000000000..3c25f0389 --- /dev/null +++ b/app/styles/play/level/modal/docs.sass @@ -0,0 +1,2 @@ +#docs-modal .modal-dialog + width: 800px \ No newline at end of file diff --git a/app/views/play/level/modal/docs_modal.coffee b/app/views/play/level/modal/docs_modal.coffee index fc975b84a..c7b77a287 100644 --- a/app/views/play/level/modal/docs_modal.coffee +++ b/app/views/play/level/modal/docs_modal.coffee @@ -6,6 +6,7 @@ Article = require 'models/Article' module.exports = class DocsModal extends View template: template + id: 'docs-modal' shortcuts: 'enter': 'hide' From c86feb13e86942c29b6e239eb7c5d74d860eccf0 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Wed, 26 Feb 2014 15:56:05 -0800 Subject: [PATCH 23/32] Fixed the region and point choosers for the level editor. --- app/lib/surface/PointChooser.coffee | 1 + app/lib/surface/RegionChooser.coffee | 1 + 2 files changed, 2 insertions(+) diff --git a/app/lib/surface/PointChooser.coffee b/app/lib/surface/PointChooser.coffee index 470b10c5f..c55b1a134 100644 --- a/app/lib/surface/PointChooser.coffee +++ b/app/lib/surface/PointChooser.coffee @@ -5,6 +5,7 @@ module.exports = class PointChooser extends CocoClass super() @buildShape() @options.stage.addEventListener 'stagemousedown', @onMouseDown + @options.camera.dragDisabled = true destroy: -> @options.stage.removeEventListener 'stagemousedown', @onMouseDown diff --git a/app/lib/surface/RegionChooser.coffee b/app/lib/surface/RegionChooser.coffee index 14eb47035..d0dbdc82a 100644 --- a/app/lib/surface/RegionChooser.coffee +++ b/app/lib/surface/RegionChooser.coffee @@ -7,6 +7,7 @@ module.exports = class RegionChooser extends CocoClass @options.stage.addEventListener 'stagemousedown', @onMouseDown @options.stage.addEventListener 'stagemousemove', @onMouseMove @options.stage.addEventListener 'stagemouseup', @onMouseUp + @options.camera.dragDisabled = true destroy: -> @options.stage.removeEventListener 'stagemousedown', @onMouseDown From 172242d226cc61f4467ac69c1f7a043543912b00 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 26 Feb 2014 17:06:21 -0800 Subject: [PATCH 24/32] Re-denormalize session if things have changed. Removed some logs. --- app/lib/LevelLoader.coffee | 13 ++++++++----- app/views/play/level_view.coffee | 4 ---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index 8afc6577a..3d1aa8115 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -110,16 +110,19 @@ module.exports = class LevelLoader extends CocoClass @updateCompleted = true denormalizeSession: -> - return if @session.get 'levelName' + return if @sessionDenormalized patch = 'levelName': @level.get('name') 'levelID': @level.get('slug') or @level.id if me.id is @session.get 'creator' patch.creatorName = me.get('name') - - @session.set key, value for key, value of patch - tempSession = new LevelSession _id: @session.id - tempSession.save(patch, {patch: true}) + for key, value of patch + if @session.get(key) is value + delete patch[key] + unless _.isEmpty patch + @session.set key, value for key, value of patch + tempSession = new LevelSession _id: @session.id + tempSession.save(patch, {patch: true}) @sessionDenormalized = true # World init diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee index 7e90832c8..16a817dcd 100644 --- a/app/views/play/level_view.coffee +++ b/app/views/play/level_view.coffee @@ -141,17 +141,13 @@ module.exports = class PlayLevelView extends View otherSession = @levelLoader.opponentSession opponentCode = otherSession?.get('submittedCode') or {} - console.log "otherSession", otherSession, "opponentSpells", opponentSpells myCode = @session.get('code') or {} for spell in opponentSpells [thang, spell] = spell.split '/' c = opponentCode[thang]?[spell] - console.log "Got opponent code", c, "for", spell, "and had my code", myCode[spell] myCode[thang] ?= {} if c then myCode[thang][spell] = c else delete myCode[thang][spell] - console.log "Going to set session code from", _.cloneDeep(myCode) @session.set('code', myCode) - console.log "Just set session code to", _.cloneDeep(@session.get('code')) if @session.get('multiplayer') and otherSession? # For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet. @session.set 'multiplayer', false From 0cf20b577d79ce306834367c5939704d83b64f0c Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 26 Feb 2014 17:23:59 -0800 Subject: [PATCH 25/32] Added a delay to the property documentation on spell debug hover. --- app/views/play/level/tome/spell_debug_view.coffee | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/views/play/level/tome/spell_debug_view.coffee b/app/views/play/level/tome/spell_debug_view.coffee index f59b84501..5f4cfdd30 100644 --- a/app/views/play/level/tome/spell_debug_view.coffee +++ b/app/views/play/level/tome/spell_debug_view.coffee @@ -82,11 +82,20 @@ module.exports = class DebugView extends View else @$el.hide() if @variableChain?.length is 2 - Backbone.Mediator.publish 'tome:spell-debug-property-hovered', property: @variableChain[1], owner: @variableChain[0] + clearTimeout @hoveredPropertyTimeout if @hoveredPropertyTimeout + @hoveredPropertyTimeout = _.delay @notifyPropertyHovered, 500 else - Backbone.Mediator.publish 'tome:spell-debug-property-hovered', property: null + @notifyPropertyHovered() @updateMarker() + notifyPropertyHovered: => + clearTimeout @hoveredPropertyTimeout if @hoveredPropertyTimeout + @hoveredPropertyTimeout = null + oldHoveredProperty = @hoveredProperty + @hoveredProperty = if @variableChain?.length is 2 then owner: @variableChain[0], property: @variableChain[1] else {} + unless _.isEqual oldHoveredProperty, @hoveredProperty + Backbone.Mediator.publish 'tome:spell-debug-property-hovered', @hoveredProperty + updateMarker: -> if @marker @ace.getSession().removeMarker @marker From f82483b9059fee86a07605b506e8da320617b183 Mon Sep 17 00:00:00 2001 From: Michael Schmatz Date: Wed, 26 Feb 2014 17:30:56 -0800 Subject: [PATCH 26/32] Changed session scheduling --- .../sessions/level_session_schema.coffee | 7 ++ server/queues/scoring.coffee | 84 ++++++++++++++----- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/server/levels/sessions/level_session_schema.coffee b/server/levels/sessions/level_session_schema.coffee index da97b8ce5..290422c10 100644 --- a/server/levels/sessions/level_session_schema.coffee +++ b/server/levels/sessions/level_session_schema.coffee @@ -139,6 +139,13 @@ _.extend LevelSessionSchema.properties, submittedCode: type: 'object' + + numberOfWinsAndTies: + type: 'number' + default: 0 + numberOfLosses: + type: 'number' + default: 0 matches: type: 'array' diff --git a/server/queues/scoring.coffee b/server/queues/scoring.coffee index c691c235b..40a6b2f21 100644 --- a/server/queues/scoring.coffee +++ b/server/queues/scoring.coffee @@ -12,7 +12,7 @@ TaskLog = require './task/ScoringTask' bayes = new (require 'bayesian-battle')() scoringTaskQueue = undefined -scoringTaskTimeoutInSeconds = 120 +scoringTaskTimeoutInSeconds = 180 module.exports.setup = (app) -> connectToScoringQueue() @@ -117,32 +117,70 @@ module.exports.processTaskResult = (req, res) -> addMatchToSessions clientResponseObject, newScoresObject, (err, data) -> if err? then return errors.serverError res, "There was an error updating the sessions with the match! #{JSON.stringify err}" + originalSessionID = clientResponseObject.originalSessionID originalSessionTeam = clientResponseObject.originalSessionTeam originalSessionRank = parseInt clientResponseObject.originalSessionRank - console.log "The player #{originalSessionID} just achieved rank #{clientResponseObject.originalSessionRank}" - if originalSessionRank is 0 - console.log "Should submit another session into the queue!" - #fetch next session - opposingTeam = calculateOpposingTeam(originalSessionTeam) - opponentID = _.pull(_.keys(newScoresObject), originalSessionID) - sessionNewScore = newScoresObject[originalSessionID].totalScore - opponentNewScore = newScoresObject[opponentID].totalScore - findNearestBetterSessionID sessionNewScore, opponentNewScore ,opposingTeam, (err, opponentSessionID) -> - if err? then return errors.serverError res, "There was an error finding the nearest sessionID!" - unless opponentSessionID then return sendResponseObject req, res, {"message":"There were no more games to rank(game is at top!"} - - addPairwiseTaskToQueue [originalSessionID, opponentSessionID], (err, success) -> - if err? then return errors.serverError res, "There was an error sending the pairwise tasks to the queue!" - sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"} - else - console.log "Player lost, achieved rank #{originalSessionRank}" - sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"} + + determineIfSessionShouldContinueAndUpdateLog originalSessionID, originalSessionRank, (err, sessionShouldContinue) -> + if err? then return errors.serverError res, "There was an error determining if the session should continue, #{err}" + + if sessionShouldContinue + opposingTeam = calculateOpposingTeam(originalSessionTeam) + opponentID = _.pull(_.keys(newScoresObject), originalSessionID) + sessionNewScore = newScoresObject[originalSessionID].totalScore + opponentNewScore = newScoresObject[opponentID].totalScore + findNearestBetterSessionID sessionNewScore, opponentNewScore, opponentID ,opposingTeam, (err, opponentSessionID) -> + if err? then return errors.serverError res, "There was an error finding the nearest sessionID!" + unless opponentSessionID then return sendResponseObject req, res, {"message":"There were no more games to rank(game is at top!"} + + addPairwiseTaskToQueue [originalSessionID, opponentSessionID], (err, success) -> + if err? then return errors.serverError res, "There was an error sending the pairwise tasks to the queue!" + sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"} + else + console.log "Player lost, achieved rank #{originalSessionRank}" + sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"} -findNearestBetterSessionID = (sessionTotalScore, opponentSessionTotalScore, opposingTeam, cb) -> + +determineIfSessionShouldContinueAndUpdateLog = (sessionID, sessionRank, cb) -> + queryParameters = + _id: sessionID + + updateParameters = + "$inc": {} + + if sessionRank is 0 + updateParameters["$inc"] = {numberOfWinsAndTies: 1} + else + updateParameters["$inc"] = {numberOfLosses: 1} + + LevelSession.findOneAndUpdate queryParameters, updateParameters,{select: 'numberOfWinsAndTies numberOfLosses'}, (err, updatedSession) -> + if err? then return cb err, updatedSession + updatedSession = updatedSession.toObject() + + totalNumberOfGamesPlayed = updatedSession.numberOfWinsAndTies + updatedSession.numberOfLosses + if totalNumberOfGamesPlayed < 5 + console.log "Number of games played is less than 5, continuing..." + cb null, true + else if totalNumberOfGamesPlayed > 15 + console.log "Too many games played, ending..." + cb null, false + else + ratio = (updatedSession.numberOfLosses - 5) / (totalNumberOfGamesPlayed) + if ratio > 0.66 + cb null, false + console.log "Ratio(#{ratio}) is bad, ending simulation" + else + console.log "Ratio(#{ratio}) is good, so continuing simulations" + cb null, true + + +findNearestBetterSessionID = (sessionTotalScore, opponentSessionTotalScore, opponentSessionID, opposingTeam, cb) -> queryParameters = totalScore: - $gt:Math.max(10,opponentSessionTotalScore) + $gt:opponentSessionTotalScore + 0.5 + _id: + $ne: opponentSessionID levelID: "project-dota" submitted: true submittedCode: @@ -162,7 +200,7 @@ findNearestBetterSessionID = (sessionTotalScore, opponentSessionTotalScore, oppo .select(selectString) .lean() - console.log "Finding session with score near #{sessionTotalScore}" + console.log "Finding session with score near #{opponentSessionTotalScore}" query.exec (err, session) -> if err? then return cb err, session unless session then return cb err, null @@ -235,6 +273,8 @@ updateSessionToSubmit = (sessionToUpdate, callback) -> meanStrength: 25 standardDeviation: 25/3 totalScore: 10 + numberOfWinsAndTies: 0 + numberOfLosses: 0 LevelSession.update {_id: sessionToUpdate._id}, sessionUpdateObject, callback fetchInitialSessionsToRankAgainst = (opposingTeam, callback) -> From 081274579b7ef4a636873fc8ca8c3624344c44a6 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 26 Feb 2014 17:45:08 -0800 Subject: [PATCH 27/32] Forget old goals. --- app/lib/simulator/Simulator.coffee | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/app/lib/simulator/Simulator.coffee b/app/lib/simulator/Simulator.coffee index 723c0cab3..521e810c7 100644 --- a/app/lib/simulator/Simulator.coffee +++ b/app/lib/simulator/Simulator.coffee @@ -64,7 +64,7 @@ module.exports = class Simulator setupGoalManager: -> @god.goalManager = new GoalManager @world - @god.goalManager.goals = @fetchGoalsFromWorldNoteChain() + @god.goalManager.goals = @god.level.goals @god.goalManager.goalStates = @manuallyGenerateGoalStates() commenceSimulationAndSetupCallback: -> @@ -114,7 +114,7 @@ module.exports = class Simulator sessions: [] for session in @task.getSessions() - + sessionResult = sessionID: session.sessionID submitDate: session.submitDate @@ -142,8 +142,6 @@ module.exports = class Simulator else return 1 - fetchGoalsFromWorldNoteChain: -> return @god.goalManager.world.scripts[0].noteChain[0].goals.add - manuallyGenerateGoalStates: -> goalStates = "destroy-humans": @@ -195,7 +193,7 @@ module.exports = class Simulator spellKeyComponents[0] = _.string.slugify spellKeyComponents[0] spellKey = spellKeyComponents.join '/' spellKey - + createSpellAndAssignName: (spellKey, spellName) -> @spells[spellKey] ?= {} @@ -267,10 +265,10 @@ class SimulationTask fullSpellName = [thangName,spellName].join '/' if _.contains(teamSpells, fullSpellName) teamCode[fullSpellName]=spell - + _.merge spellKeyToSourceMap, teamCode commonSpells = session.teamSpells["common"] _.merge spellKeyToSourceMap, _.pick(session.code, commonSpells) if commonSpells? - + spellKeyToSourceMap From 5c1c17c8dd3bfb37de4cc61ef7f370b2c771a2cf Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 26 Feb 2014 17:52:08 -0800 Subject: [PATCH 28/32] Green Guide button for attention. --- app/templates/play/level/control_bar.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/play/level/control_bar.jade b/app/templates/play/level/control_bar.jade index 59d378bc8..0cdd24241 100644 --- a/app/templates/play/level/control_bar.jade +++ b/app/templates/play/level/control_bar.jade @@ -6,7 +6,7 @@ h4.home h4.title #{worldName} -button.btn.btn-xs.btn-inverse.banner#docs-button(title="Show level instructions", data-i18n="play_level.guide") Guide +button.btn.btn-xs.btn-success.banner#docs-button(title="Show level instructions", data-i18n="play_level.guide") Guide if ladderGame button.btn.btn-xs.btn-inverse.banner#multiplayer-button(title="Leaderboard", data-i18n="play_level.leaderboard") Leaderboard From 48122000ed8e7961458dae5377ae8c067014daee Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 26 Feb 2014 18:09:09 -0800 Subject: [PATCH 29/32] Gold shows up as an int in the HUD now. --- app/lib/LevelBus.coffee | 1 - app/views/play/level/hud_view.coffee | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/lib/LevelBus.coffee b/app/lib/LevelBus.coffee index 287110f98..18985716b 100644 --- a/app/lib/LevelBus.coffee +++ b/app/lib/LevelBus.coffee @@ -113,7 +113,6 @@ module.exports = class LevelBus extends Bus @changedSessionProperties.teamSpells = true @session.set({'teamSpells': @teamSpellMap}) @saveSession() - console.log spellTeam, me.team, e.spell.spellKey if spellTeam is me.team @onSpellChanged e # Save the new spell to the session, too. diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee index 09059d20b..cc62fb047 100644 --- a/app/views/play/level/hud_view.coffee +++ b/app/views/play/level/hud_view.coffee @@ -270,7 +270,7 @@ module.exports = class HUDView extends View if prop is "rotation" return (val * 180 / Math.PI).toFixed(0) + "˚" if typeof val is 'number' - if Math.round(val) == val then return val.toFixed(0) # int + if Math.round(val) == val or prop is 'gold' then return val.toFixed(0) # int if -10 < val < 10 then return val.toFixed(2) if -100 < val < 100 then return val.toFixed(1) return val.toFixed(0) From 7052b0600bc0519cf03deabb0c51661c78ff1b08 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Wed, 26 Feb 2014 18:42:39 -0800 Subject: [PATCH 30/32] Made mouse dragging not interrupt selecting units so much. --- app/lib/surface/SpriteBoss.coffee | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index b5adf175c..130d017b7 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -25,6 +25,7 @@ module.exports = class SpriteBoss extends CocoClass constructor: (@options) -> super() + @dragged = 0 @options ?= {} @camera = @options.camera @surfaceLayer = @options.surfaceLayer @@ -238,11 +239,12 @@ module.exports = class SpriteBoss extends CocoClass @selectThang e.thangID, e.spellName onCameraDragged: -> - @dragged = true + @dragged += 1 onSpriteMouseUp: (e) -> return if key.shift and @options.choosing - return @dragged = false if @dragged + return @dragged = 0 if @dragged > 3 + @dragged = 0 sprite = if e.sprite?.thang?.isSelectable then e.sprite else null @selectSprite e, sprite From c26995a3a9e3dda848dc208f5b6b1f1fb39c32d0 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 26 Feb 2014 18:58:25 -0800 Subject: [PATCH 31/32] Home button on ladder level goes to ladder. --- app/templates/play/level/control_bar.jade | 2 +- app/views/play/level/control_bar_view.coffee | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/templates/play/level/control_bar.jade b/app/templates/play/level/control_bar.jade index 0cdd24241..1cc3af07d 100644 --- a/app/templates/play/level/control_bar.jade +++ b/app/templates/play/level/control_bar.jade @@ -1,6 +1,6 @@ h4.home - a(href="/") + a(href=homeLink || "/") i.icon-home.icon-white span(data-i18n="play_level.home") Home diff --git a/app/views/play/level/control_bar_view.coffee b/app/views/play/level/control_bar_view.coffee index 7c5b22d53..685452d81 100644 --- a/app/views/play/level/control_bar_view.coffee +++ b/app/views/play/level/control_bar_view.coffee @@ -47,12 +47,17 @@ module.exports = class ControlBarView extends View text += " (#{numPlayers})" if numPlayers > 1 $('#multiplayer-button', @$el).text(text) - getRenderData: (context={}) -> - super context - context.worldName = @worldName - context.multiplayerEnabled = @session.get('multiplayer') - context.ladderGame = @ladderGame - context + getRenderData: (c={}) -> + super c + c.worldName = @worldName + c.multiplayerEnabled = @session.get('multiplayer') + c.ladderGame = @ladderGame + c.homeLink = "/" + levelID = @level.get('slug') + if levelID in ["project-dota", "brawlwood", "ladder-tutorial"] + levelID = 'project-dota' if levelID is 'ladder-tutorial' + c.homeLink = "/play/ladder/" + levelID + c showGuideModal: -> options = {docs: @level.get('documentation'), supermodel: @supermodel} From ec7028af6015138e72dc957b179a8b84e0ca27c5 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Wed, 26 Feb 2014 19:30:37 -0800 Subject: [PATCH 32/32] Fixed uploading images for articles. --- app/treema-ext.coffee | 7 ++++--- app/views/editor/article/edit.coffee | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/treema-ext.coffee b/app/treema-ext.coffee index ec105749b..9112abaa6 100644 --- a/app/treema-ext.coffee +++ b/app/treema-ext.coffee @@ -38,12 +38,13 @@ class LiveEditingMarkup extends TreemaNode.nodeMap.ace url: InkBlob.url filename: InkBlob.filename mimetype: InkBlob.mimetype - description: '' - createdFor: [] + path: @settings.filePath + + @uploadingPath = [@settings.filePath, InkBlob.filename].join('/') $.ajax('/file', { type: 'POST', data: body, success: @onFileUploaded }) onFileUploaded: (e) => - @editor.insert "![#{e.metadata.name}](/file/#{e._id})" + @editor.insert "![#{e.metadata.name}](/file/#{@uploadingPath})" onEditorChange: => @saveChanges() diff --git a/app/views/editor/article/edit.coffee b/app/views/editor/article/edit.coffee index f462afd40..05df5291d 100644 --- a/app/views/editor/article/edit.coffee +++ b/app/views/editor/article/edit.coffee @@ -35,6 +35,7 @@ module.exports = class ArticleEditView extends View data = $.extend(true, {}, @article.attributes) options = data: data + filePath: "db/thang.type/#{@article.get('original')}" schema: Article.schema.attributes callbacks: change: @pushChangesToPreview