Merge branch 'master' into production

This commit is contained in:
Nick Winter 2014-08-27 12:27:10 -07:00
commit 4d3c5524a8
136 changed files with 1915 additions and 2342 deletions

View file

@ -10,7 +10,7 @@ module.exports = class CocoRouter extends Backbone.Router
initialize: -> initialize: ->
# http://nerds.airbnb.com/how-to-add-google-analytics-page-tracking-to-57536 # http://nerds.airbnb.com/how-to-add-google-analytics-page-tracking-to-57536
@bind 'route', @_trackPageView @bind 'route', @_trackPageView
Backbone.Mediator.subscribe 'gapi-loaded', @onGPlusAPILoaded, @ Backbone.Mediator.subscribe 'auth:gplus-api-loaded', @onGPlusAPILoaded, @
Backbone.Mediator.subscribe 'router:navigate', @onNavigate, @ Backbone.Mediator.subscribe 'router:navigate', @onNavigate, @
routes: routes:
@ -49,7 +49,7 @@ module.exports = class CocoRouter extends Backbone.Router
'demo(/*subpath)': go('DemoView') 'demo(/*subpath)': go('DemoView')
'docs/components': go('docs/ComponentDocumentationView') 'docs/components': go('docs/ComponentDocumentationView')
'editor': go('editor/MainEditorView') 'editor': go('CommunityView')
'editor/achievement': go('editor/achievement/AchievementSearchView') 'editor/achievement': go('editor/achievement/AchievementSearchView')
'editor/achievement/:articleID': go('editor/achievement/AchievementEditView') 'editor/achievement/:articleID': go('editor/achievement/AchievementEditView')

View file

@ -2,7 +2,7 @@ Backbone.Mediator.setValidationEnabled false
app = require 'application' app = require 'application'
channelSchemas = channelSchemas =
'app': require './schemas/subscriptions/app' 'auth': require './schemas/subscriptions/auth'
'bus': require './schemas/subscriptions/bus' 'bus': require './schemas/subscriptions/bus'
'editor': require './schemas/subscriptions/editor' 'editor': require './schemas/subscriptions/editor'
'errors': require './schemas/subscriptions/errors' 'errors': require './schemas/subscriptions/errors'
@ -10,8 +10,8 @@ channelSchemas =
'play': require './schemas/subscriptions/play' 'play': require './schemas/subscriptions/play'
'surface': require './schemas/subscriptions/surface' 'surface': require './schemas/subscriptions/surface'
'tome': require './schemas/subscriptions/tome' 'tome': require './schemas/subscriptions/tome'
'user': require './schemas/subscriptions/user' 'god': require './schemas/subscriptions/god'
'world': require './schemas/subscriptions/world' 'scripts': require './schemas/subscriptions/scripts'
definitionSchemas = definitionSchemas =
'bus': require './schemas/definitions/bus' 'bus': require './schemas/definitions/bus'

View file

@ -91,7 +91,7 @@ module.exports = class Angel extends CocoClass
when 'user-code-problem' when 'user-code-problem'
Backbone.Mediator.publish 'god:user-code-problem', problem: event.data.problem Backbone.Mediator.publish 'god:user-code-problem', problem: event.data.problem
when 'world-load-progress-changed' when 'world-load-progress-changed'
Backbone.Mediator.publish 'god:world-load-progress-changed', event.data Backbone.Mediator.publish 'god:world-load-progress-changed', progress: event.data.progress
unless event.data.progress is 1 or @work.preload or @work.headless or @work.synchronous or @deserializationQueue.length or @shared.firstWorld unless event.data.progress is 1 or @work.preload or @work.headless or @work.synchronous or @deserializationQueue.length or @shared.firstWorld
@worker.postMessage func: 'serializeFramesSoFar' # Stream it! @worker.postMessage func: 'serializeFramesSoFar' # Stream it!

View file

@ -33,7 +33,7 @@ class Media
class AudioPlayer extends CocoClass class AudioPlayer extends CocoClass
subscriptions: subscriptions:
'play-sound': (e) -> @playInterfaceSound e.trigger, e.volume 'audio-player:play-sound': (e) -> @playInterfaceSound e.trigger, e.volume
constructor: () -> constructor: () ->
super() super()
@ -89,8 +89,10 @@ class AudioPlayer extends CocoClass
playSound: (name, volume=1, delay=0, pos=null) -> playSound: (name, volume=1, delay=0, pos=null) ->
audioOptions = {volume: (me.get('volume') ? 1) * volume, delay: delay} audioOptions = {volume: (me.get('volume') ? 1) * volume, delay: delay}
unless @camera is null or pos is null filename = if _.string.startsWith(name, '/file/') then name else '/file/' + name
audioOptions = @applyPanning audioOptions, pos unless (filename of cache) and createjs.Sound.loadComplete filename
@soundsToPlayWhenLoaded[name] = audioOptions.volume
audioOptions = @applyPanning audioOptions, pos if @camera and pos
instance = createjs.Sound.play name, audioOptions instance = createjs.Sound.play name, audioOptions
instance instance

View file

@ -19,11 +19,7 @@ module.exports = Bus = class Bus extends CocoClass
Bus.activeBuses[@docName] = @ Bus.activeBuses[@docName] = @
subscriptions: subscriptions:
'level-bus-echo-states': 'onEchoStates' 'auth:me-synced': 'onMeSynced'
'me:synced': 'onMeSynced'
onEchoStates: ->
@notifyStateChanges()
connect: -> connect: ->
Backbone.Mediator.publish 'bus:connecting', {bus: @} Backbone.Mediator.publish 'bus:connecting', {bus: @}
@ -99,7 +95,7 @@ module.exports = Bus = class Bus extends CocoClass
@onPlayerJoined(snapshot) if player.connected and not wasConnected @onPlayerJoined(snapshot) if player.connected and not wasConnected
Backbone.Mediator.publish('bus:player-states-changed', {states: @players, bus: @}) Backbone.Mediator.publish('bus:player-states-changed', {states: @players, bus: @})
onMeSynced: => onMeSynced: ->
@myConnection?.child('name').set(me.get('name')) @myConnection?.child('name').set(me.get('name'))
countPlayers: -> _.size(@players) countPlayers: -> _.size(@players)

View file

@ -11,7 +11,7 @@ module.exports = [
scriptPrereqs: ["Introduction"] scriptPrereqs: ["Introduction"]
} }
{ {
channel: "level-set-playing" channel: "level:set-playing"
noteChain: [] noteChain: []
scriptPrereqs: ["Victory Playback"] scriptPrereqs: ["Victory Playback"]
id: "Victory Playback Started" id: "Victory Playback Started"

View file

@ -14,10 +14,9 @@ userPropsToSave =
module.exports = FacebookHandler = class FacebookHandler extends CocoClass module.exports = FacebookHandler = class FacebookHandler extends CocoClass
subscriptions: subscriptions:
'facebook-logged-in':'onFacebookLogin' 'auth:logged-in-with-facebook': 'onFacebookLoggedIn'
'facebook-logged-out': 'onFacebookLogout'
onFacebookLogin: (e) => onFacebookLoggedIn: (e) ->
# user is logged in also when the page first loads, so check to see # user is logged in also when the page first loads, so check to see
# if we really need to do the lookup # if we really need to do the lookup
return if not me return if not me
@ -30,9 +29,6 @@ module.exports = FacebookHandler = class FacebookHandler extends CocoClass
break break
FB.api('/me', @onReceiveMeInfo) if doIt FB.api('/me', @onReceiveMeInfo) if doIt
onFacebookLogout: (e) =>
console.warn('On facebook logout not implemented.')
onReceiveMeInfo: (r) => onReceiveMeInfo: (r) =>
unless r.email unless r.email
console.error('could not get data, since no email provided') console.error('could not get data, since no email provided')
@ -45,7 +41,7 @@ module.exports = FacebookHandler = class FacebookHandler extends CocoClass
me.set('email', r.email) if r.email me.set('email', r.email) if r.email
me.set('facebookID', r.id) if r.id me.set('facebookID', r.id) if r.id
Backbone.Mediator.publish('logging-in-with-facebook') Backbone.Mediator.publish 'auth:logging-in-with-facebook', {}
window.tracker?.trackEvent 'Facebook Login' window.tracker?.trackEvent 'Facebook Login'
window.tracker?.identify() window.tracker?.identify()
me.patch({ me.patch({

View file

@ -23,8 +23,8 @@ module.exports = GPlusHandler = class GPlusHandler extends CocoClass
super() super()
subscriptions: subscriptions:
'gplus-logged-in':'onGPlusLogin' 'auth:logged-in-with-gplus':'onGPlusLogin'
'gapi-loaded':'onGPlusLoaded' 'auth:gplus-api-loaded':'onGPlusLoaded'
onGPlusLoaded: -> onGPlusLoaded: ->
session_state = null session_state = null
@ -88,7 +88,7 @@ module.exports = GPlusHandler = class GPlusHandler extends CocoClass
return unless @responsesComplete is 2 return unless @responsesComplete is 2
return unless me.get('email') and me.get('gplusID') return unless me.get('email') and me.get('gplusID')
Backbone.Mediator.publish('logging-in-with-gplus') Backbone.Mediator.publish 'auth:logging-in-with-gplus', {}
gplusID = me.get('gplusID') gplusID = me.get('gplusID')
window.tracker?.trackEvent 'Google Login' window.tracker?.trackEvent 'Google Login'
window.tracker?.identify() window.tracker?.identify()

View file

@ -6,14 +6,14 @@ module.exports = class GitHubHandler extends CocoClass
scopes: 'user:email' scopes: 'user:email'
subscriptions: subscriptions:
'github-login': 'commenceGitHubLogin' 'auth:log-in-with-github': 'commenceGitHubLogin'
constructor: -> constructor: ->
super arguments... super arguments...
@clientID = if application.isProduction() then '9b405bf5fb84590d1f02' else 'fd5c9d34eb171131bc87' @clientID = if application.isProduction() then '9b405bf5fb84590d1f02' else 'fd5c9d34eb171131bc87'
@redirectURI = if application.isProduction() then 'http://codecombat.com/github/auth_callback' else 'http://localhost:3000/github/auth_callback' @redirectURI = if application.isProduction() then 'http://codecombat.com/github/auth_callback' else 'http://localhost:3000/github/auth_callback'
commenceGitHubLogin: -> commenceGitHubLogin: (e) ->
request = request =
scope: @scopes scope: @scopes
client_id: @clientID client_id: @clientID

View file

@ -127,7 +127,7 @@ module.exports = class God extends CocoClass
when 'debug-value-return' when 'debug-value-return'
Backbone.Mediator.publish 'god:debug-value-return', event.data.serialized Backbone.Mediator.publish 'god:debug-value-return', event.data.serialized
when 'debug-world-load-progress-changed' when 'debug-world-load-progress-changed'
Backbone.Mediator.publish 'god:debug-world-load-progress-changed', event.data Backbone.Mediator.publish 'god:debug-world-load-progress-changed', progress: event.data.progress
onNewWorldCreated: (e) -> onNewWorldCreated: (e) ->
@currentUserCodeMap = @filterUserCodeMapWhenFromWorld e.world.userCodeMap @currentUserCodeMap = @filterUserCodeMapWhenFromWorld e.world.userCodeMap

View file

@ -11,6 +11,7 @@ module.exports = class LevelBus extends Bus
subscriptions: subscriptions:
'self-wizard:target-changed': 'onSelfWizardTargetChanged' 'self-wizard:target-changed': 'onSelfWizardTargetChanged'
'self-wizard:created': 'onSelfWizardCreated'
'tome:editing-began': 'onEditingBegan' 'tome:editing-began': 'onEditingBegan'
'tome:editing-ended': 'onEditingEnded' 'tome:editing-ended': 'onEditingEnded'
'script:state-changed': 'onScriptStateChanged' 'script:state-changed': 'onScriptStateChanged'
@ -18,8 +19,8 @@ module.exports = class LevelBus extends Bus
'script:reset': 'onScriptReset' 'script:reset': 'onScriptReset'
'surface:frame-changed': 'onFrameChanged' 'surface:frame-changed': 'onFrameChanged'
'surface:sprite-selected': 'onSpriteSelected' 'surface:sprite-selected': 'onSpriteSelected'
'level-set-playing': 'onSetPlaying' 'level:set-playing': 'onSetPlaying'
'level-show-victory': 'onVictory' 'level:show-victory': 'onVictory'
'tome:spell-changed': 'onSpellChanged' 'tome:spell-changed': 'onSpellChanged'
'tome:spell-created': 'onSpellCreated' 'tome:spell-created': 'onSpellCreated'
'application:idle-changed': 'onIdleChanged' 'application:idle-changed': 'onIdleChanged'
@ -51,10 +52,12 @@ module.exports = class LevelBus extends Bus
return true unless @session?.get('multiplayer') return true unless @session?.get('multiplayer')
super() super()
onSelfWizardTargetChanged: => onSelfWizardCreated: (e) ->
wizardSprite = @getSelfWizard() @selfWizardSprite = e.sprite
@wizardRef?.child('targetPos').set(wizardSprite?.targetPos or null)
@wizardRef?.child('targetSprite').set(wizardSprite?.targetSprite?.thang.id or null) onSelfWizardTargetChanged: (e) ->
@wizardRef?.child('targetPos').set(@selfWizardSprite?.targetPos or null)
@wizardRef?.child('targetSprite').set(@selfWizardSprite?.targetSprite?.thang.id or null)
onMeSynced: => onMeSynced: =>
super() super()
@ -63,9 +66,8 @@ module.exports = class LevelBus extends Bus
join: -> join: ->
super() super()
@wizardRef = @myConnection.child('wizard') @wizardRef = @myConnection.child('wizard')
wizardSprite = @getSelfWizard() @wizardRef?.child('targetPos').set(@selfWizardSprite?.targetPos or null)
@wizardRef?.child('targetPos').set(wizardSprite?.targetPos or null) @wizardRef?.child('targetSprite').set(@selfWizardSprite?.targetSprite?.thang.id or null)
@wizardRef?.child('targetSprite').set(wizardSprite?.targetSprite?.thang.id or null)
@wizardRef?.child('wizardColor1').set(me.get('wizardColor1') or 0.0) @wizardRef?.child('wizardColor1').set(me.get('wizardColor1') or 0.0)
disconnect: -> disconnect: ->
@ -81,11 +83,6 @@ module.exports = class LevelBus extends Bus
@fireRef.remove() @fireRef.remove()
@onDisconnect.cancel(-> callback?()) @onDisconnect.cancel(-> callback?())
getSelfWizard: ->
e = {}
Backbone.Mediator.publish('echo-self-wizard-sprite', e)
return e.payload
# UPDATING FIREBASE AND SESSION # UPDATING FIREBASE AND SESSION
onEditingBegan: -> @wizardRef?.child('editing').set(true) onEditingBegan: -> @wizardRef?.child('editing').set(true)
@ -125,7 +122,8 @@ module.exports = class LevelBus extends Bus
@changedSessionProperties.teamSpells = true @changedSessionProperties.teamSpells = true
@session.set({'teamSpells': @teamSpellMap}) @session.set({'teamSpells': @teamSpellMap})
@saveSession() @saveSession()
if spellTeam is me.team or spellTeam is 'common' if spellTeam is me.team or (e.spell.otherSession and spellTeam isnt e.spell.otherSession.get('team'))
# https://github.com/codecombat/codecombat/issues/81
@onSpellChanged e # Save the new spell to the session, too. @onSpellChanged e # Save the new spell to the session, too.
onScriptStateChanged: (e) -> onScriptStateChanged: (e) ->

View file

@ -9,7 +9,7 @@ module.exports = LinkedInHandler = class LinkedInHandler extends CocoClass
super() super()
subscriptions: subscriptions:
'linkedin-loaded': 'onLinkedInLoaded' 'auth:linkedin-api-loaded': 'onLinkedInLoaded'
onLinkedInLoaded: (e) -> onLinkedInLoaded: (e) ->
IN.Event.on IN, 'auth', @onLinkedInAuth IN.Event.on IN, 'auth', @onLinkedInAuth

View file

@ -12,7 +12,7 @@ init = ->
me.set 'testGroupNumber', Math.floor(Math.random() * 256) me.set 'testGroupNumber', Math.floor(Math.random() * 256)
me.patch() me.patch()
Backbone.listenTo(me, 'sync', -> Backbone.Mediator.publish('me:synced', {me: me})) Backbone.listenTo me, 'sync', -> Backbone.Mediator.publish('auth:me-synced', me: me)
module.exports.createUser = (userObject, failure=backboneFailure, nextURL=null) -> module.exports.createUser = (userObject, failure=backboneFailure, nextURL=null) ->
user = new User(userObject) user = new User(userObject)
@ -57,7 +57,7 @@ onSetVolume = (e) ->
me.set('volume', e.volume) me.set('volume', e.volume)
me.save() me.save()
Backbone.Mediator.subscribe('level-set-volume', onSetVolume, module.exports) Backbone.Mediator.subscribe('level:set-volume', onSetVolume, module.exports)
trackFirstArrival = -> trackFirstArrival = ->
# will have to filter out users who log in with existing accounts separately # will have to filter out users who log in with existing accounts separately

View file

@ -15,8 +15,8 @@ module.exports = class DOMScriptModule extends ScriptModule
endNotes: -> endNotes: ->
notes = [] notes = []
notes.push({'channel': 'end-level-highlight-dom'}) if @noteGroup.dom.highlight? notes.push({'channel': 'level:end-highlight-dom'}) if @noteGroup.dom.highlight?
notes.push({'channel': 'level-enable-controls'}) if @noteGroup.dom.lock? notes.push({'channel': 'level:enable-controls'}) if @noteGroup.dom.lock?
return notes return notes
skipNotes: -> skipNotes: ->
@ -28,7 +28,7 @@ module.exports = class DOMScriptModule extends ScriptModule
highlightNote: -> highlightNote: ->
dom = @noteGroup.dom dom = @noteGroup.dom
note = note =
channel: 'level-highlight-dom' channel: 'level:highlight-dom'
event: event:
selector: dom.highlight.target selector: dom.highlight.target
delay: dom.highlight.delay delay: dom.highlight.delay
@ -41,7 +41,7 @@ module.exports = class DOMScriptModule extends ScriptModule
focusNote: -> focusNote: ->
note = note =
channel: 'level-focus-dom' channel: 'level:focus-dom'
event: event:
selector: @noteGroup.dom.focus selector: @noteGroup.dom.focus
note note
@ -51,7 +51,7 @@ module.exports = class DOMScriptModule extends ScriptModule
e.showModal = @noteGroup.dom.showVictory in [true, 'Done Button And Modal'] e.showModal = @noteGroup.dom.showVictory in [true, 'Done Button And Modal']
e.showModal = showModal if showModal? e.showModal = showModal if showModal?
note = note =
channel: 'level-show-victory' channel: 'level:show-victory'
event: e event: e
note note
@ -59,8 +59,8 @@ module.exports = class DOMScriptModule extends ScriptModule
event = {} event = {}
lock = @noteGroup.dom.lock lock = @noteGroup.dom.lock
event.controls = lock if _.isArray lock # array: subset of controls event.controls = lock if _.isArray lock # array: subset of controls
channel = if lock then 'level-disable-controls' else 'level-enable-controls' channel = if lock then 'level:disable-controls' else 'level:enable-controls'
return {channel: channel, event: event} return {channel: channel, event: event}
letterboxNote: -> letterboxNote: ->
return {channel: 'level-set-letterbox', event: {on: @noteGroup.dom.letterbox}} return {channel: 'level:set-letterbox', event: {on: @noteGroup.dom.letterbox}}

View file

@ -1,31 +0,0 @@
ScriptModule = require './ScriptModule'
module.exports = class GoalsScriptModule extends ScriptModule
@neededFor: (noteGroup) ->
return noteGroup.goals?
startNotes: ->
notes = []
notes.push(@addNote()) if @noteGroup.goals.add?
notes.push(@removeNote()) if @noteGroup.goals.remove?
return notes
endNotes: ->
return []
skipNotes: ->
return @startNotes()
addNote: ->
note =
channel: 'level-add-goals'
event:
goals: @noteGroup.goals.add
return note
removeNote: ->
note =
channel: 'level-remove-goals'
event:
goals: @noteGroup.goals.remove
return note

View file

@ -25,18 +25,17 @@ module.exports = class PlaybackScriptModule extends ScriptModule
playingNote: -> playingNote: ->
note = note =
channel: 'level-set-playing' channel: 'level:set-playing'
event: {playing: @noteGroup.playback.playing} event: {playing: @noteGroup.playback.playing}
return note return note
scrubNote: (instant=false) -> scrubNote: (instant=false) ->
scrub = @noteGroup.playback.scrub scrub = @noteGroup.playback.scrub
note = note =
channel: 'level-set-time' channel: 'level:set-time'
event: event:
frameOffset: scrub.frameOffset or 2 frameOffset: scrub.frameOffset or 2
scrubDuration: if instant then 0 else scrub.duration scrubDuration: if instant then 0 else scrub.duration
note.event.time = scrub.toTime if scrub.toTime? note.event.time = scrub.toTime if scrub.toTime?
note.event.ratio = scrub.toRatio if scrub.toRatio? note.event.ratio = scrub.toRatio if scrub.toRatio?
return note return note

View file

@ -1,6 +1,3 @@
# * search for how various places handle or call 'end-current-script' event
CocoClass = require 'lib/CocoClass' CocoClass = require 'lib/CocoClass'
CocoView = require 'views/kinds/CocoView' CocoView = require 'views/kinds/CocoView'
{scriptMatchesEventPrereqs} = require './../world/script_event_prereqs' {scriptMatchesEventPrereqs} = require './../world/script_event_prereqs'
@ -10,8 +7,6 @@ allScriptModules.push(require './SpriteScriptModule')
allScriptModules.push(require './DOMScriptModule') allScriptModules.push(require './DOMScriptModule')
allScriptModules.push(require './SurfaceScriptModule') allScriptModules.push(require './SurfaceScriptModule')
allScriptModules.push(require './PlaybackScriptModule') allScriptModules.push(require './PlaybackScriptModule')
GoalScriptsModule = require './GoalsScriptModule'
allScriptModules.push(GoalScriptsModule)
allScriptModules.push(require './SoundScriptModule') allScriptModules.push(require './SoundScriptModule')
@ -32,16 +27,15 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
originalScripts: [] # use these later when you want to revert to an original state originalScripts: [] # use these later when you want to revert to an original state
subscriptions: subscriptions:
'end-current-script': 'onEndNoteGroup' 'script:end-current-script': 'onEndNoteGroup'
'end-all-scripts': 'onEndAll'
'level:started': -> @setWorldLoading(false) 'level:started': -> @setWorldLoading(false)
'level:restarted': 'onLevelRestarted' 'level:restarted': 'onLevelRestarted'
'level:shift-space-pressed': 'onEndNoteGroup' 'level:shift-space-pressed': 'onEndNoteGroup'
'level:escape-pressed': 'onEndAll' 'level:escape-pressed': 'onEndAll'
shortcuts: shortcuts:
'⇧+space, space, enter': -> Backbone.Mediator.publish 'level:shift-space-pressed' '⇧+space, space, enter': -> Backbone.Mediator.publish 'level:shift-space-pressed', {}
'escape': -> Backbone.Mediator.publish 'level:escape-pressed' 'escape': -> Backbone.Mediator.publish 'level:escape-pressed', {}
# SETUP / TEARDOWN # SETUP / TEARDOWN
@ -94,13 +88,14 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
scriptStates: scriptStates scriptStates: scriptStates
timeSinceLastScriptEnded: (if @lastScriptEnded then now - @lastScriptEnded else 0) / 1000 timeSinceLastScriptEnded: (if @lastScriptEnded then now - @lastScriptEnded else 0) / 1000
Backbone.Mediator.publish 'script-manager:tick', stateEvent Backbone.Mediator.publish 'script:tick', stateEvent # Is this even needed?
loadFromSession: -> loadFromSession: ->
# load the queue with note groups to skip through # load the queue with note groups to skip through
@addEndedScriptsFromSession() @addEndedScriptsFromSession()
@addPartiallyEndedScriptFromSession() @addPartiallyEndedScriptFromSession()
@fireGoalNotesEarly() for noteGroup in @noteGroupQueue
@processNoteGroup(noteGroup)
addPartiallyEndedScriptFromSession: -> addPartiallyEndedScriptFromSession: ->
scripts = @session.get('state').scripts scripts = @session.get('state').scripts
@ -133,14 +128,6 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
noteGroup.skipMe = true for noteGroup in noteChain noteGroup.skipMe = true for noteGroup in noteChain
@addNoteChain(noteChain, false) @addNoteChain(noteChain, false)
fireGoalNotesEarly: ->
for noteGroup in @noteGroupQueue
@processNoteGroup(noteGroup)
for module in noteGroup.modules
if module instanceof GoalScriptsModule
notes = module.skipNotes()
@processNote(note, noteGroup) for note in notes
setWorldLoading: (@worldLoading) -> setWorldLoading: (@worldLoading) ->
@run() unless @worldLoading @run() unless @worldLoading
@ -238,7 +225,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
if nextNoteGroup.script.duration if nextNoteGroup.script.duration
f = => @onNoteGroupTimeout? nextNoteGroup f = => @onNoteGroupTimeout? nextNoteGroup
setTimeout(f, nextNoteGroup.script.duration) setTimeout(f, nextNoteGroup.script.duration)
Backbone.Mediator.publish('note-group-started') Backbone.Mediator.publish 'script:note-group-started', {}
skipAhead: -> skipAhead: ->
return if @worldLoading return if @worldLoading
@ -270,7 +257,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
publishNote: (note) -> publishNote: (note) ->
Backbone.Mediator.publish 'playback:real-time-playback-ended', {} Backbone.Mediator.publish 'playback:real-time-playback-ended', {}
Backbone.Mediator.publish(note.channel, note.event) Backbone.Mediator.publish note.channel, note.event ? {}
# ENDING NOTES # ENDING NOTES
@ -279,7 +266,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
@endAll({force:true}) @endAll({force:true})
@initProperties() @initProperties()
@resetThings() @resetThings()
Backbone.Mediator.publish 'script:reset' Backbone.Mediator.publish 'script:reset', {}
@quiet = false @quiet = false
@run() @run()
@ -298,7 +285,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
clearTimeout(timeout) for timeout in @currentTimeouts clearTimeout(timeout) for timeout in @currentTimeouts
for module in @currentNoteGroup.modules for module in @currentNoteGroup.modules
@processNote(note, @currentNoteGroup) for note in module.endNotes() @processNote(note, @currentNoteGroup) for note in module.endNotes()
Backbone.Mediator.publish 'note-group-ended' unless @quiet Backbone.Mediator.publish 'script:note-group-ended' unless @quiet
@scriptInProgress = false @scriptInProgress = false
@trackScriptCompletionsFromNoteGroup(@currentNoteGroup) @trackScriptCompletionsFromNoteGroup(@currentNoteGroup)
@currentNoteGroup = null @currentNoteGroup = null
@ -307,8 +294,8 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
@resetThings() @resetThings()
@ending = false @ending = false
onEndAll: -> onEndAll: (e) ->
# press escape # Escape was pressed.
@endAll() @endAll()
endAll: (options) -> endAll: (options) ->
@ -341,8 +328,8 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
@run() @run()
resetThings: -> resetThings: ->
Backbone.Mediator.publish 'level-enable-controls', {} Backbone.Mediator.publish 'level:enable-controls', {}
Backbone.Mediator.publish 'level-set-letterbox', { on: false } Backbone.Mediator.publish 'level:set-letterbox', { on: false }
trackScriptCompletionsFromNoteGroup: (noteGroup) -> trackScriptCompletionsFromNoteGroup: (noteGroup) ->
return unless noteGroup.isLast return unless noteGroup.isLast

View file

@ -23,12 +23,12 @@ module.exports = class SoundScriptModule extends ScriptModule
addSuppressSelectionSoundsNote: -> addSuppressSelectionSoundsNote: ->
note = note =
channel: 'level-suppress-selection-sounds' channel: 'level:suppress-selection-sounds'
event: {suppress: @noteGroup.sound.suppressSelectionSounds} event: {suppress: @noteGroup.sound.suppressSelectionSounds}
return note return note
addMusicNote: -> addMusicNote: ->
note = note =
channel: 'level-play-music' channel: 'music-player:play-music'
event: @noteGroup.sound.music event: @noteGroup.sound.music
return note return note

View file

@ -20,7 +20,7 @@ module.exports = class SpritesScriptModule extends ScriptModule
spriteMoveNote: (sprite, instant=false) -> spriteMoveNote: (sprite, instant=false) ->
duration = if instant then 0 else sprite.move.duration duration = if instant then 0 else sprite.move.duration
note = note =
channel: 'level-sprite-move' channel: 'sprite:move'
event: event:
pos: sprite.move.target pos: sprite.move.target
duration: duration duration: duration
@ -41,7 +41,7 @@ module.exports = class SpritesScriptModule extends ScriptModule
blurb = utils.i18n sprite.say, 'blurb' blurb = utils.i18n sprite.say, 'blurb'
sound = sprite.say.sound # TODO support sound i18n sound = sprite.say.sound # TODO support sound i18n
note = note =
channel: 'level-sprite-dialogue' channel: 'level:sprite-dialogue'
event: event:
message: text message: text
blurb: blurb blurb: blurb
@ -54,7 +54,7 @@ module.exports = class SpritesScriptModule extends ScriptModule
spriteSelectNote: (sprite) -> spriteSelectNote: (sprite) ->
note = note =
channel: 'level-select-sprite' channel: 'level:select-sprite'
event: event:
thangID: if sprite.select then sprite.id else null thangID: if sprite.select then sprite.id else null
return note return note
@ -64,7 +64,7 @@ module.exports = class SpritesScriptModule extends ScriptModule
for sprite in @noteGroup.sprites or [] for sprite in @noteGroup.sprites or []
notes[sprite.id] ?= {} notes[sprite.id] ?= {}
notes[sprite.id]['move'] = (@spriteMoveNote sprite, true) if sprite.move? notes[sprite.id]['move'] = (@spriteMoveNote sprite, true) if sprite.move?
notes[sprite.id]['say'] = { channel: 'level-sprite-clear-dialogue' } if sprite.say? notes[sprite.id]['say'] = { channel: 'level:sprite-clear-dialogue' } if sprite.say?
noteArray = [] noteArray = []
for spriteID of notes for spriteID of notes
for type of notes[spriteID] for type of notes[spriteID]

View file

@ -13,7 +13,7 @@ module.exports = class SurfaceScriptModule extends ScriptModule
endNotes: -> endNotes: ->
notes = [] notes = []
notes.push({channel:'level-highlight-sprites', event: {thangIDs: []}}) if @noteGroup.surface.highlight? notes.push({channel:'sprite:highlight-sprites', event: {thangIDs: []}}) if @noteGroup.surface.highlight?
notes.push(@surfaceCameraNote(true)) if @noteGroup.surface.focus? notes.push(@surfaceCameraNote(true)) if @noteGroup.surface.focus?
notes.push(@surfaceLockSelectNote()) if @noteGroup.surface.lockSelect? notes.push(@surfaceLockSelectNote()) if @noteGroup.surface.lockSelect?
return notes return notes
@ -33,12 +33,12 @@ module.exports = class SurfaceScriptModule extends ScriptModule
e.duration = if focus.duration? then focus.duration else 1500 e.duration = if focus.duration? then focus.duration else 1500
e.duration = 0 if instant e.duration = 0 if instant
e.bounds = focus.bounds if focus.bounds? e.bounds = focus.bounds if focus.bounds?
return { channel: 'level-set-surface-camera', event: e } return { channel: 'camera:set-camera', event: e }
surfaceHighlightNote: -> surfaceHighlightNote: ->
highlight = @noteGroup.surface.highlight highlight = @noteGroup.surface.highlight
note = note =
channel: 'level-highlight-sprites' channel: 'sprite:highlight-sprites'
event: event:
thangIDs: highlight.targets thangIDs: highlight.targets
delay: highlight.delay delay: highlight.delay
@ -46,4 +46,4 @@ module.exports = class SurfaceScriptModule extends ScriptModule
return note return note
surfaceLockSelectNote: -> surfaceLockSelectNote: ->
return { channel: 'level-lock-select', event: {lock: @noteGroup.surface.lockSelect} } return { channel: 'level:lock-select', event: {lock: @noteGroup.surface.lockSelect} }

View file

@ -8,7 +8,7 @@ module.exports = initializeFacebook = ->
cookie: true # enable cookies to allow the server to access the session cookie: true # enable cookies to allow the server to access the session
xfbml: true # parse XFBML xfbml: true # parse XFBML
Backbone.Mediator.publish 'fbapi-loaded' Backbone.Mediator.publish 'auth:facebook-api-loaded', {}
# This is fired for any auth related change, such as login, logout or session refresh. # This is fired for any auth related change, such as login, logout or session refresh.
FB.Event.subscribe 'auth.authResponseChange', (response) -> FB.Event.subscribe 'auth.authResponseChange', (response) ->
@ -17,8 +17,7 @@ module.exports = initializeFacebook = ->
if response.status is 'connected' if response.status is 'connected'
# They have logged in to the app. # They have logged in to the app.
Backbone.Mediator.publish 'facebook-logged-in', Backbone.Mediator.publish 'facebook-logged-in', response: response
response: response
else if response.status is 'not_authorized' else if response.status is 'not_authorized'
# #

View file

@ -1,9 +1,9 @@
module.exports = initializeGoogle = -> module.exports = initializeGoogle = ->
window.onGPlusLoaded = -> window.onGPlusLoaded = ->
Backbone.Mediator.publish 'gapi-loaded' Backbone.Mediator.publish 'auth:gplus-api-loaded', {}
return return
window.signinCallback = (authResult) -> window.signinCallback = (authResult) ->
Backbone.Mediator.publish 'gplus-logged-in', authResult if authResult['access_token'] Backbone.Mediator.publish 'auth:logged-in-with-gplus', authResult if authResult.access_token
return return
(-> (->
po = document.createElement('script') po = document.createElement('script')

View file

@ -1,7 +1,7 @@
module.exports = initializeLinkedIn = -> module.exports = initializeLinkedIn = ->
window.linkedInAsyncInit = -> window.linkedInAsyncInit = ->
#console.log 'Linkedin async init success!' #console.log 'Linkedin async init success!'
Backbone.Mediator.publish 'linkedin-loaded' Backbone.Mediator.publish 'auth:linkedin-api-loaded', {}
linkedInSnippet = linkedInSnippet =
'' ''

View file

@ -40,9 +40,9 @@ module.exports = class Camera extends CocoClass
# INIT # INIT
subscriptions: subscriptions:
'camera-zoom-in': 'onZoomIn' 'camera:zoom-in': 'onZoomIn'
'camera-zoom-out': 'onZoomOut' 'camera:zoom-out': 'onZoomOut'
'camera-zoom-to': 'onZoomTo' 'camera:zoom-to': 'onZoomTo'
'level:restarted': 'onLevelRestarted' 'level:restarted': 'onLevelRestarted'
'surface:mouse-scrolled': 'onMouseScrolled' 'surface:mouse-scrolled': 'onMouseScrolled'
'sprite:mouse-down': 'onMouseDown' 'sprite:mouse-down': 'onMouseDown'
@ -187,7 +187,7 @@ module.exports = class Camera extends CocoClass
y: target.y + (@lastPos.y - e.originalEvent.rawY) / @zoom y: target.y + (@lastPos.y - e.originalEvent.rawY) / @zoom
@zoomTo newPos, @zoom, 0 @zoomTo newPos, @zoom, 0
@lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY} @lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY}
Backbone.Mediator.publish 'camera:dragged' Backbone.Mediator.publish 'camera:dragged', {}
onLevelRestarted: -> onLevelRestarted: ->
@setBounds(@firstBounds, false) @setBounds(@firstBounds, false)
@ -322,5 +322,5 @@ module.exports = class Camera extends CocoClass
createjs.Tween.removeTweens @ createjs.Tween.removeTweens @
super() super()
onZoomTo: (pos, time) -> onZoomTo: (e) ->
@zoomTo @worldToSurface(pos), @zoom, time @zoomTo @worldToSurface(e.pos), @zoom, e.duration

View file

@ -57,11 +57,11 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
currentAction: null # related action that is right now playing currentAction: null # related action that is right now playing
subscriptions: subscriptions:
'level-sprite-dialogue': 'onDialogue' 'level:sprite-dialogue': 'onDialogue'
'level-sprite-clear-dialogue': 'onClearDialogue' 'level:sprite-clear-dialogue': 'onClearDialogue'
'level-set-letterbox': 'onSetLetterbox' 'level:set-letterbox': 'onSetLetterbox'
'surface:ticked': 'onSurfaceTicked' 'surface:ticked': 'onSurfaceTicked'
'level-sprite-move': 'onMove' 'sprite:move': 'onMove'
constructor: (@thangType, options) -> constructor: (@thangType, options) ->
super() super()
@ -519,9 +519,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@imageObject.on 'pressmove', @onMouseEvent, @, false, 'sprite:dragged' @imageObject.on 'pressmove', @onMouseEvent, @, false, 'sprite:dragged'
@imageObject.on 'pressup', @onMouseEvent, @, false, 'sprite:mouse-up' @imageObject.on 'pressup', @onMouseEvent, @, false, 'sprite:mouse-up'
onSetLetterbox: (e) ->
@letterboxOn = e.on
onMouseEvent: (e, ourEventName) -> onMouseEvent: (e, ourEventName) ->
return if @letterboxOn or not @imageObject return if @letterboxOn or not @imageObject
p = @imageObject p = @imageObject
@ -678,16 +675,19 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
label = @addLabel 'dialogue', Label.STYLE_DIALOGUE label = @addLabel 'dialogue', Label.STYLE_DIALOGUE
label.setText e.blurb or '...' label.setText e.blurb or '...'
sound = e.sound ? AudioPlayer.soundForDialogue e.message, @thangType.get 'soundTriggers' sound = e.sound ? AudioPlayer.soundForDialogue e.message, @thangType.get 'soundTriggers'
@instance?.stop() @dialogueSoundInstance?.stop()
if @instance = @playSound sound, false if @dialogueSoundInstance = @playSound sound, false
@instance.addEventListener 'complete', -> Backbone.Mediator.publish 'dialogue-sound-completed' @dialogueSoundInstance.addEventListener 'complete', -> Backbone.Mediator.publish 'sprite:dialogue-sound-completed', {}
@notifySpeechUpdated e @notifySpeechUpdated e
onClearDialogue: (e) -> onClearDialogue: (e) ->
@labels.dialogue?.setText null @labels.dialogue?.setText null
@instance?.stop() @dialogueSoundInstance?.stop()
@notifySpeechUpdated {} @notifySpeechUpdated {}
onSetLetterbox: (e) ->
@letterboxOn = e.on
setNameLabel: (name) -> setNameLabel: (name) ->
label = @addLabel 'name', Label.STYLE_NAME label = @addLabel 'name', Label.STYLE_NAME
label.setText name label.setText name
@ -733,6 +733,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
return null unless sound return null unless sound
delay = if withDelay and sound.delay then 1000 * sound.delay / createjs.Ticker.getFPS() else 0 delay = if withDelay and sound.delay then 1000 * sound.delay / createjs.Ticker.getFPS() else 0
name = AudioPlayer.nameForSoundReference sound name = AudioPlayer.nameForSoundReference sound
AudioPlayer.preloadSoundReference sound
instance = AudioPlayer.playSound name, volume, delay, @getWorldPosition() instance = AudioPlayer.playSound name, volume, delay, @getWorldPosition()
#console.log @thang?.id, 'played sound', name, 'with delay', delay, 'volume', volume, 'and got sound instance', instance #console.log @thang?.id, 'played sound', name, 'with delay', delay, 'volume', volume, 'and got sound instance', instance
instance instance
@ -749,7 +750,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
distance = @thang.pos.distance target.pos distance = @thang.pos.distance target.pos
offset = Math.max(target.width, target.height, 2) / 2 + 3 offset = Math.max(target.width, target.height, 2) / 2 + 3
pos = Vector.add(@thang.pos, heading.multiply(distance - offset)) pos = Vector.add(@thang.pos, heading.multiply(distance - offset))
Backbone.Mediator.publish 'level-sprite-clear-dialogue', {} Backbone.Mediator.publish 'level:sprite-clear-dialogue', {}
@onClearDialogue() @onClearDialogue()
args = [pos] args = [pos]
args.push(e.duration) if e.duration? args.push(e.duration) if e.duration?

View file

@ -11,7 +11,9 @@ module.exports = class CoordinateDisplay extends createjs.Container
super() super()
@initialize() @initialize()
@camera = options.camera @camera = options.camera
console.error 'CoordinateDisplay needs camera.' unless @camera @layer = options.layer
console.error @toString(), 'needs a camera.' unless @camera
console.error @toString(), 'needs a layer.' unless @layer
@build() @build()
@show = _.debounce @show, 125 @show = _.debounce @show, 125
Backbone.Mediator.subscribe(channel, @[func], @) for channel, func of @subscriptions Backbone.Mediator.subscribe(channel, @[func], @) for channel, func of @subscriptions
@ -21,6 +23,8 @@ module.exports = class CoordinateDisplay extends createjs.Container
@show = null @show = null
@destroyed = true @destroyed = true
toString: -> '<CoordinateDisplay>'
build: -> build: ->
@mouseEnabled = @mouseChildren = false @mouseEnabled = @mouseChildren = false
@addChild @background = new createjs.Shape() @addChild @background = new createjs.Shape()
@ -30,6 +34,7 @@ module.exports = class CoordinateDisplay extends createjs.Container
@label.shadow = new createjs.Shadow('#000000', 1, 1, 0) @label.shadow = new createjs.Shadow('#000000', 1, 1, 0)
@background.name = 'Coordinate Display Background' @background.name = 'Coordinate Display Background'
@pointMarker.name = 'Point Marker' @pointMarker.name = 'Point Marker'
@layer.addChild @
onMouseOver: (e) -> @mouseInBounds = true onMouseOver: (e) -> @mouseInBounds = true
onMouseOut: (e) -> @mouseInBounds = false onMouseOut: (e) -> @mouseInBounds = false

View file

@ -0,0 +1,94 @@
CocoClass = require 'lib/CocoClass'
module.exports = class CoordinateGrid extends CocoClass
subscriptions:
'level:toggle-grid': 'onToggleGrid'
shortcuts:
'ctrl+g, ⌘+g': 'onToggleGrid'
constructor: (options, worldSize) ->
super()
options ?= {}
@camera = options.camera
@layer = options.layer
@textLayer = options.textLayer
console.error @toString(), 'needs a camera.' unless @camera
console.error @toString(), 'needs a layer.' unless @layer
console.error @toString(), 'needs a textLayer.' unless @textLayer
@build worldSize
destroy: ->
super()
toString: -> '<CoordinateGrid>'
build: (worldSize) ->
worldWidth = worldSize[0] ? 80
worldHeight = worldSize[1] ? 68
@gridContainer = new createjs.Container()
@gridShape = new createjs.Shape()
@gridContainer.addChild @gridShape
@gridContainer.mouseEnabled = false
@gridShape.alpha = 0.125
@gridShape.graphics.setStrokeStyle 1
@gridShape.graphics.beginStroke 'blue'
gridSize = Math.round(worldWidth / 20)
wopStart = x: 0, y: 0
wopEnd = x: worldWidth, y: worldHeight
supStart = @camera.worldToSurface wopStart
supEnd = @camera.worldToSurface wopEnd
wop = x: wopStart.x, y: wopStart.y
@labels = []
linesDrawn = 0
while wop.x <= wopEnd.x
sup = @camera.worldToSurface wop
@gridShape.graphics.mt(sup.x, supStart.y).lt(sup.x, supEnd.y)
if ++linesDrawn % 2
t = new createjs.Text(wop.x.toFixed(0), '16px Arial', 'blue')
t.textAlign = 'center'
t.textBaseline = 'bottom'
t.x = sup.x
t.y = supStart.y
t.alpha = 0.75
@labels.push t
wop.x += gridSize
if wopEnd.x < wop.x <= wopEnd.x - gridSize / 2
wop.x = wopEnd.x
linesDrawn = 0
while wop.y <= wopEnd.y
sup = @camera.worldToSurface wop
@gridShape.graphics.mt(supStart.x, sup.y).lt(supEnd.x, sup.y)
if ++linesDrawn % 2
t = new createjs.Text(wop.y.toFixed(0), '16px Arial', 'blue')
t.textAlign = 'left'
t.textBaseline = 'middle'
t.x = 0
t.y = sup.y
t.alpha = 0.75
@labels.push t
wop.y += gridSize
if wopEnd.y < wop.y <= wopEnd.y - gridSize / 2
wop.y = wopEnd.y
@gridShape.graphics.endStroke()
bounds = x: supStart.x, y: supEnd.y, width: supEnd.x - supStart.x, height: supStart.y - supEnd.y
return unless bounds?.width and bounds.height
@gridContainer.cache bounds.x, bounds.y, bounds.width, bounds.height
showGrid: ->
return if @gridShowing()
@layer.addChild @gridContainer
@textLayer.addChild label for label in @labels
hideGrid: ->
return unless @gridShowing()
@layer.removeChild @gridContainer
@textLayer.removeChild label for label in @labels
gridShowing: ->
@gridContainer?.parent?
onToggleGrid: (e) ->
e?.preventDefault?()
if @gridShowing() then @hideGrid() else @showGrid()

View file

@ -1,7 +1,7 @@
module.exports = class DebugDisplay extends createjs.Container module.exports = class DebugDisplay extends createjs.Container
layerPriority: 20 layerPriority: 20
subscriptions: subscriptions:
'level-set-debug': 'onSetDebug' 'level:set-debug': 'onSetDebug'
constructor: (options) -> constructor: (options) ->
super() super()

View file

@ -2,9 +2,9 @@ CocoClass = require 'lib/CocoClass'
module.exports = class Dimmer extends CocoClass module.exports = class Dimmer extends CocoClass
subscriptions: subscriptions:
'level-disable-controls': 'onDisableControls' 'level:disable-controls': 'onDisableControls'
'level-enable-controls': 'onEnableControls' 'level:enable-controls': 'onEnableControls'
'level-highlight-sprites': 'onHighlightSprites' 'sprite:highlight-sprites': 'onHighlightSprites'
'sprite:speech-updated': 'onSpriteSpeechUpdated' 'sprite:speech-updated': 'onSpriteSpeechUpdated'
'surface:frame-changed': 'onFrameChanged' 'surface:frame-changed': 'onFrameChanged'
'camera:zoom-updated': 'onZoomUpdated' 'camera:zoom-updated': 'onZoomUpdated'

View file

@ -4,8 +4,8 @@ CocoSprite = require 'lib/surface/CocoSprite'
module.exports = IndieSprite = class IndieSprite extends CocoSprite module.exports = IndieSprite = class IndieSprite extends CocoSprite
notOfThisWorld: true notOfThisWorld: true
subscriptions: subscriptions:
'note-group-started': 'onNoteGroupStarted' 'script:note-group-started': 'onNoteGroupStarted'
'note-group-ended': 'onNoteGroupEnded' 'script:note-group-ended': 'onNoteGroupEnded'
constructor: (thangType, options) -> constructor: (thangType, options) ->
options.thang = @makeIndieThang thangType, options options.thang = @makeIndieThang thangType, options
@ -26,6 +26,8 @@ module.exports = IndieSprite = class IndieSprite extends CocoSprite
thang.getActionName = -> thang.action thang.getActionName = -> thang.action
thang.acts = true thang.acts = true
thang.isSelectable = true thang.isSelectable = true
thang.team = options.team
thang.teamColors = options.teamColors
thang thang
onNoteGroupStarted: => @scriptRunning = true onNoteGroupStarted: => @scriptRunning = true

View file

@ -1,6 +1,6 @@
module.exports = class Letterbox extends createjs.Container module.exports = class Letterbox extends createjs.Container
subscriptions: subscriptions:
'level-set-letterbox': 'onSetLetterbox' 'level:set-letterbox': 'onSetLetterbox'
constructor: (options) -> constructor: (options) ->
super() super()

View file

@ -216,7 +216,7 @@ module.exports = class Mark extends CocoClass
onLoadedThangType: -> onLoadedThangType: ->
@build() @build()
@toggle(@toggleTo) if @toggleTo? @toggle(@toggleTo) if @toggleTo?
Backbone.Mediator.publish 'sprite:loaded' Backbone.Mediator.publish 'sprite:loaded', {sprite: @}
update: (pos=null) -> update: (pos=null) ->
return false unless @on and @mark return false unless @on and @mark

View file

@ -9,7 +9,7 @@ module.exports = class MusicPlayer extends CocoClass
standingBy: null standingBy: null
subscriptions: subscriptions:
'level-play-music': 'onPlayMusic' 'music-player:play-music': 'onPlayMusic'
'audio-player:loaded': 'onAudioLoaded' 'audio-player:loaded': 'onAudioLoaded'
constructor: -> constructor: ->

View file

@ -24,10 +24,9 @@ module.exports = class PointChooser extends CocoClass
@shape.layerIndex = 100 @shape.layerIndex = 100
onMouseDown: (e) => onMouseDown: (e) =>
console.log 'got stagemousedown', e, key.shift
return unless key.shift return unless key.shift
@setPoint @options.camera.screenToWorld {x: e.stageX, y: e.stageY} @setPoint @options.camera.screenToWorld {x: e.stageX, y: e.stageY}
Backbone.Mediator.publish 'choose-point', point: @point Backbone.Mediator.publish 'surface:choose-point', point: @point
updateShape: -> updateShape: ->
sup = @options.camera.worldToSurface @point sup = @options.camera.worldToSurface @point

View file

@ -27,7 +27,7 @@ module.exports = class RegionChooser extends CocoClass
onMouseUp: (e) => onMouseUp: (e) =>
return unless @firstPoint return unless @firstPoint
Backbone.Mediator.publish 'choose-region', points: [@firstPoint, @secondPoint] Backbone.Mediator.publish 'surface:choose-region', points: [@firstPoint, @secondPoint]
@firstPoint = null @firstPoint = null
@secondPoint = null @secondPoint = null
@options.camera.dragDisabled = false @options.camera.dragDisabled = false

View file

@ -12,12 +12,12 @@ module.exports = class SpriteBoss extends CocoClass
subscriptions: subscriptions:
'bus:player-joined': 'onPlayerJoined' 'bus:player-joined': 'onPlayerJoined'
'bus:player-left': 'onPlayerLeft' 'bus:player-left': 'onPlayerLeft'
'level-set-debug': 'onSetDebug' 'level:set-debug': 'onSetDebug'
'level-highlight-sprites': 'onHighlightSprites' 'sprite:highlight-sprites': 'onHighlightSprites'
'surface:stage-mouse-down': 'onStageMouseDown' 'surface:stage-mouse-down': 'onStageMouseDown'
'level-select-sprite': 'onSelectSprite' 'level:select-sprite': 'onSelectSprite'
'level-suppress-selection-sounds': 'onSuppressSelectionSounds' 'level:suppress-selection-sounds': 'onSuppressSelectionSounds'
'level-lock-select': 'onSetLockSelect' 'level:lock-select': 'onSetLockSelect'
'level:restarted': 'onLevelRestarted' 'level:restarted': 'onLevelRestarted'
'god:new-world-created': 'onNewWorld' 'god:new-world-created': 'onNewWorld'
'god:streaming-world-updated': 'onNewWorld' 'god:streaming-world-updated': 'onNewWorld'
@ -111,7 +111,7 @@ module.exports = class SpriteBoss extends CocoClass
unless thangType = @thangTypeFor indieSprite.thangType unless thangType = @thangTypeFor indieSprite.thangType
console.warn "Need to convert #{indieSprite.id}'s ThangType #{indieSprite.thangType} to a ThangType reference. Until then, #{indieSprite.id} won't show up." console.warn "Need to convert #{indieSprite.id}'s ThangType #{indieSprite.thangType} to a ThangType reference. Until then, #{indieSprite.id} won't show up."
return return
sprite = new IndieSprite thangType, @createSpriteOptions {thangID: indieSprite.id, pos: indieSprite.pos, sprites: @sprites, colorConfig: indieSprite.colorConfig} sprite = new IndieSprite thangType, @createSpriteOptions {thangID: indieSprite.id, pos: indieSprite.pos, sprites: @sprites, team: indieSprite.team, teamColors: @world.getTeamColors()}
@addSprite sprite, sprite.thang.id @addSprite sprite, sprite.thang.id
createOpponentWizard: (opponent) -> createOpponentWizard: (opponent) ->
@ -319,9 +319,9 @@ module.exports = class SpriteBoss extends CocoClass
if alive and not @suppressSelectionSounds if alive and not @suppressSelectionSounds
instance = sprite.playSound 'selected' instance = sprite.playSound 'selected'
if instance?.playState is 'playSucceeded' if instance?.playState is 'playSucceeded'
Backbone.Mediator.publish 'thang-began-talking', thang: sprite?.thang Backbone.Mediator.publish 'sprite:thang-began-talking', thang: sprite?.thang
instance.addEventListener 'complete', -> instance.addEventListener 'complete', ->
Backbone.Mediator.publish 'thang-finished-talking', thang: sprite?.thang Backbone.Mediator.publish 'sprite:thang-finished-talking', thang: sprite?.thang
onFlagColorSelected: (e) -> onFlagColorSelected: (e) ->
@removeSprite @flagCursorSprite if @flagCursorSprite @removeSprite @flagCursorSprite if @flagCursorSprite

View file

@ -12,6 +12,7 @@ CountdownScreen = require './CountdownScreen'
PlaybackOverScreen = require './PlaybackOverScreen' PlaybackOverScreen = require './PlaybackOverScreen'
DebugDisplay = require './DebugDisplay' DebugDisplay = require './DebugDisplay'
CoordinateDisplay = require './CoordinateDisplay' CoordinateDisplay = require './CoordinateDisplay'
CoordinateGrid = require './CoordinateGrid'
SpriteBoss = require './SpriteBoss' SpriteBoss = require './SpriteBoss'
PointChooser = require './PointChooser' PointChooser = require './PointChooser'
RegionChooser = require './RegionChooser' RegionChooser = require './RegionChooser'
@ -24,7 +25,7 @@ module.exports = Surface = class Surface extends CocoClass
surfaceLayer: null surfaceLayer: null
surfaceTextLayer: null surfaceTextLayer: null
screenLayer: null screenLayer: null
gridLayer: null # TODO: maybe gridLayer: null
spriteBoss: null spriteBoss: null
@ -51,21 +52,19 @@ module.exports = Surface = class Surface extends CocoClass
frameRate: 30 # Best as a divisor of 60, like 15, 30, 60, with RAF_SYNCHED timing. frameRate: 30 # Best as a divisor of 60, like 15, 30, 60, with RAF_SYNCHED timing.
subscriptions: subscriptions:
'level-disable-controls': 'onDisableControls' 'level:disable-controls': 'onDisableControls'
'level-enable-controls': 'onEnableControls' 'level:enable-controls': 'onEnableControls'
'level-set-playing': 'onSetPlaying' 'level:set-playing': 'onSetPlaying'
'level-set-debug': 'onSetDebug' 'level:set-debug': 'onSetDebug'
'level-toggle-debug': 'onToggleDebug' 'level:toggle-debug': 'onToggleDebug'
'level-set-grid': 'onSetGrid' 'level:toggle-pathfinding': 'onTogglePathFinding'
'level-toggle-grid': 'onToggleGrid' 'level:set-time': 'onSetTime'
'level-toggle-pathfinding': 'onTogglePathFinding' 'camera:set-camera': 'onSetCamera'
'level-set-time': 'onSetTime'
'level-set-surface-camera': 'onSetCamera'
'level:restarted': 'onLevelRestarted' 'level:restarted': 'onLevelRestarted'
'god:new-world-created': 'onNewWorld' 'god:new-world-created': 'onNewWorld'
'god:streaming-world-updated': 'onNewWorld' 'god:streaming-world-updated': 'onNewWorld'
'tome:cast-spells': 'onCastSpells' 'tome:cast-spells': 'onCastSpells'
'level-set-letterbox': 'onSetLetterbox' 'level:set-letterbox': 'onSetLetterbox'
'application:idle-changed': 'onIdleChanged' 'application:idle-changed': 'onIdleChanged'
'camera:zoom-updated': 'onZoomUpdated' 'camera:zoom-updated': 'onZoomUpdated'
'playback:real-time-playback-started': 'onRealTimePlaybackStarted' 'playback:real-time-playback-started': 'onRealTimePlaybackStarted'
@ -75,7 +74,6 @@ module.exports = Surface = class Surface extends CocoClass
shortcuts: shortcuts:
'ctrl+\\, ⌘+\\': 'onToggleDebug' 'ctrl+\\, ⌘+\\': 'onToggleDebug'
'ctrl+g, ⌘+g': 'onToggleGrid'
'ctrl+o, ⌘+o': 'onTogglePathFinding' 'ctrl+o, ⌘+o': 'onTogglePathFinding'
# external functions # external functions
@ -103,6 +101,8 @@ module.exports = Surface = class Surface extends CocoClass
@dimmer?.destroy() @dimmer?.destroy()
@countdownScreen?.destroy() @countdownScreen?.destroy()
@playbackOverScreen?.destroy() @playbackOverScreen?.destroy()
@coordinateDisplay?.destroy()
@coordinateGrid?.destroy()
@stage.clear() @stage.clear()
@musicPlayer?.destroy() @musicPlayer?.destroy()
@stage.removeAllChildren() @stage.removeAllChildren()
@ -126,12 +126,8 @@ module.exports = Surface = class Surface extends CocoClass
@showLevel() @showLevel()
@updateState true if @loaded @updateState true if @loaded
# TODO: synchronize both ways of choosing whether to show coords (@world via UI System or @options via World Select modal)
if @world.showCoordinates and @options.coords and not @coordinateDisplay
@coordinateDisplay = new CoordinateDisplay camera: @camera
@surfaceTextLayer.addChild @coordinateDisplay
@onFrameChanged() @onFrameChanged()
Backbone.Mediator.publish 'surface:world-set-up' Backbone.Mediator.publish 'surface:world-set-up', {world: @world}
onTogglePathFinding: (e) -> onTogglePathFinding: (e) ->
e?.preventDefault?() e?.preventDefault?()
@ -315,7 +311,6 @@ module.exports = Surface = class Surface extends CocoClass
return if @currentFrame is @lastFrame and not force return if @currentFrame is @lastFrame and not force
progress = @getProgress() progress = @getProgress()
Backbone.Mediator.publish('surface:frame-changed', Backbone.Mediator.publish('surface:frame-changed',
type: 'frame-changed'
selectedThang: @spriteBoss.selectedSprite?.thang selectedThang: @spriteBoss.selectedSprite?.thang
progress: progress progress: progress
frame: @currentFrame frame: @currentFrame
@ -325,11 +320,11 @@ module.exports = Surface = class Surface extends CocoClass
if @lastFrame < @world.frames.length and @currentFrame >= @world.totalFrames - 1 if @lastFrame < @world.frames.length and @currentFrame >= @world.totalFrames - 1
@ended = true @ended = true
@setPaused true @setPaused true
Backbone.Mediator.publish 'surface:playback-ended' Backbone.Mediator.publish 'surface:playback-ended', {}
else if @currentFrame < @world.totalFrames and @ended else if @currentFrame < @world.totalFrames and @ended
@ended = false @ended = false
@setPaused false @setPaused false
Backbone.Mediator.publish 'surface:playback-restarted' Backbone.Mediator.publish 'surface:playback-restarted', {}
@lastFrame = @currentFrame @lastFrame = @currentFrame
@ -364,12 +359,15 @@ module.exports = Surface = class Surface extends CocoClass
onNewWorld: (event) -> onNewWorld: (event) ->
return unless event.world.name is @world.name return unless event.world.name is @world.name
@onStreamingWorldUpdated event
onStreamingWorldUpdated: (event) ->
@casting = false @casting = false
@spriteBoss.play() @spriteBoss.play()
# This has a tendency to break scripts that are waiting for playback to change when the level is loaded # 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. # so only run it after the first world is created.
Backbone.Mediator.publish 'level-set-playing', {playing: true} unless event.firstWorld or @setPlayingCalled Backbone.Mediator.publish 'level:set-playing', {playing: true} unless event.firstWorld or @setPlayingCalled
@setWorld event.world @setWorld event.world
@onFrameChanged(true) @onFrameChanged(true)
@ -390,22 +388,21 @@ module.exports = Surface = class Surface extends CocoClass
# initialization # initialization
initEasel: -> initEasel: ->
# takes DOM objects, not jQuery objects @stage = new createjs.Stage(@canvas[0]) # Takes DOM objects, not jQuery objects.
@stage = new createjs.Stage(@canvas[0])
canvasWidth = parseInt @canvas.attr('width'), 10 canvasWidth = parseInt @canvas.attr('width'), 10
canvasHeight = parseInt @canvas.attr('height'), 10 canvasHeight = parseInt @canvas.attr('height'), 10
@camera?.destroy() @camera = AudioPlayer.camera = new Camera @canvas
@camera = new Camera @canvas
AudioPlayer.camera = @camera
@layers.push @surfaceLayer = new Layer name: 'Surface', layerPriority: 0, transform: Layer.TRANSFORM_SURFACE, camera: @camera @layers.push @surfaceLayer = new Layer name: 'Surface', layerPriority: 0, transform: Layer.TRANSFORM_SURFACE, camera: @camera
@layers.push @surfaceTextLayer = new Layer name: 'Surface Text', layerPriority: 1, transform: Layer.TRANSFORM_SURFACE_TEXT, camera: @camera @layers.push @surfaceTextLayer = new Layer name: 'Surface Text', layerPriority: 1, transform: Layer.TRANSFORM_SURFACE_TEXT, camera: @camera
@layers.push @screenLayer = new Layer name: 'Screen', layerPriority: 2, transform: Layer.TRANSFORM_SCREEN, camera: @camera @layers.push @gridLayer = new Layer name: 'Grid', layerPriority: 2, transform: Layer.TRANSFORM_SURFACE, camera: @camera
@layers.push @screenLayer = new Layer name: 'Screen', layerPriority: 3, transform: Layer.TRANSFORM_SCREEN, camera: @camera
@stage.addChild @layers... @stage.addChild @layers...
@surfaceLayer.addChild @cameraBorder = new CameraBorder bounds: @camera.bounds @surfaceLayer.addChild @cameraBorder = new CameraBorder bounds: @camera.bounds
@screenLayer.addChild new Letterbox canvasWidth: canvasWidth, canvasHeight: canvasHeight @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 @spriteBoss = new SpriteBoss camera: @camera, surfaceLayer: @surfaceLayer, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible
@countdownScreen ?= new CountdownScreen camera: @camera, layer: @screenLayer @countdownScreen = new CountdownScreen camera: @camera, layer: @screenLayer
@playbackOverScreen ?= new PlaybackOverScreen camera: @camera, layer: @screenLayer @playbackOverScreen = new PlaybackOverScreen camera: @camera, layer: @screenLayer
@initCoordinates()
@stage.enableMouseOver(10) @stage.enableMouseOver(10)
@stage.addEventListener 'stagemousemove', @onMouseMove @stage.addEventListener 'stagemousemove', @onMouseMove
@stage.addEventListener 'stagemousedown', @onMouseDown @stage.addEventListener 'stagemousedown', @onMouseDown
@ -416,6 +413,11 @@ module.exports = Surface = class Surface extends CocoClass
createjs.Ticker.setFPS @options.frameRate createjs.Ticker.setFPS @options.frameRate
@onResize() @onResize()
initCoordinates: ->
@coordinateGrid ?= new CoordinateGrid {camera: @camera, layer: @gridLayer, textLayer: @surfaceTextLayer}, @world.size()
@coordinateGrid.showGrid() if @world.showGrid or @options.grid
@coordinateDisplay ?= new CoordinateDisplay camera: @camera, layer: @surfaceTextLayer if @world.showCoordinates or @options.coords
onResize: (e) => onResize: (e) =>
return if @destroyed return if @destroyed
oldWidth = parseInt @canvas.attr('width'), 10 oldWidth = parseInt @canvas.attr('width'), 10
@ -447,12 +449,10 @@ module.exports = Surface = class Surface extends CocoClass
@loaded = true @loaded = true
@spriteBoss.createMarks() @spriteBoss.createMarks()
@spriteBoss.createIndieSprites @world.indieSprites, @options.wizards @spriteBoss.createIndieSprites @world.indieSprites, @options.wizards
Backbone.Mediator.publish 'registrar-echo-states'
@updateState true @updateState true
@drawCurrentFrame() @drawCurrentFrame()
@showGrid() if @options.grid # TODO: pay attention to world grid setting (which we only know when world simulates)
createjs.Ticker.addEventListener 'tick', @tick createjs.Ticker.addEventListener 'tick', @tick
Backbone.Mediator.publish 'level:started' Backbone.Mediator.publish 'level:started', {}
createOpponentWizard: (opponent) -> createOpponentWizard: (opponent) ->
@spriteBoss.createOpponentWizard opponent @spriteBoss.createOpponentWizard opponent
@ -460,70 +460,9 @@ module.exports = Surface = class Surface extends CocoClass
initAudio: -> initAudio: ->
@musicPlayer = new MusicPlayer() @musicPlayer = new MusicPlayer()
# grid; should probably refactor into separate class
showGrid: ->
return if @gridShowing()
unless @gridLayer
@gridLayer = new createjs.Container()
@gridShape = new createjs.Shape()
@gridLayer.addChild @gridShape
@gridLayer.z = 90019001
@gridLayer.mouseEnabled = false
@gridShape.alpha = 0.125
@gridShape.graphics.beginStroke 'blue'
gridSize = Math.round(@world.size()[0] / 20)
unless gridSize > 0.1
return console.error 'Grid size is', gridSize, 'so we can\'t draw a grid.'
wopStart = x: 0, y: 0
wopEnd = x: @world.size()[0], y: @world.size()[1]
supStart = @camera.worldToSurface wopStart
supEnd = @camera.worldToSurface wopEnd
wop = x: wopStart.x, y: wopStart.y
while wop.x < wopEnd.x
sup = @camera.worldToSurface wop
@gridShape.graphics.mt(sup.x, supStart.y).lt(sup.x, supEnd.y)
t = new createjs.Text(wop.x.toFixed(0), '16px Arial', 'blue')
t.x = sup.x - t.getMeasuredWidth() / 2
t.y = supStart.y - 10 - t.getMeasuredHeight() / 2
t.alpha = 0.75
@gridLayer.addChild t
wop.x += gridSize
while wop.y < wopEnd.y
sup = @camera.worldToSurface wop
@gridShape.graphics.mt(supStart.x, sup.y).lt(supEnd.x, sup.y)
t = new createjs.Text(wop.y.toFixed(0), '16px Arial', 'blue')
t.x = 10 - t.getMeasuredWidth() / 2
t.y = sup.y - t.getMeasuredHeight() / 2
t.alpha = 0.75
@gridLayer.addChild t
wop.y += gridSize
@gridShape.graphics.endStroke()
bounds = @gridLayer.getBounds()
return unless bounds?.width and bounds.height
@gridLayer.cache bounds.x, bounds.y, bounds.width, bounds.height
@surfaceLayer.addChild @gridLayer
hideGrid: ->
return unless @gridShowing()
@gridLayer.parent.removeChild @gridLayer
gridShowing: ->
@gridLayer?.parent?
onToggleGrid: (e) ->
# TODO: figure out a better way of managing grid / debug so it's not split across PlaybackView and Surface
e?.preventDefault?()
if @gridShowing() then @hideGrid() else @showGrid()
flag = $('#grid-toggle i.icon-ok')
flag.toggleClass 'invisible', not @gridShowing()
onSetGrid: (e) ->
if e.grid then @showGrid() else @hideGrid()
onToggleDebug: (e) -> onToggleDebug: (e) ->
e?.preventDefault?() e?.preventDefault?()
Backbone.Mediator.publish 'level-set-debug', {debug: not @debug} Backbone.Mediator.publish 'level:set-debug', {debug: not @debug}
onSetDebug: (e) -> onSetDebug: (e) ->
return if e.debug is @debug return if e.debug is @debug
@ -547,6 +486,7 @@ module.exports = Surface = class Surface extends CocoClass
onMouseUp: (e) => onMouseUp: (e) =>
return if @disabled return if @disabled
console.log 'yo on mouse up', e
onBackground = not @stage.hitTest e.stageX, e.stageY onBackground = not @stage.hitTest e.stageX, e.stageY
Backbone.Mediator.publish 'surface:stage-mouse-up', onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e Backbone.Mediator.publish 'surface:stage-mouse-up', onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e

View file

@ -16,10 +16,9 @@ module.exports = class WizardSprite extends IndieSprite
subscriptions: subscriptions:
'bus:player-states-changed': 'onPlayerStatesChanged' 'bus:player-states-changed': 'onPlayerStatesChanged'
'me:synced': 'onMeSynced' 'auth:me-synced': 'onMeSynced'
'surface:sprite-selected': 'onSpriteSelected' 'surface:sprite-selected': 'onSpriteSelected'
'echo-self-wizard-sprite': 'onEchoSelfWizardSprite' 'sprite:echo-all-wizard-sprites': 'onEchoAllWizardSprites'
'echo-all-wizard-sprites': 'onEchoAllWizardSprites'
shortcuts: shortcuts:
'up': 'onMoveKey' 'up': 'onMoveKey'
@ -36,6 +35,7 @@ module.exports = class WizardSprite extends IndieSprite
@setNameLabel me.displayName() @setNameLabel me.displayName()
else if options.name else if options.name
@setNameLabel options.name @setNameLabel options.name
Backbone.Mediator.publish 'self-wizard:created', sprite: @
makeIndieThang: (thangType, options) -> makeIndieThang: (thangType, options) ->
thang = super thangType, options thang = super thangType, options
@ -112,7 +112,6 @@ module.exports = class WizardSprite extends IndieSprite
@targetPos = @getPosFromTarget(@targetSprite or targetPos) @targetPos = @getPosFromTarget(@targetSprite or targetPos)
@endMoveTween() @endMoveTween()
onEchoSelfWizardSprite: (e) -> e.payload = @ if @isSelf
onEchoAllWizardSprites: (e) -> e.payload.push @ onEchoAllWizardSprites: (e) -> e.payload.push @
defaultPos: -> x: 35, y: 24, z: @thang.depth / 2 + @thang.bobHeight defaultPos: -> x: 35, y: 24, z: @thang.depth / 2 + @thang.bobHeight
move: (pos, duration) -> @setTarget(pos, duration) move: (pos, duration) -> @setTarget(pos, duration)
@ -132,7 +131,7 @@ module.exports = class WizardSprite extends IndieSprite
@targetPos = @boundWizard targetPos @targetPos = @boundWizard targetPos
@beginMoveTween(duration, isLinear) @beginMoveTween(duration, isLinear)
@shoveOtherWizards() @shoveOtherWizards()
Backbone.Mediator.publish('self-wizard:target-changed', {sender: @}) if @isSelf Backbone.Mediator.publish('self-wizard:target-changed', {sprite: @}) if @isSelf
boundWizard: (target) -> boundWizard: (target) ->
# Passed an {x, y} in world coordinates, returns {x, y} within world bounds # Passed an {x, y} in world coordinates, returns {x, y} within world bounds
@ -179,7 +178,7 @@ module.exports = class WizardSprite extends IndieSprite
shoveOtherWizards: (removeMe) -> shoveOtherWizards: (removeMe) ->
return unless @targetSprite return unless @targetSprite
allWizards = [] allWizards = []
Backbone.Mediator.publish('echo-all-wizard-sprites', {payload: allWizards}) Backbone.Mediator.publish 'sprite:echo-all-wizard-sprites', payload: allWizards
allOfUs = (wizard for wizard in allWizards when wizard.targetSprite is @targetSprite) allOfUs = (wizard for wizard in allWizards when wizard.targetSprite is @targetSprite)
allOfUs = (wizard for wizard in allOfUs when wizard isnt @) if removeMe allOfUs = (wizard for wizard in allOfUs when wizard isnt @) if removeMe
@ -271,4 +270,4 @@ module.exports = class WizardSprite extends IndieSprite
position = {x: @targetPos.x + x, y: @targetPos.y + y} position = {x: @targetPos.x + x, y: @targetPos.y + y}
@setTarget(position, interval, true) @setTarget(position, interval, true)
@updatePosition() @updatePosition()
Backbone.Mediator.publish 'camera-zoom-to', position, interval Backbone.Mediator.publish 'camera:zoom-to', pos: position, duration: interval

View file

@ -167,7 +167,7 @@ module.exports = class Thang
{CN: @constructor.className, id: @id} {CN: @constructor.className, id: @id}
getSpriteOptions: -> getSpriteOptions: ->
colorConfigs = @world?.getTeamColors() or {} colorConfigs = @teamColors or @world?.getTeamColors() or {}
options = {colorConfig: {}} options = {colorConfig: {}}
if @team and teamColor = colorConfigs[@team] if @team and teamColor = colorConfigs[@team]
options.colorConfig.team = teamColor options.colorConfig.team = teamColor

File diff suppressed because it is too large Load diff

View file

@ -103,11 +103,11 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
for_beginners: "Für Anfänger" for_beginners: "Für Anfänger"
multiplayer: "Mehrspieler" multiplayer: "Mehrspieler"
for_developers: "Für Entwickler" for_developers: "Für Entwickler"
# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." javascript_blurb: "Die Sprache des Web. Geeignet für die Erstellung von Webseiten, WebApps, HTML5 Spielen und Servern.."
# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." # python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
# coffeescript_blurb: "Nicer JavaScript syntax." coffeescript_blurb: "Schönere JavaScript Syntax."
# clojure_blurb: "A modern Lisp." clojure_blurb: "Ein modernes Lisp."
# lua_blurb: "Game scripting language." lua_blurb: "Skriptsprache für Spiele."
# io_blurb: "Simple but obscure." # io_blurb: "Simple but obscure."
play: play:
@ -179,7 +179,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
new_password: "Neues Passwort" new_password: "Neues Passwort"
new_password_verify: "Passwort verifizieren" new_password_verify: "Passwort verifizieren"
email_subscriptions: "Email Abonnements" email_subscriptions: "Email Abonnements"
# email_subscriptions_none: "No Email Subscriptions." email_subscriptions_none: "Keine Email Abonnements."
email_announcements: "Ankündigungen" email_announcements: "Ankündigungen"
email_announcements_description: "Erhalte regelmäßig Ankündigungen zu deinem Account." email_announcements_description: "Erhalte regelmäßig Ankündigungen zu deinem Account."
email_notifications: "Benachrichtigungen" email_notifications: "Benachrichtigungen"
@ -197,7 +197,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
error_saving: "Fehler beim Speichern" error_saving: "Fehler beim Speichern"
saved: "Änderungen gespeichert" saved: "Änderungen gespeichert"
password_mismatch: "Passwörter stimmen nicht überein." password_mismatch: "Passwörter stimmen nicht überein."
# password_repeat: "Please repeat your password." password_repeat: "Bitte wiederhole dein Passwort."
job_profile: "Jobprofil" job_profile: "Jobprofil"
job_profile_approved: "Dein Jobprofil wurde von CodeCombat freigegeben. Arbeitgeber können dieses solange einsehen, bis du es als inaktiv markiert oder wenn innerhalb von vier Wochen keine Änderung daran vorgenommen wurde." job_profile_approved: "Dein Jobprofil wurde von CodeCombat freigegeben. Arbeitgeber können dieses solange einsehen, bis du es als inaktiv markiert oder wenn innerhalb von vier Wochen keine Änderung daran vorgenommen wurde."
job_profile_explanation: "Hi! Fülle dies aus und wir melden uns bei dir bezüglich des Auffindens eines Jobs als Programmierer" job_profile_explanation: "Hi! Fülle dies aus und wir melden uns bei dir bezüglich des Auffindens eines Jobs als Programmierer"
@ -212,7 +212,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
profile_for_suffix: "" profile_for_suffix: ""
# featured: "Featured" # featured: "Featured"
# not_featured: "Not Featured" # not_featured: "Not Featured"
# looking_for: "Looking for:" looking_for: "Suche nach:"
last_updated: "zuletzt geändert:" last_updated: "zuletzt geändert:"
contact: "Kontakt" contact: "Kontakt"
# active: "Looking for interview offers now" # active: "Looking for interview offers now"
@ -359,13 +359,13 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
customize_wizard: "Bearbeite den Zauberer" customize_wizard: "Bearbeite den Zauberer"
home: "Startseite" home: "Startseite"
# stop: "Stop" # stop: "Stop"
# game_menu: "Game Menu" game_menu: "Spielmenü"
guide: "Hilfe" guide: "Hilfe"
restart: "Neustart" restart: "Neustart"
goals: "Ziele" goals: "Ziele"
# success: "Success!" success: "Erfolgreich!"
# incomplete: "Incomplete" incomplete: "Unvollständig"
# timed_out: "Ran out of time" timed_out: "Zeit abgelaufen"
# failing: "Failing" # failing: "Failing"
action_timeline: "Aktionszeitstrahl" action_timeline: "Aktionszeitstrahl"
click_to_select: "Klicke auf eine Einheit, um sie auszuwählen." click_to_select: "Klicke auf eine Einheit, um sie auszuwählen."
@ -425,7 +425,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
tip_impossible: "Es wirkt immer unmöglich bis es vollbracht ist. - Nelson Mandela" tip_impossible: "Es wirkt immer unmöglich bis es vollbracht ist. - Nelson Mandela"
tip_talk_is_cheap: "Reden ist billig. Zeig mir den Code. - Linus Torvalds" tip_talk_is_cheap: "Reden ist billig. Zeig mir den Code. - Linus Torvalds"
tip_first_language: "Das schwierigste, das du jemals lernen wirst, ist die erste Programmiersprache. - Alan Kay" tip_first_language: "Das schwierigste, das du jemals lernen wirst, ist die erste Programmiersprache. - Alan Kay"
# tip_hardware_problem: "Q: How many programmers does it take to change a light bulb? A: None, it's a hardware problem." tip_hardware_problem: "Q: Wie viele Programmierer braucht man um eine Glühbirne auszuwechseln? A: Keine, es ist ein Hardware-Problem."
time_current: "Aktuell" time_current: "Aktuell"
time_total: "Total" time_total: "Total"
time_goto: "Gehe zu" time_goto: "Gehe zu"
@ -433,19 +433,19 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
# infinite_loop_reset_level: "Reset Level" # infinite_loop_reset_level: "Reset Level"
infinite_loop_comment_out: "Meinen Code auskommentieren" infinite_loop_comment_out: "Meinen Code auskommentieren"
game_menu: # game_menu:
# inventory_tab: "Inventory" # inventory_tab: "Inventory"
# choose_hero_tab: "Restart Level" choose_hero_tab: "Level neustarten"
# save_load_tab: "Save/Load" save_load_tab: "Speichere/Lade"
# options_tab: "Options" options_tab: "Optionen"
# guide_tab: "Guide" # guide_tab: "Guide"
multiplayer_tab: "Multiplayer" multiplayer_tab: "Mehrspieler"
# inventory_caption: "Equip your hero" # inventory_caption: "Equip your hero"
# choose_hero_caption: "Choose hero, language" # choose_hero_caption: "Choose hero, language"
# save_load_caption: "... and view history" # save_load_caption: "... and view history"
# options_caption: "Configure settings" options_caption: "Konfiguriere Einstellungen"
# guide_caption: "Docs and tips" # guide_caption: "Docs and tips"
# multiplayer_caption: "Play with friends!" multiplayer_caption: "Spiele mit Freunden!"
# inventory: # inventory:
# temp: "Temp" # temp: "Temp"
@ -458,9 +458,9 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
# granularity_change_history: "History" # granularity_change_history: "History"
options: options:
# general_options: "General Options" general_options: "Allgemeine Einstellungen"
# music_label: "Music" music_label: "Musik"
# music_description: "Turn background music on/off." music_description: "Schalte Hintergrundmusik an/aus."
# autorun_label: "Autorun" # autorun_label: "Autorun"
# autorun_description: "Control automatic code execution." # autorun_description: "Control automatic code execution."
editor_config: "Editor Einstellungen" editor_config: "Editor Einstellungen"
@ -472,8 +472,8 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
editor_config_keybindings_label: "Tastenbelegung" editor_config_keybindings_label: "Tastenbelegung"
editor_config_keybindings_default: "Standard (Ace)" editor_config_keybindings_default: "Standard (Ace)"
editor_config_keybindings_description: "Fügt zusätzliche Tastenkombinationen, bekannt aus anderen Editoren, hinzu" editor_config_keybindings_description: "Fügt zusätzliche Tastenkombinationen, bekannt aus anderen Editoren, hinzu"
# editor_config_livecompletion_label: "Live Autocompletion" editor_config_livecompletion_label: "Live Auto-Vervollständigung"
# editor_config_livecompletion_description: "Displays autocomplete suggestions while typing." editor_config_livecompletion_description: "Zeigt Vorschläge der Auto-Vervollständigung an während du tippst."
editor_config_invisibles_label: "Zeige unsichtbare Zeichen" editor_config_invisibles_label: "Zeige unsichtbare Zeichen"
editor_config_invisibles_description: "Zeigt unsichtbare Zeichen wie Leertasten an." editor_config_invisibles_description: "Zeigt unsichtbare Zeichen wie Leertasten an."
editor_config_indentguides_label: "Zeige Einrückungshilfe" editor_config_indentguides_label: "Zeige Einrückungshilfe"
@ -485,9 +485,9 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
# temp: "Temp" # temp: "Temp"
multiplayer: multiplayer:
multiplayer_title: "Multiplayer Einstellungen" multiplayer_title: "Mehrspieler Einstellungen"
# multiplayer_toggle: "Enable multiplayer" # multiplayer_toggle: "Enable multiplayer"
# multiplayer_toggle_description: "Allow others to join your game." multiplayer_toggle_description: "Erlaube anderen an deinem Spiel teilzunehmen."
multiplayer_link_description: "Gib diesen Link jedem, der mitmachen will." multiplayer_link_description: "Gib diesen Link jedem, der mitmachen will."
multiplayer_hint_label: "Hinweis:" multiplayer_hint_label: "Hinweis:"
multiplayer_hint: " Klick den Link, um alles auszuwählen, dann drück ⌘-C oder Strg-C um den Link zu kopieren." multiplayer_hint: " Klick den Link, um alles auszuwählen, dann drück ⌘-C oder Strg-C um den Link zu kopieren."
@ -521,7 +521,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
av_entities_active_instances_url: "Aktive Instanzen" av_entities_active_instances_url: "Aktive Instanzen"
av_entities_employer_list_url: "Arbeitgeberliste" av_entities_employer_list_url: "Arbeitgeberliste"
av_other_sub_title: "Sonstige" av_other_sub_title: "Sonstige"
# av_other_debug_base_url: "Base (for debugging base.jade)" av_other_debug_base_url: "Base (um base.jade zu debuggen)"
u_title: "Benutzerliste" u_title: "Benutzerliste"
lg_title: "Letzte Spiele" lg_title: "Letzte Spiele"
# clas: "CLAs" # clas: "CLAs"
@ -535,7 +535,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
# thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites." # thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites."
# article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the" # article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the"
# article_editor_suffix: "and help CodeCombat players get the most out of their playtime." # article_editor_suffix: "and help CodeCombat players get the most out of their playtime."
# find_us: "Find us on these sites" find_us: "Finde uns auf diesen Seiten"
# contribute_to_the_project: "Contribute to the project" # contribute_to_the_project: "Contribute to the project"
editor: editor:
@ -547,8 +547,8 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
back: "Zurück" back: "Zurück"
revert: "Zurücksetzen" revert: "Zurücksetzen"
revert_models: "Models zurücksetzen." revert_models: "Models zurücksetzen."
# pick_a_terrain: "Pick A Terrain" pick_a_terrain: "Wähle ein Terrain"
# small: "Small" small: "Klein"
# grassy: "Grassy" # grassy: "Grassy"
fork_title: "Forke neue Version" fork_title: "Forke neue Version"
fork_creating: "Erzeuge Fork..." fork_creating: "Erzeuge Fork..."
@ -608,7 +608,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
general: general:
and: "und" and: "und"
name: "Name" name: "Name"
# date: "Date" date: "Datum"
body: "Inhalt" body: "Inhalt"
version: "Version" version: "Version"
commit_msg: "Commit Nachricht" commit_msg: "Commit Nachricht"
@ -685,20 +685,20 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
recruitment_description_suffix: "So wenn du deine Fähigkeiten entwickelt hast und zustimmst, werden wir deine besten Leistungen den tausenden Arbeitgebern demonstrieren, welche nur auf die Gelegentheit warten, dich einzustellen. Sie bezahlen uns ein bisschen, und sie bezahlen dir " recruitment_description_suffix: "So wenn du deine Fähigkeiten entwickelt hast und zustimmst, werden wir deine besten Leistungen den tausenden Arbeitgebern demonstrieren, welche nur auf die Gelegentheit warten, dich einzustellen. Sie bezahlen uns ein bisschen, und sie bezahlen dir "
recruitment_description_italic: "jede Menge" recruitment_description_italic: "jede Menge"
recruitment_description_ending: ", die Seite bleibt kostenlos und jeder ist glücklich. So der Plan." recruitment_description_ending: ", die Seite bleibt kostenlos und jeder ist glücklich. So der Plan."
# copyrights_title: "Copyrights and Licenses" copyrights_title: "Copyrights und Lizenzen"
# contributor_title: "Contributor License Agreement" # contributor_title: "Contributor License Agreement"
# contributor_description_prefix: "All contributions, both on the site and on our GitHub repository, are subject to our" # contributor_description_prefix: "All contributions, both on the site and on our GitHub repository, are subject to our"
# cla_url: "CLA" # cla_url: "CLA"
# contributor_description_suffix: "to which you should agree before contributing." # contributor_description_suffix: "to which you should agree before contributing."
# code_title: "Code - MIT" # code_title: "Code - MIT"
# code_description_prefix: "All code owned by CodeCombat or hosted on codecombat.com, both in the GitHub repository or in the codecombat.com database, is licensed under the" # code_description_prefix: "All code owned by CodeCombat or hosted on codecombat.com, both in the GitHub repository or in the codecombat.com database, is licensed under the"
# mit_license_url: "MIT license" mit_license_url: "MIT Lizenz"
# code_description_suffix: "This includes all code in Systems and Components that are made available by CodeCombat for the purpose of creating levels." # code_description_suffix: "This includes all code in Systems and Components that are made available by CodeCombat for the purpose of creating levels."
# art_title: "Art/Music - Creative Commons " # art_title: "Art/Music - Creative Commons "
# art_description_prefix: "All common content is available under the" # art_description_prefix: "All common content is available under the"
# cc_license_url: "Creative Commons Attribution 4.0 International License" # cc_license_url: "Creative Commons Attribution 4.0 International License"
# art_description_suffix: "Common content is anything made generally available by CodeCombat for the purpose of creating Levels. This includes:" # art_description_suffix: "Common content is anything made generally available by CodeCombat for the purpose of creating Levels. This includes:"
# art_music: "Music" art_music: "Musik"
# art_sound: "Sound" # art_sound: "Sound"
# art_artwork: "Artwork" # art_artwork: "Artwork"
# art_sprites: "Sprites" # art_sprites: "Sprites"
@ -733,7 +733,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
# alert_account_message: "To subscribe for class emails, you'll need to be logged in first." # alert_account_message: "To subscribe for class emails, you'll need to be logged in first."
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever." # archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever." # archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes" class_attributes: "Klassenattribute"
# archmage_attribute_1_pref: "Knowledge in " # archmage_attribute_1_pref: "Knowledge in "
# archmage_attribute_1_suf: ", or a desire to learn. Most of our code is in this language. If you're a fan of Ruby or Python, you'll feel right at home. It's JavaScript, but with a nicer syntax." # archmage_attribute_1_suf: ", or a desire to learn. Most of our code is in this language. If you're a fan of Ruby or Python, you'll feel right at home. It's JavaScript, but with a nicer syntax."
# archmage_attribute_2: "Some experience in programming and personal initiative. We'll help you get oriented, but we can't spend much time training you." # archmage_attribute_2: "Some experience in programming and personal initiative. We'll help you get oriented, but we can't spend much time training you."
@ -865,8 +865,8 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
# fight: "Fight!" # fight: "Fight!"
# watch_victory: "Watch your victory" # watch_victory: "Watch your victory"
# defeat_the: "Defeat the" # defeat_the: "Defeat the"
# tournament_ends: "Tournament ends" tournament_ends: "Turnier endet"
# tournament_ended: "Tournament ended" tournament_ended: "Turnier beendet"
tournament_rules: "Turnier-Regeln" tournament_rules: "Turnier-Regeln"
# tournament_blurb: "Write code, collect gold, build armies, crush foes, win prizes, and upgrade your career in our $40,000 Greed tournament! Check out the details" # tournament_blurb: "Write code, collect gold, build armies, crush foes, win prizes, and upgrade your career in our $40,000 Greed tournament! Check out the details"
# tournament_blurb_criss_cross: "Win bids, construct paths, outwit opponents, grab gems, and upgrade your career in our Criss-Cross tournament! Check out the details" # tournament_blurb_criss_cross: "Win bids, construct paths, outwit opponents, grab gems, and upgrade your career in our Criss-Cross tournament! Check out the details"
@ -875,7 +875,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
winners: "Gewinner" winners: "Gewinner"
ladder_prizes: ladder_prizes:
title: "Turnier Preise" title: "Turnierpreise"
# blurb_1: "These prizes will be awarded according to" # blurb_1: "These prizes will be awarded according to"
# blurb_2: "the tournament rules" # blurb_2: "the tournament rules"
# blurb_3: "to the top human and ogre players." # blurb_3: "to the top human and ogre players."
@ -938,9 +938,9 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
document: "Dokument" document: "Dokument"
sprite_sheet: "Sprite Sheet" sprite_sheet: "Sprite Sheet"
candidate_sessions: "Kandidat-Sessions" candidate_sessions: "Kandidat-Sessions"
# user_remark: "User Remark" user_remark: "Benutzerkommentar"
# versions: "Versions" versions: "Versionen"
# items: "Items" items: "Gegenstände"
delta: delta:
added: "hinzugefügt" added: "hinzugefügt"
@ -948,15 +948,15 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
deleted: "gelöscht" deleted: "gelöscht"
# moved_index: "Moved Index" # moved_index: "Moved Index"
# text_diff: "Text Diff" # text_diff: "Text Diff"
# merge_conflict_with: "MERGE CONFLICT WITH" merge_conflict_with: "MERGE KONFLIKT MIT"
# no_changes: "No Changes" no_changes: "Keine Änderungen"
# user: # user:
# stats: "Stats" # stats: "Stats"
# singleplayer_title: "Singleplayer Levels" singleplayer_title: "Einzelspieler Levels"
# multiplayer_title: "Multiplayer Levels" multiplayer_title: "Mehrspieler Levels"
# achievements_title: "Achievements" # achievements_title: "Achievements"
# last_played: "Last Played" last_played: "Zuletzt gespielt"
# status: "Status" # status: "Status"
# status_completed: "Completed" # status_completed: "Completed"
# status_unfinished: "Unfinished" # status_unfinished: "Unfinished"

View file

@ -103,11 +103,11 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
for_beginners: "Für Anfänger" for_beginners: "Für Anfänger"
multiplayer: "Mehrspieler" multiplayer: "Mehrspieler"
for_developers: "Für Entwickler" for_developers: "Für Entwickler"
# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." javascript_blurb: "Die Sprache des Web. Geeignet für die Erstellung von Webseiten, WebApps, HTML5 Spielen und Servern.."
# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." # python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
# coffeescript_blurb: "Nicer JavaScript syntax." coffeescript_blurb: "Schönere JavaScript Syntax."
# clojure_blurb: "A modern Lisp." clojure_blurb: "Ein modernes Lisp."
# lua_blurb: "Game scripting language." lua_blurb: "Skriptsprache für Spiele."
# io_blurb: "Simple but obscure." # io_blurb: "Simple but obscure."
play: play:
@ -179,7 +179,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
new_password: "Neues Passwort" new_password: "Neues Passwort"
new_password_verify: "Passwort verifizieren" new_password_verify: "Passwort verifizieren"
email_subscriptions: "Email Abonnements" email_subscriptions: "Email Abonnements"
# email_subscriptions_none: "No Email Subscriptions." email_subscriptions_none: "Keine Email Abonnements."
email_announcements: "Ankündigungen" email_announcements: "Ankündigungen"
email_announcements_description: "Erhalte regelmäßig Ankündigungen zu deinem Account." email_announcements_description: "Erhalte regelmäßig Ankündigungen zu deinem Account."
email_notifications: "Benachrichtigungen" email_notifications: "Benachrichtigungen"
@ -197,7 +197,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
error_saving: "Fehler beim Speichern" error_saving: "Fehler beim Speichern"
saved: "Änderungen gespeichert" saved: "Änderungen gespeichert"
password_mismatch: "Passwörter stimmen nicht überein." password_mismatch: "Passwörter stimmen nicht überein."
# password_repeat: "Please repeat your password." password_repeat: "Bitte wiederhole dein Passwort."
job_profile: "Jobprofil" job_profile: "Jobprofil"
job_profile_approved: "Dein Jobprofil wurde von CodeCombat freigegeben. Arbeitgeber können dieses solange einsehen, bis du es als inaktiv markiert oder wenn innerhalb von vier Wochen keine Änderung daran vorgenommen wurde." job_profile_approved: "Dein Jobprofil wurde von CodeCombat freigegeben. Arbeitgeber können dieses solange einsehen, bis du es als inaktiv markiert oder wenn innerhalb von vier Wochen keine Änderung daran vorgenommen wurde."
job_profile_explanation: "Hi! Fülle dies aus und wir melden uns bei dir bezüglich des Auffindens eines Jobs als Programmierer" job_profile_explanation: "Hi! Fülle dies aus und wir melden uns bei dir bezüglich des Auffindens eines Jobs als Programmierer"
@ -212,7 +212,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
profile_for_suffix: "" profile_for_suffix: ""
# featured: "Featured" # featured: "Featured"
# not_featured: "Not Featured" # not_featured: "Not Featured"
# looking_for: "Looking for:" looking_for: "Suche nach:"
last_updated: "zuletzt geändert:" last_updated: "zuletzt geändert:"
contact: "Kontakt" contact: "Kontakt"
# active: "Looking for interview offers now" # active: "Looking for interview offers now"
@ -359,13 +359,13 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
customize_wizard: "Bearbeite den Zauberer" customize_wizard: "Bearbeite den Zauberer"
home: "Startseite" home: "Startseite"
# stop: "Stop" # stop: "Stop"
# game_menu: "Game Menu" game_menu: "Spielmenü"
guide: "Hilfe" guide: "Hilfe"
restart: "Neustart" restart: "Neustart"
goals: "Ziele" goals: "Ziele"
# success: "Success!" success: "Erfolgreich!"
# incomplete: "Incomplete" incomplete: "Unvollständig"
# timed_out: "Ran out of time" timed_out: "Zeit abgelaufen"
# failing: "Failing" # failing: "Failing"
action_timeline: "Aktionszeitstrahl" action_timeline: "Aktionszeitstrahl"
click_to_select: "Klicke auf eine Einheit, um sie auszuwählen." click_to_select: "Klicke auf eine Einheit, um sie auszuwählen."
@ -425,7 +425,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
tip_impossible: "Es wirkt immer unmöglich bis es vollbracht ist. - Nelson Mandela" tip_impossible: "Es wirkt immer unmöglich bis es vollbracht ist. - Nelson Mandela"
tip_talk_is_cheap: "Reden ist billig. Zeig mir den Code. - Linus Torvalds" tip_talk_is_cheap: "Reden ist billig. Zeig mir den Code. - Linus Torvalds"
tip_first_language: "Das schwierigste, das du jemals lernen wirst, ist die erste Programmiersprache. - Alan Kay" tip_first_language: "Das schwierigste, das du jemals lernen wirst, ist die erste Programmiersprache. - Alan Kay"
# tip_hardware_problem: "Q: How many programmers does it take to change a light bulb? A: None, it's a hardware problem." tip_hardware_problem: "Q: Wie viele Programmierer braucht man um eine Glühbirne auszuwechseln? A: Keine, es ist ein Hardware-Problem."
time_current: "Aktuell" time_current: "Aktuell"
time_total: "Total" time_total: "Total"
time_goto: "Gehe zu" time_goto: "Gehe zu"
@ -435,17 +435,17 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
# game_menu: # game_menu:
# inventory_tab: "Inventory" # inventory_tab: "Inventory"
# choose_hero_tab: "Restart Level" choose_hero_tab: "Level neustarten"
# save_load_tab: "Save/Load" save_load_tab: "Speichere/Lade"
# options_tab: "Options" options_tab: "Optionen"
# guide_tab: "Guide" # guide_tab: "Guide"
# multiplayer_tab: "Multiplayer" multiplayer_tab: "Mehrspieler"
# inventory_caption: "Equip your hero" # inventory_caption: "Equip your hero"
# choose_hero_caption: "Choose hero, language" # choose_hero_caption: "Choose hero, language"
# save_load_caption: "... and view history" # save_load_caption: "... and view history"
# options_caption: "Configure settings" options_caption: "Konfiguriere Einstellungen"
# guide_caption: "Docs and tips" # guide_caption: "Docs and tips"
# multiplayer_caption: "Play with friends!" multiplayer_caption: "Spiele mit Freunden!"
# inventory: # inventory:
# temp: "Temp" # temp: "Temp"
@ -458,9 +458,9 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
# granularity_change_history: "History" # granularity_change_history: "History"
options: options:
# general_options: "General Options" general_options: "Allgemeine Einstellungen"
# music_label: "Music" music_label: "Musik"
# music_description: "Turn background music on/off." music_description: "Schalte Hintergrundmusik an/aus."
# autorun_label: "Autorun" # autorun_label: "Autorun"
# autorun_description: "Control automatic code execution." # autorun_description: "Control automatic code execution."
editor_config: "Editor Einstellungen" editor_config: "Editor Einstellungen"
@ -472,8 +472,8 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
editor_config_keybindings_label: "Tastenbelegung" editor_config_keybindings_label: "Tastenbelegung"
editor_config_keybindings_default: "Standard (Ace)" editor_config_keybindings_default: "Standard (Ace)"
editor_config_keybindings_description: "Fügt zusätzliche Tastenkombinationen, bekannt aus anderen Editoren, hinzu" editor_config_keybindings_description: "Fügt zusätzliche Tastenkombinationen, bekannt aus anderen Editoren, hinzu"
# editor_config_livecompletion_label: "Live Autocompletion" editor_config_livecompletion_label: "Live Auto-Vervollständigung"
# editor_config_livecompletion_description: "Displays autocomplete suggestions while typing." editor_config_livecompletion_description: "Zeigt Vorschläge der Auto-Vervollständigung an während du tippst."
editor_config_invisibles_label: "Zeige unsichtbare Zeichen" editor_config_invisibles_label: "Zeige unsichtbare Zeichen"
editor_config_invisibles_description: "Zeigt unsichtbare Zeichen wie Leertasten an." editor_config_invisibles_description: "Zeigt unsichtbare Zeichen wie Leertasten an."
editor_config_indentguides_label: "Zeige Einrückungshilfe" editor_config_indentguides_label: "Zeige Einrückungshilfe"
@ -485,9 +485,9 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
# temp: "Temp" # temp: "Temp"
multiplayer: multiplayer:
multiplayer_title: "Multiplayer Einstellungen" multiplayer_title: "Mehrspieler Einstellungen"
# multiplayer_toggle: "Enable multiplayer" # multiplayer_toggle: "Enable multiplayer"
# multiplayer_toggle_description: "Allow others to join your game." multiplayer_toggle_description: "Erlaube anderen an deinem Spiel teilzunehmen."
multiplayer_link_description: "Gib diesen Link jedem, der mitmachen will." multiplayer_link_description: "Gib diesen Link jedem, der mitmachen will."
multiplayer_hint_label: "Hinweis:" multiplayer_hint_label: "Hinweis:"
multiplayer_hint: " Klick den Link, um alles auszuwählen, dann drück ⌘-C oder Strg-C um den Link zu kopieren." multiplayer_hint: " Klick den Link, um alles auszuwählen, dann drück ⌘-C oder Strg-C um den Link zu kopieren."
@ -521,7 +521,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
av_entities_active_instances_url: "Aktive Instanzen" av_entities_active_instances_url: "Aktive Instanzen"
av_entities_employer_list_url: "Arbeitgeberliste" av_entities_employer_list_url: "Arbeitgeberliste"
av_other_sub_title: "Sonstige" av_other_sub_title: "Sonstige"
# av_other_debug_base_url: "Base (for debugging base.jade)" av_other_debug_base_url: "Base (um base.jade zu debuggen)"
u_title: "Benutzerliste" u_title: "Benutzerliste"
lg_title: "Letzte Spiele" lg_title: "Letzte Spiele"
# clas: "CLAs" # clas: "CLAs"
@ -535,7 +535,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
# thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites." # thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites."
# article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the" # article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the"
# article_editor_suffix: "and help CodeCombat players get the most out of their playtime." # article_editor_suffix: "and help CodeCombat players get the most out of their playtime."
# find_us: "Find us on these sites" find_us: "Finde uns auf diesen Seiten"
# contribute_to_the_project: "Contribute to the project" # contribute_to_the_project: "Contribute to the project"
editor: editor:
@ -547,8 +547,8 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
back: "Zurück" back: "Zurück"
revert: "Zurücksetzen" revert: "Zurücksetzen"
revert_models: "Models zurücksetzen." revert_models: "Models zurücksetzen."
# pick_a_terrain: "Pick A Terrain" pick_a_terrain: "Wähle ein Terrain"
# small: "Small" small: "Klein"
# grassy: "Grassy" # grassy: "Grassy"
fork_title: "Forke neue Version" fork_title: "Forke neue Version"
fork_creating: "Erzeuge Fork..." fork_creating: "Erzeuge Fork..."
@ -608,7 +608,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
general: general:
and: "und" and: "und"
name: "Name" name: "Name"
# date: "Date" date: "Datum"
body: "Inhalt" body: "Inhalt"
version: "Version" version: "Version"
commit_msg: "Commit Nachricht" commit_msg: "Commit Nachricht"
@ -685,20 +685,20 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
recruitment_description_suffix: "So wenn du deine Fähigkeiten entwickelt hast und zustimmst, werden wir deine besten Leistungen den tausenden Arbeitgebern demonstrieren, welche nur auf die Gelegentheit warten, dich einzustellen. Sie bezahlen uns ein bisschen, und sie bezahlen dir " recruitment_description_suffix: "So wenn du deine Fähigkeiten entwickelt hast und zustimmst, werden wir deine besten Leistungen den tausenden Arbeitgebern demonstrieren, welche nur auf die Gelegentheit warten, dich einzustellen. Sie bezahlen uns ein bisschen, und sie bezahlen dir "
recruitment_description_italic: "jede Menge" recruitment_description_italic: "jede Menge"
recruitment_description_ending: ", die Seite bleibt kostenlos und jeder ist glücklich. So der Plan." recruitment_description_ending: ", die Seite bleibt kostenlos und jeder ist glücklich. So der Plan."
# copyrights_title: "Copyrights and Licenses" copyrights_title: "Copyrights und Lizenzen"
# contributor_title: "Contributor License Agreement" # contributor_title: "Contributor License Agreement"
# contributor_description_prefix: "All contributions, both on the site and on our GitHub repository, are subject to our" # contributor_description_prefix: "All contributions, both on the site and on our GitHub repository, are subject to our"
# cla_url: "CLA" # cla_url: "CLA"
# contributor_description_suffix: "to which you should agree before contributing." # contributor_description_suffix: "to which you should agree before contributing."
# code_title: "Code - MIT" # code_title: "Code - MIT"
# code_description_prefix: "All code owned by CodeCombat or hosted on codecombat.com, both in the GitHub repository or in the codecombat.com database, is licensed under the" # code_description_prefix: "All code owned by CodeCombat or hosted on codecombat.com, both in the GitHub repository or in the codecombat.com database, is licensed under the"
# mit_license_url: "MIT license" mit_license_url: "MIT Lizenz"
# code_description_suffix: "This includes all code in Systems and Components that are made available by CodeCombat for the purpose of creating levels." # code_description_suffix: "This includes all code in Systems and Components that are made available by CodeCombat for the purpose of creating levels."
# art_title: "Art/Music - Creative Commons " # art_title: "Art/Music - Creative Commons "
# art_description_prefix: "All common content is available under the" # art_description_prefix: "All common content is available under the"
# cc_license_url: "Creative Commons Attribution 4.0 International License" # cc_license_url: "Creative Commons Attribution 4.0 International License"
# art_description_suffix: "Common content is anything made generally available by CodeCombat for the purpose of creating Levels. This includes:" # art_description_suffix: "Common content is anything made generally available by CodeCombat for the purpose of creating Levels. This includes:"
# art_music: "Music" art_music: "Musik"
# art_sound: "Sound" # art_sound: "Sound"
# art_artwork: "Artwork" # art_artwork: "Artwork"
# art_sprites: "Sprites" # art_sprites: "Sprites"
@ -733,7 +733,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
# alert_account_message: "To subscribe for class emails, you'll need to be logged in first." # alert_account_message: "To subscribe for class emails, you'll need to be logged in first."
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever." # archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever." # archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
# class_attributes: "Class Attributes" class_attributes: "Klassenattribute"
# archmage_attribute_1_pref: "Knowledge in " # archmage_attribute_1_pref: "Knowledge in "
# archmage_attribute_1_suf: ", or a desire to learn. Most of our code is in this language. If you're a fan of Ruby or Python, you'll feel right at home. It's JavaScript, but with a nicer syntax." # archmage_attribute_1_suf: ", or a desire to learn. Most of our code is in this language. If you're a fan of Ruby or Python, you'll feel right at home. It's JavaScript, but with a nicer syntax."
# archmage_attribute_2: "Some experience in programming and personal initiative. We'll help you get oriented, but we can't spend much time training you." # archmage_attribute_2: "Some experience in programming and personal initiative. We'll help you get oriented, but we can't spend much time training you."
@ -938,9 +938,9 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
document: "Dokument" document: "Dokument"
sprite_sheet: "Sprite Sheet" sprite_sheet: "Sprite Sheet"
candidate_sessions: "Kandidat-Sessions" candidate_sessions: "Kandidat-Sessions"
# user_remark: "User Remark" user_remark: "Benutzerkommentar"
# versions: "Versions" versions: "Versionen"
# items: "Items" items: "Gegenstände"
delta: delta:
added: "hinzugefügt" added: "hinzugefügt"
@ -948,15 +948,15 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
deleted: "gelöscht" deleted: "gelöscht"
# moved_index: "Moved Index" # moved_index: "Moved Index"
# text_diff: "Text Diff" # text_diff: "Text Diff"
# merge_conflict_with: "MERGE CONFLICT WITH" merge_conflict_with: "MERGE KONFLIKT MIT"
# no_changes: "No Changes" no_changes: "Keine Änderungen"
# user: # user:
# stats: "Stats" # stats: "Stats"
# singleplayer_title: "Singleplayer Levels" singleplayer_title: "Einzelspieler Levels"
# multiplayer_title: "Multiplayer Levels" multiplayer_title: "Mehrspieler Levels"
# achievements_title: "Achievements" # achievements_title: "Achievements"
# last_played: "Last Played" last_played: "Zuletzt gespielt"
# status: "Status" # status: "Status"
# status_completed: "Completed" # status_completed: "Completed"
# status_unfinished: "Unfinished" # status_unfinished: "Unfinished"

View file

@ -355,7 +355,6 @@
play_level: play_level:
done: "Done" done: "Done"
grid: "Grid"
customize_wizard: "Customize Wizard" customize_wizard: "Customize Wizard"
home: "Home" home: "Home"
stop: "Stop" stop: "Stop"
@ -908,6 +907,7 @@
unknown: "Unknown error." unknown: "Unknown error."
resources: resources:
sessions: "Sessions"
your_sessions: "Your Sessions" your_sessions: "Your Sessions"
level: "Level" level: "Level"
social_network_apis: "Social Network APIs" social_network_apis: "Social Network APIs"
@ -923,6 +923,7 @@
patched_model: "Source Document" patched_model: "Source Document"
model: "Model" model: "Model"
system: "System" system: "System"
systems: "Systems"
component: "Component" component: "Component"
components: "Components" components: "Components"
thang: "Thang" thang: "Thang"
@ -937,10 +938,16 @@
source_document: "Source Document" source_document: "Source Document"
document: "Document" document: "Document"
sprite_sheet: "Sprite Sheet" sprite_sheet: "Sprite Sheet"
employers: "Employers"
candidates: "Candidates"
candidate_sessions: "Candidate Sessions" candidate_sessions: "Candidate Sessions"
user_remark: "User Remark" user_remark: "User Remark"
user_remarks: "User Remarks"
versions: "Versions" versions: "Versions"
items: "Items" items: "Items"
wizard: "Wizard"
achievement: "Achievement"
clas: "CLAs"
delta: delta:
added: "Added" added: "Added"

View file

@ -358,7 +358,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
grid: "Grelha" grid: "Grelha"
customize_wizard: "Personalizar Feiticeiro" customize_wizard: "Personalizar Feiticeiro"
home: "Início" home: "Início"
# stop: "Stop" stop: "Parar"
game_menu: "Menu do Jogo" game_menu: "Menu do Jogo"
guide: "Guia" guide: "Guia"
restart: "Reiniciar" restart: "Reiniciar"
@ -499,9 +499,9 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
space: "Espaço" space: "Espaço"
enter: "Enter" enter: "Enter"
escape: "Esc" escape: "Esc"
# shift: "Shift" shift: "Shift"
cast_spell: "Lançar feitiço atual." cast_spell: "Lançar feitiço atual."
# run_real_time: "Run in real time." run_real_time: "Correr em tempo real."
continue_script: "Saltar o script atual." continue_script: "Saltar o script atual."
skip_scripts: "Saltar todos os scripts saltáveis." skip_scripts: "Saltar todos os scripts saltáveis."
toggle_playback: "Alternar entre Jogar e Pausar." toggle_playback: "Alternar entre Jogar e Pausar."

View file

@ -312,7 +312,7 @@ class CocoModel extends Backbone.Model
achievements = new NewAchievementCollection achievements = new NewAchievementCollection
achievements.fetch achievements.fetch
success: (collection) -> success: (collection) ->
me.fetch (success: -> Backbone.Mediator.publish('achievements:new', collection)) unless _.isEmpty(collection.models) me.fetch (success: -> Backbone.Mediator.publish('achievements:new', earnedAchievements: collection)) unless _.isEmpty(collection.models)
error: -> error: ->
console.error 'Miserably failed to fetch unnotified achievements', arguments console.error 'Miserably failed to fetch unnotified achievements', arguments

View file

@ -0,0 +1,17 @@
c = require './../schemas'
CLASubmissionSchema = c.object {
title: 'CLA Submission'
description: 'Recording when a user signed the CLA.'
}
_.extend CLASubmissionSchema.properties,
user: c.objectId links: [{rel: 'extra', href: '/db/user/{($)}'}]
email: c.shortString({format: 'email'})
name: {type: 'string'}
githubUsername: c.shortString()
created: c.date title: 'Created', readOnly: true
c.extendBasicProperties CLASubmissionSchema, 'user.remark'
module.exports = CLASubmissionSchema

View file

@ -65,7 +65,7 @@ GoalSchema = c.object {title: 'Goal', description: 'A goal that the player can a
ResponseSchema = c.object {title: 'Dialogue Button', description: 'A button to be shown to the user with the dialogue.', required: ['text']}, ResponseSchema = c.object {title: 'Dialogue Button', description: 'A button to be shown to the user with the dialogue.', required: ['text']},
text: {title: 'Title', description: 'The text that will be on the button', 'default': 'Okay', type: 'string', maxLength: 30} text: {title: 'Title', description: 'The text that will be on the button', 'default': 'Okay', type: 'string', maxLength: 30}
channel: c.shortString(title: 'Channel', format: 'event-channel', description: 'Channel that this event will be broadcast over, like "level-set-playing".') channel: c.shortString(title: 'Channel', format: 'event-channel', description: 'Channel that this event will be broadcast over, like "level:set-playing".')
event: {type: 'object', title: 'Event', description: 'Event that will be broadcast when this button is pressed, like {playing: true}.'} event: {type: 'object', title: 'Event', description: 'Event that will be broadcast when this button is pressed, like {playing: true}.'}
buttonClass: c.shortString(title: 'Button Class', description: 'CSS class that will be added to the button, like "btn-primary".') buttonClass: c.shortString(title: 'Button Class', description: 'CSS class that will be added to the button, like "btn-primary".')
i18n: {type: 'object', format: 'i18n', props: ['text'], description: 'Help translate this button'} i18n: {type: 'object', format: 'i18n', props: ['text'], description: 'Help translate this button'}

View file

@ -43,7 +43,7 @@ _.extend UserSchema.properties,
photoURL: {type: 'string', format: 'image-file', title: 'Profile Picture', description: 'Upload a 256x256px or larger image to serve as your profile picture.'} photoURL: {type: 'string', format: 'image-file', title: 'Profile Picture', description: 'Upload a 256x256px or larger image to serve as your profile picture.'}
facebookID: c.shortString({title: 'Facebook ID'}) facebookID: c.shortString({title: 'Facebook ID'})
githubID: c.shortString({title: 'GitHub ID'}) githubID: {type: 'integer', title: 'GitHub ID'}
gplusID: c.shortString({title: 'G+ ID'}) gplusID: c.shortString({title: 'G+ ID'})
wizardColor1: c.pct({title: 'Wizard Clothes Color'}) wizardColor1: c.pct({title: 'Wizard Clothes Color'})

View file

@ -1,45 +0,0 @@
module.exports =
'application: idle-changed':
{} # TODO schema
'fbapi-loaded':
{} # TODO schema
'logging-in-with-facebook':
{} # TODO schema
'facebook-logged-in':
title: 'Facebook logged in'
$schema: 'http://json-schema.org/draft-04/schema#'
description: 'Published when you successfully logged in with facebook'
type: 'object'
properties:
response:
type: 'object'
properties:
status: {type: 'string'}
authResponse:
type: 'object'
properties:
accessToken: {type: 'string'}
expiresIn: {type: 'number'}
signedRequest: {type: 'string'}
userID: {type: 'string'}
required: ['response']
'facebook-logged-out': {}
'linkedin-loaded': {}
'gapi-loaded':
{} # TODO schema
'logging-in-with-gplus':
{} # TODO schema
'gplus-logged-in':
title: 'G+ logged in'
$schema: 'http://json-schema.org/draft-04/schema#'
description: 'Published when you successfully logged in with G+'
type: 'object'
required: ['access_token']

View file

@ -0,0 +1,39 @@
c = require 'schemas/schemas'
module.exports =
'auth:me-synced': c.object {required: ['me']},
me: {type: 'object'}
'auth:facebook-api-loaded': c.object {}
'auth:logging-in-with-facebook': c.object {}
'auth:logged-in-with-facebook': c.object {title: 'Facebook logged in', description: 'Published when you successfully logged in with Facebook', required: ['response']},
response:
type: 'object'
properties:
status: {type: 'string'}
authResponse:
type: 'object'
properties:
accessToken: {type: 'string'}
expiresIn: {type: 'number'}
signedRequest: {type: 'string'}
userID: {type: 'string'}
'auth:linkedin-api-loaded': c.object {}
'auth:gplus-api-loaded': c.object {}
'auth:logging-in-with-gplus': c.object {}
'auth:logged-in-with-gplus':
title: 'G+ logged in'
description: 'Published when you successfully logged in with G+'
type: 'object'
required: ['access_token']
properties:
access_token: {type: 'string'}
# Could be some other stuff
'auth:log-in-with-github': c.object {}

View file

@ -1,71 +1,27 @@
c = require 'schemas/schemas'
module.exports = module.exports =
'bus:connecting': 'bus:connecting': c.object {title: 'Bus Connecting', description: 'Published when a Bus starts connecting'},
title: 'Bus Connecting' bus: {$ref: 'bus'}
$schema: 'http://json-schema.org/draft-04/schema#'
description: 'Published when a Bus starts connecting'
type: 'object'
properties:
bus:
$ref: 'bus'
'bus:connected': 'bus:connected': c.object {title: 'Bus Connected', description: 'Published when a Bus has connected'},
title: 'Bus Connected' bus: {$ref: 'bus'}
$schema: 'http://json-schema.org/draft-04/schema#'
description: 'Published when a Bus has connected'
type: 'object'
properties:
bus:
$ref: 'bus'
'bus:disconnected': 'bus:disconnected': c.object {title: 'Bus Disconnected', description: 'Published when a Bus has disconnected'},
title: 'Bus Disconnected' bus: {$ref: 'bus'}
$schema: 'http://json-schema.org/draft-04/schema#'
description: 'Published when a Bus has disconnected'
type: 'object'
properties:
bus:
$ref: 'bus'
'bus:new-message': 'bus:new-message': c.object {title: 'Message sent', description: 'A new message was sent'},
title: 'Message sent' message: {type: 'object'}
$schema: 'http://json-schema.org/draft-04/schema#' bus: {$ref: 'bus'}
description: 'A new message was sent'
type: 'object'
properties:
message:
type: 'object'
bus:
$ref: 'bus'
'bus:player-joined': 'bus:player-joined': c.object {title: 'Player joined', description: 'A new player has joined'},
title: 'Player joined' player: {type: 'object'}
$schema: 'http://json-schema.org/draft-04/schema#' bus: {$ref: 'bus'}
description: 'A new player has joined'
type: 'object'
properties:
player:
type: 'object'
bus:
$ref: 'bus'
'bus:player-left': 'bus:player-left': c.object {title: 'Player left', description: 'A player has left'},
title: 'Player left' player: {type: 'object'}
$schema: 'http://json-schema.org/draft-04/schema#' bus: {$ref: 'bus'}
description: 'A player has left'
type: 'object'
properties:
player:
type: 'object'
bus:
$ref: 'bus'
'bus:player-states-changed': 'bus:player-states-changed': c.object {title: 'Player state changes', description: 'State of the players has changed'},
title: 'Player state changes' states: c.array {}, {type: 'object'}
$schema: 'http://json-schema.org/draft-04/schema#' bus: {$ref: 'bus'}
description: 'State of the players has changed'
type: 'object'
properties:
player:
type: 'array'
bus:
$ref: 'bus'

View file

@ -1,78 +1,43 @@
c = require 'schemas/schemas'
module.exports = module.exports =
'save-new-version': 'editor:save-new-version': c.object {title: 'Save New Version', description: 'Published when a version gets saved', required: ['major', 'commitMessage']},
title: 'Save New Version' major: {type: 'boolean'}
$schema: 'http://json-schema.org/draft-04/schema#' commitMessage: {type: 'string'}
description: 'Published when a version gets saved'
type: 'object'
properties:
major:
type: 'boolean'
commitMessage:
type: 'string'
required: ['major', 'commitMessage']
additionalProperties: false
# TODO all these events starting with 'level:' should have 'editor' in their name 'editor:view-switched': c.object {title: 'Level View Switched', description: 'Published whenever the view switches'}
# to avoid confusion with level play events
'level:view-switched': 'editor:level-component-editing-ended': c.object {required: ['component']},
title: 'Level View Switched' component: {type: 'object'}
$schema: 'http://json-schema.org/draft-04/schema#'
description: 'Published whenever the view switches'
$ref: 'jQueryEvent'
'level-components-changed': 'editor:edit-level-system': c.object {required: ['original', 'majorVersion']},
{} # TODO schema original: {type: 'string'}
majorVersion: {type: 'integer', minimum: 0}
'edit-level-component': 'editor:level-system-added': c.object {required: ['system']},
{} # TODO schema system: {type: 'object'}
'level-component-edited': 'editor:level-system-editing-ended': c.object {required: ['system']},
{} # TODO schema system: {type: 'object'}
'level-component-editing-ended': 'editor:edit-level-thang': c.object {required: ['thangID']},
{} # TODO schema thangID: {type: 'string'}
'level-systems-changed': 'editor:level-thang-edited': c.object {required: ['thangID', 'thangData']},
{} # TODO schema thangID: {type: 'string'}
thangData: {type: 'object'}
'edit-level-system': 'editor:level-thang-done-editing': c.object {}
{} # TODO schema
'level-system-added': 'editor:level-loaded': c.object {required: ['level']},
{} # TODO schema level: {type: 'object'}
'level-system-edited': 'level:reload-from-data': c.object {required: ['level', 'supermodel']},
{} # TODO schema level: {type: 'object'}
supermodel: {type: 'object'}
'level-system-editing-ended': 'level:reload-thang-type': c.object {required: ['thangType']},
{} # TODO schema thangType: {type: 'object'}
'level-thangs-changed': 'editor:random-terrain-generated': c.object {required: ['thangs']},
title: 'Level Thangs Changed' thangs: c.array {}, {type: 'object'}
$schema: 'http://json-schema.org/draft-04/schema#'
description: 'Published when a Thang changes'
type: 'object'
properties:
thangsData:
type: 'array'
required: ['thangsData']
additionalProperties: false
'edit-level-thang':
{} # TODO schema
'level-thang-edited':
{} # TODO schema
'level-thang-done-editing':
{} # TODO schema
'level-loaded':
{} # TODO schema
'level-reload-from-data':
{} # TODO schema
'save-new-version':
{} # TODO schema

View file

@ -1,4 +1,6 @@
c = require 'schemas/schemas'
module.exports = module.exports =
# app/lib/errors # app/lib/errors
'server-error': 'errors:server-error': c.object {required: ['response']},
{} # TODO schema response: {type: 'object'}

View file

@ -0,0 +1,53 @@
c = require 'schemas/schemas'
goalStatesSchema =
type: 'object'
additionalProperties:
type: 'object'
required: ['status']
properties:
status:
oneOf: [
{type: 'null'}
{type: 'string', enum: ['success', 'failure', 'incomplete']}
]
keyFrame:
oneOf: [
{type: 'integer', minimum: 0}
{type: 'string', enum: ['end']}
]
team: {type: ['null', 'string']}
worldUpdatedEventSchema = c.object {required: ['world', 'firstWorld', 'goalStates', 'team', 'firstChangedFrame']},
world: {type: 'object'}
firstWorld: {type: 'boolean'}
goalStates: goalStatesSchema
team: {type: 'string'}
firstChangedFrame: {type: 'integer', minimum: 0}
module.exports =
'god:user-code-problem': c.object {required: ['problem']},
problem: {type: 'object'}
'god:non-user-code-problem': c.object {required: ['problem']},
problem: {type: 'object'}
'god:infinite-loop': c.object {required: ['firstWorld']},
firstWorld: {type: 'boolean'}
'god:new-world-created': worldUpdatedEventSchema
'god:streaming-world-updated': worldUpdatedEventSchema
'god:goals-calculated': c.object {required: ['goalStates']},
goalStates: goalStatesSchema
'god:world-load-progress-changed': c.object {required: ['progress']},
progress: {type: 'number', minimum: 0, maximum: 1}
'god:debug-world-load-progress-changed': c.object {required: ['progress']},
progress: {type: 'number', minimum: 0, maximum: 1}
'god:debug-value-return': c.object {required: ['key']},
key: {type: 'string'}
value: {type: 'any'}

View file

@ -1,23 +1,29 @@
c = require 'schemas/schemas'
module.exports = module.exports =
'audio-played:loaded': 'application:idle-changed': c.object {},
{} # TODO schema idle: {type: 'boolean'}
# TODO location is debatable 'audio-player:loaded': c.object {required: ['sender']},
'note-group-started': sender: {type: 'object'}
{} # TODO schema
'note-group-ended': 'audio-player:play-sound': c.object {required: ['trigger']},
{} # TODO schema trigger: {type: 'string'}
volume: {type: 'number', minimum: 0, maximum: 1}
'modal-opened': 'music-player:play-music': c.object {required: ['play']},
{} # TODO schema play: {type: 'boolean'}
file: {type: 'string'}
'modal-closed': 'modal:opened': c.object {}
{} # TODO schema
# TODO I propose prepending 'modal:' 'modal:closed': c.object {}
'save-new-version':
{} # TODO schema
'router:navigate': 'router:navigate': c.object {required: ['route']},
{} # TODO schema route: {type: 'string'}
view: {type: 'object'}
viewClass: {type: 'object'}
viewArgs: {type: 'array'}
'achievements:new': c.object {required: 'earnedAchievements'},
earnedAchievements: {type: 'object'}

View file

@ -1,206 +1,153 @@
c = require 'schemas/schemas'
module.exports = module.exports =
# TODO There should be a better way to divide these channels into smaller ones # TODO There should be a better way to divide these channels into smaller ones
# TODO location is debatable 'level:session-will-save': c.object {required: ['session']},
'echo-self-wizard-sprite': session: {type: 'object'}
{} # TODO schema
'level:session-will-save': 'level:shift-space-pressed': c.object {}
{} # TODO schema
'level-loader:progress-changed': 'level:escape-pressed': c.object {}
{} # TODO schema
'level:shift-space-pressed': 'level:enable-controls': c.object {},
{} # TODO schema controls: c.array {},
c.shortString()
'level:escape-pressed': 'level:disable-controls': c.object {},
{} # TODO schema controls: c.array {},
c.shortString()
'level-enable-controls':
{} # TODO schema
'level-set-letterbox': 'level:set-letterbox': c.object {},
{} # TODO schema on: {type: 'boolean'}
'level:started': 'level:started': c.object {}
{} # TODO schema
'level-set-debug': 'level:set-debug': c.object {required: ['debug']},
{} # TODO schema debug: {type: 'boolean'}
'level-set-grid': 'level:restart': c.object {}
{} # TODO schema
'level:restarted': 'level:restarted': c.object {}
{} # TODO schema
'level-set-volume': 'level:set-volume': c.object {required: ['volume']},
{} # TODO schema volume: {type: 'number', minimum: 0, maximum: 1}
'level-set-time': 'level:set-time': c.object {},
{} # TODO schema time: {type: 'number', minimum: 0}
ratio: {type: 'number', minimum: 0, maximum: 1}
frameOffset: {type: 'integer'}
scrubDuration: {type: 'integer', minimum: 0}
'level-select-sprite': 'level:select-sprite': c.object {},
{} # TODO schema thangID: {type: ['string', 'null', 'undefined']}
spellName: {type: ['string', 'null', 'undefined']}
'level-set-playing': 'level:set-playing': c.object {required: ['playing']},
{} # TODO schema playing: {type: 'boolean'}
'level:team-set': 'level:team-set': c.object {required: ['team']},
{} # TODO schema team: c.shortString()
'level:docs-shown': {} 'level:docs-shown': c.object {}
'level:docs-hidden': {} 'level:docs-hidden': c.object {}
'level:victory-hidden': 'level:flag-color-selected': c.object {},
{} # TODO schema
'level:flag-color-selected':
type: 'object'
additionalProperties: false
properties:
color: color:
oneOf: [ oneOf: [
{type: 'null'} {type: 'null'}
{type: 'string', enum: ['green', 'black', 'violet'], description: 'The flag color to place next, or omitted/null if deselected.'} {type: 'string', enum: ['green', 'black', 'violet'], description: 'The flag color to place next, or omitted/null if deselected.'}
] ]
pos: pos: c.object {required: ['x', 'y']},
type: 'object'
additionalProperties: false
required: ['x', 'y']
properties:
x: {type: 'number'} x: {type: 'number'}
y: {type: 'number'} y: {type: 'number'}
'level:flag-updated': 'level:flag-updated': c.object {required: ['player', 'color', 'time', 'active']},
type: 'object' player: {type: 'string'}
additionalProperties: false team: {type: 'string'}
required: ['player', 'color', 'time', 'active'] color: {type: 'string', enum: ['green', 'black', 'violet']}
properties: time: {type: 'number', minimum: 0}
player: active: {type: 'boolean'}
type: 'string' pos: c.object {required: ['x', 'y']},
team:
type: 'string'
color:
type: 'string'
enum: ['green', 'black', 'violet']
time:
type: 'number'
minimum: 0
active:
type: 'boolean'
pos:
type: 'object'
additionalProperties: false
required: ['x', 'y']
properties:
x: {type: 'number'} x: {type: 'number'}
y: {type: 'number'} y: {type: 'number'}
'next-game-pressed': 'level:next-game-pressed': c.object {}
{} # TODO schema
'end-current-script': 'level:loading-view-unveiled': c.object {required: ['view']},
{} # TODO schema view: {type: 'object'}
'script:reset': 'playback:manually-scrubbed': c.object {required: ['ratio']},
{} # TODO schema ratio: {type: 'number', minimum: 0, maximum: 1}
'script:ended': 'playback:stop-real-time-playback': c.object {}
{} # TODO schema
'end-all-scripts': {} 'playback:real-time-playback-started': c.object {}
'script:state-changed': 'playback:real-time-playback-ended': c.object {}
{} # TODO schema
'script-manager:tick': 'level:play-next-level': c.object {}
type: 'object'
additionalProperties: false
properties:
scriptRunning: {type: 'string'}
noteGroupRunning: {type: 'string'}
timeSinceLastScriptEnded: {type: 'number'}
scriptStates:
type: 'object'
additionalProperties:
title: 'Script State'
type: 'object'
additionalProperties: false
properties:
timeSinceLastEnded:
type: 'number'
description: 'seconds since this script ended last'
timeSinceLastTriggered:
type: 'number'
description: 'seconds since this script was triggered last'
'play-sound': 'level:toggle-playing': c.object {}
{} # TODO schema
# TODO refactor name 'level:toggle-grid': c.object {}
'onLoadingViewUnveiled':
{} # TODO schema
'playback:manually-scrubbed': 'level:toggle-debug': c.object {}
{} # TODO schema
'playback:stop-real-time-playback': 'level:toggle-pathfinding': c.object {}
type: 'object'
additionalProperties: false
'playback:real-time-playback-started': 'level:scrub-forward': c.object {}
type: 'object'
additionalProperties: false
'playback:real-time-playback-ended': 'level:scrub-back': c.object {}
type: 'object'
additionalProperties: false
'change:editor-config': 'level:show-victory': c.object {required: ['showModal']},
{} # TODO schema
'restart-level':
{} # TODO schema
'play-next-level':
{} # TODO schema
'level-select-sprite':
{} # TODO schema
'level-toggle-grid':
{} # TODO schema
'level-toggle-debug':
{} # TODO schema
'level-toggle-pathfinding':
{} # TODO schema
'level-scrub-forward':
{} # TODO schema
'level-scrub-back':
{} # TODO schema
'level-show-victory':
type: 'object'
additionalProperties: false
properties:
showModal: {type: 'boolean'} showModal: {type: 'boolean'}
'level-highlight-dom': 'level:highlight-dom': c.object {required: ['selector']},
type: 'object'
additionalProperties: false
properties:
selector: {type: 'string'} selector: {type: 'string'}
delay: {type: 'number'} delay: {type: 'number'}
sides: {type: 'array', items: {'enum': ['left', 'right', 'top', 'bottom']}} sides: {type: 'array', items: {'enum': ['left', 'right', 'top', 'bottom']}}
offset: {type: 'object'} offset: {type: 'object'}
rotation: {type: 'number'} rotation: {type: 'number'}
'goal-manager:new-goal-states': 'level:end-highlight-dom': c.object {}
{} # TODO schema
'level:focus-dom': c.object {},
selector: {type: 'string'}
'level:lock-select': c.object {},
lock: {type: ['boolean', 'array']}
'level:suppress-selection-sounds': c.object {required: ['suppress']},
suppress: {type: 'boolean'}
'goal-manager:new-goal-states': c.object {required: ['goalStates', 'goals', 'overallStatus', 'timedOut']},
goalStates:
type: 'object'
additionalProperties:
type: 'object'
required: ['status']
properties:
status:
oneOf: [
{type: 'null'}
{type: 'string', enum: ['success', 'failure', 'incomplete']}
]
keyFrame:
oneOf: [
{type: 'integer', minimum: 0}
{type: 'string', enum: ['end']}
]
team: {type: ['null', 'string']}
goals: c.array {},
{type: 'object'}
overallStatus:
oneOf: [
{type: 'null'}
{type: 'string', enum: ['success', 'failure', 'incomplete']}
]
timedOut: {type: 'boolean'}
'level:edit-wizard-settings': c.object {}

View file

@ -0,0 +1,27 @@
c = require 'schemas/schemas'
module.exports =
'script:end-current-script': c.object {}
'script:reset': c.object {}
'script:ended': c.object {required: ['scriptID']},
scriptID: {type: 'string'}
'script:state-changed': c.object {required: ['currentScript', 'currentScriptOffset']},
currentScript: {type: ['string', 'null']}
currentScriptOffset: {type: 'integer', minimum: 0}
'script:tick': c.object {required: ['scriptRunning', 'noteGroupRunning', 'scriptStates', 'timeSinceLastScriptEnded']},
scriptRunning: {type: 'string'}
noteGroupRunning: {type: 'string'}
timeSinceLastScriptEnded: {type: 'number'}
scriptStates:
type: 'object'
additionalProperties: c.object {title: 'Script State'},
timeSinceLastEnded: {type: 'number', minimum: 0, description: 'seconds since this script ended last'}
timeSinceLastTriggered: {type: 'number', minimum: 0, description: 'seconds since this script was triggered last'}
'script:note-group-started': c.object {}
'script:note-group-ended': c.object {}

View file

@ -1,108 +1,180 @@
c = require 'schemas/schemas'
spriteMouseEventSchema = c.object {required: ['sprite', 'thang', 'originalEvent', 'canvas']},
sprite: {type: 'object'}
thang: {type: 'object'}
originalEvent: {type: 'object'}
canvas: {type: 'object'}
module.exports = # /app/lib/surface module.exports = # /app/lib/surface
'camera-dragged': 'camera:dragged': c.object {}
{} # TODO schema
'camera-zoom-in': 'camera:zoom-in': c.object {}
{} # TODO schema
'camera-zoom-out': 'camera:zoom-out': c.object {}
{} # TODO schema
'camera-zoom-to': 'camera:zoom-to': c.object {required: ['pos']},
{} # TODO schema pos: c.object {required: ['x', 'y']},
x: {type: 'number'}
y: {type: 'number'}
duration: {type: 'number', minimum: 0}
'camera:zoom-updated': 'camera:zoom-updated': c.object {required: ['camera', 'zoom', 'surfaceViewport']},
{} # TODO schema camera: {type: 'object'}
zoom: {type: 'number', minimum: 0, exclusiveMinimum: true}
surfaceViewport: {type: 'object'}
'sprite:speech-updated': 'camera:set-camera': c.object {},
{} # TODO schema pos: c.object {required: ['x', 'y']},
x: {type: 'number'}
y: {type: 'number'}
thangID: {type: 'string'}
zoom: {type: 'number'}
duration: {type: 'number', minimum: 0}
bounds: c.array {maxItems: 2, minItems: 2},
c.object {required: ['x', 'y']},
x: {type: 'number'}
y: {type: 'number'}
'dialogue-sound-completed': 'sprite:speech-updated': c.object {required: ['sprite', 'thang']},
{} # TODO schema sprite: {type: 'object'}
thang: {type: 'object'}
blurb: {type: 'string'}
message: {type: 'string'}
mood: {type: 'string'}
responses: {type: 'array'}
spriteID: {type: 'string'}
sound: {type: ['null', 'undefined', 'object']}
'surface:gold-changed': 'level:sprite-dialogue': c.object {required: ['spriteID', 'message']},
{} # TODO schema blurb: {type: 'string'}
message: {type: 'string'}
mood: {type: 'string'}
responses: {type: 'array'}
spriteID: {type: 'string'}
sound: {type: ['null', 'undefined', 'object']}
'surface:coordinate-selected': 'sprite:dialogue-sound-completed': c.object {}
{} # TODO schema
'surface:coordinates-shown': 'level:sprite-clear-dialogue': c.object {}
{} # TODO schema
'level-sprite-clear-dialogue': 'surface:gold-changed': c.object {required: ['team', 'gold']},
{} # TODO schema team: {type: 'string'}
gold: {type: 'number'}
goldEarned: {type: 'number'}
'sprite:loaded': 'surface:coordinate-selected': c.object {required: ['x', 'y']},
{} # TODO schema x: {type: 'number'}
y: {type: 'number'}
'choose-point': 'surface:coordinates-shown': c.object {}
{} # TODO schema
'choose-region': 'sprite:loaded': c.object {},
{} # TODO schema sprite: {type: 'object'}
'surface:new-thang-added': 'surface:choose-point': c.object {required: ['point']},
{} # TODO schema point: c.object {required: ['x', 'y']},
x: {type: 'number'}
y: {type: 'number'}
'surface:sprite-selected': 'surface:choose-region': c.object {required: ['points']},
{} # TODO schema points: c.array {minItems: 2, maxItems: 2},
c.object {required: ['x', 'y']},
x: {type: 'number'}
y: {type: 'number'}
'thang-began-talking': 'surface:new-thang-added': c.object {required: ['thang', 'sprite']},
{} # TODO schema thang: {type: 'object'}
sprite: {type: 'object'}
'thang-finished-talking': 'surface:sprite-selected': c.object {required: ['thang', 'sprite']},
{} # TODO schema thang: {type: ['object', 'null', 'undefined']}
sprite: {type: ['object', 'null', 'undefined']}
spellName: {type: ['string', 'null', 'undefined']}
originalEvent: {type: ['object', 'null', 'undefined']}
worldPos: {type: ['object', 'null', 'undefined']}
'surface:world-set-up': 'sprite:thang-began-talking': c.object {},
{} # TODO schema thang: {type: 'object'}
'surface:frame-changed': 'sprite:thang-finished-talking': c.object {},
{} # TODO schema thang: {type: 'object'}
'surface:playback-ended': 'sprite:highlight-sprites': c.object {},
{} # TODO schema thangIDs: c.array {}, {type: 'string'}
delay: {type: 'number'}
'surface:playback-restarted': 'sprite:move': c.object {required: ['spriteID', 'pos']},
{} # TODO schema spriteID: {type: 'string'}
pos: c.object {required: ['x', 'y']},
x: {type: 'number'}
y: {type: 'number'}
duration: {type: 'number', minimum: 0}
'level-set-playing': 'sprite:mouse-down': spriteMouseEventSchema
{} # TODO schema 'sprite:clicked': spriteMouseEventSchema
'sprite:double-clicked': spriteMouseEventSchema
'sprite:dragged': spriteMouseEventSchema
'sprite:mouse-up': spriteMouseEventSchema
'registrar-echo-states': 'surface:world-set-up': c.object {},
{} # TODO schema world: {type: 'object'}
'surface:mouse-moved': 'surface:frame-changed': c.object {required: ['frame', 'world', 'progress']},
{} # TODO schema frame: {type: 'number', minimum: 0}
world: {type: 'object'}
progress: {type: 'number', minimum: 0, maximum: 1}
selectedThang: {type: ['object', 'null', 'undefined']}
'surface:stage-mouse-down': 'surface:playback-ended': c.object {}
{} # TODO schema
'surface:mouse-scrolled': 'surface:playback-restarted': c.object {}
{} # TODO schema
'surface:ticked': 'surface:mouse-moved': c.object {required: ['x', 'y']},
{} # TODO schema x: {type: 'number'}
y: {type: 'number'}
'surface:mouse-over': 'surface:stage-mouse-down': c.object {required: ['onBackground', 'x', 'y', 'originalEvent']},
{} # TODO schema onBackground: {type: 'boolean'}
x: {type: 'number'}
y: {type: 'number'}
originalEvent: {type: 'object'}
worldPos: {type: ['object', 'null', 'undefined']}
'surface:mouse-out': 'surface:stage-mouse-up': c.object {required: ['onBackground', 'x', 'y', 'originalEvent']},
{} # TODO schema onBackground: {type: 'boolean'}
x: {type: 'number'}
y: {type: 'number'}
originalEvent: {type: 'object'}
'self-wizard:target-changed': 'surface:mouse-scrolled': c.object {required: ['deltaX', 'deltaY', 'screenPos', 'canvas']},
{} # TODO schema deltaX: {type: 'number'}
deltaY: {type: 'number'}
screenPos: c.object {required: ['x', 'y']},
x: {type: 'number'}
y: {type: 'number'}
canvas: {type: 'object'}
'echo-all-wizard-sprites': 'surface:ticked': c.object {required: ['dt']},
{} # TODO schema dt: {type: 'number'}
'surface:flag-appeared': 'surface:mouse-over': c.object {}
type: 'object'
additionalProperties: false
required: ['sprite']
properties:
sprite:
type: 'object'
'surface:remove-selected-flag': 'surface:mouse-out': c.object {}
type: 'object'
additionalProperties: false 'sprite:echo-all-wizard-sprites': c.object {required: ['payload']},
payload: c.array {}, {type: 'object'}
'self-wizard:created': c.object {required: ['sprite']},
sprite: {type: 'object'}
'self-wizard:target-changed': c.object {required: ['sprite']},
sprite: {type: 'object'}
'surface:flag-appeared': c.object {required: ['sprite']},
sprite: {type: 'object'}
'surface:remove-selected-flag': c.object {}
'surface:remove-flag': c.object {required: 'color'},
color: {type: 'string'}

View file

@ -1,277 +1,109 @@
c = require 'schemas/schemas'
module.exports = module.exports =
"tome:cast-spell": 'tome:cast-spell': c.object {title: 'Cast Spell', description: 'Published when a spell is cast', required: ['spell', 'thang', 'preload', 'realTime']},
title: "Cast Spell" spell: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#" thang: {type: 'object'}
description: "Published when a spell is cast" preload: {type: 'boolean'}
type: ["object", "undefined"] realTime: {type: 'boolean'}
properties:
spell:
type: "object"
thang:
type: "object"
preload:
type: "boolean"
realTime:
type: "boolean"
required: []
additionalProperties: false
"tome:cast-spells": 'tome:cast-spells': c.object {title: 'Cast Spells', description: 'Published when spells are cast', required: ['spells', 'preload', 'realTime']},
title: "Cast Spells" spells: [type: 'object']
$schema: "http://json-schema.org/draft-04/schema#" preload: [type: 'boolean']
description: "Published when spells are cast" realTime: [type: 'boolean']
type: ["object", "undefined"]
properties:
spells:
type: "object"
preload:
type: "boolean"
realTime:
type: "boolean"
required: []
additionalProperties: false
"tome:manual-cast": 'tome:manual-cast': c.object {title: 'Manually Cast Spells', description: 'Published when you wish to manually recast all spells', required: []},
title: "Manually Cast Spells" realTime: {type: 'boolean'}
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when you wish to manually recast all spells"
type: "object"
properties:
realTime:
type: "boolean"
required: []
additionalProperties: false
"tome:spell-created": 'tome:spell-created': c.object {title: 'Spell Created', description: 'Published after a new spell has been created', required: ['spell']},
title: "Spell Created" spell: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published after a new spell has been created"
type: "object"
properties:
"spell": "object"
required: ["spell"]
additionalProperties: false
"tome:spell-debug-property-hovered": 'tome:spell-has-changed-significantly-calculation': c.object {title: 'Has Changed Significantly Calculation', description: 'Let anyone know that the spell has changed significantly.', required: ['hasChangedSignificantly']},
title: "Spell Debug Property Hovered" hasChangedSignificantly: {type: 'boolean'}
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when you hover over a spell property"
type: "object"
properties:
"property": "string"
"owner": "string"
required: []
additionalProperties: false
"tome:toggle-spell-list": 'tome:spell-debug-property-hovered': c.object {title: 'Spell Debug Property Hovered', description: 'Published when you hover over a spell property', required: []},
title: "Toggle Spell List" property: {type: 'string'}
$schema: "http://json-schema.org/draft-04/schema#" owner: {type: 'string'}
description: "Published when you toggle the dropdown for a thang's spells"
type: "undefined"
additionalProperties: false
"tome:reload-code": 'tome:spell-debug-value-request': c.object {title: 'Spell Debug Value Request', description: 'Published when the SpellDebugView wants to retrieve a debug value.', required: ['thangID', 'spellID', 'variableChain', 'frame']},
title: "Reload Code" thangID: {type: 'string'}
$schema: "http://json-schema.org/draft-04/schema#" spellID: {type: 'string'}
description: "Published when you reset a spell to its original source" variableChain: c.array {}, {type: 'string'}
type: "object" frame: {type: 'integer', minimum: 0}
properties:
"spell": "object"
required: ["spell"]
additionalProperties: false
"tome:palette-hovered": 'tome:toggle-spell-list': c.object {title: 'Toggle Spell List', description: 'Published when you toggle the dropdown for a thang\'s spells'}
title: "Palette Hovered"
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when you hover over a Thang in the spell palette"
type: "object"
properties:
"thang": "object"
"prop": "string"
"entry": "object"
required: ["thang", "prop", "entry"]
additionalProperties: false
"tome:palette-pin-toggled": 'tome:reload-code': c.object {title: 'Reload Code', description: 'Published when you reset a spell to its original source', required: ['spell']},
title: "Palette Pin Toggled" spell: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when you pin or unpin the spell palette"
type: "object"
properties:
"entry": "object"
"pinned": "boolean"
required: ["entry", "pinned"]
additionalProperties: false
"tome:palette-clicked": 'tome:palette-hovered': c.object {title: 'Palette Hovered', description: 'Published when you hover over a Thang in the spell palette', required: ['thang', 'prop', 'entry']},
title: "Palette Clicked" thang: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#" prop: {type: 'string'}
description: "Published when you click on the spell palette" entry: {type: 'object'}
type: "object"
properties:
"thang": "object"
"prop": "string"
"entry": "object"
required: ["thang", "prop", "entry"]
additionalProperties: false
"tome:spell-statement-index-updated": 'tome:palette-pin-toggled': c.object {title: 'Palette Pin Toggled', description: 'Published when you pin or unpin the spell palette', required: ['entry', 'pinned']},
title: "Spell Statement Index Updated" entry: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#" pinned: {type: 'boolean'}
description: "Published when the spell index is updated"
type: "object"
properties:
"statementIndex": "object"
"ace": "object"
required: ["statementIndex", "ace"]
additionalProperties: false
# TODO proposition: refactor 'tome' into spell events 'tome:palette-clicked': c.object {title: 'Palette Clicked', description: 'Published when you click on the spell palette', required: ['thang', 'prop', 'entry']},
"spell-beautify": thang: {type: 'object'}
title: "Beautify" prop: {type: 'string'}
$schema: "http://json-schema.org/draft-04/schema#" entry: {type: 'object'}
description: "Published when you click the \"beautify\" button"
type: "object"
properties:
"spell": "object"
required: []
additionalProperties: false
"spell-step-forward": 'tome:spell-statement-index-updated': c.object {title: 'Spell Statement Index Updated', description: 'Published when the spell index is updated', required: ['statementIndex', 'ace']},
title: "Step Forward" statementIndex: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#" ace: {type: 'object'}
description: "Published when you step forward in time"
type: "undefined"
additionalProperties: false
"spell-step-backward": 'tome:spell-beautify': c.object {title: 'Beautify', description: 'Published when you click the \'beautify\' button', required: []},
title: "Step Backward" spell: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when you step backward in time"
type: "undefined"
additionalProperties: false
"tome:spell-loaded": 'tome:spell-step-forward': c.object {title: 'Step Forward', description: 'Published when you step forward in time'}
title: "Spell Loaded"
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when a spell is loaded"
type: "object"
properties:
"spell": "object"
required: ["spell"]
additionalProperties: false
"tome:spell-changed": 'tome:spell-step-backward': c.object {title: 'Step Backward', description: 'Published when you step backward in time'}
title: "Spell Changed"
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when a spell is changed"
type: "object"
properties:
"spell": "object"
required: ["spell"]
additionalProperties: false
"tome:editing-began": 'tome:spell-loaded': c.object {title: 'Spell Loaded', description: 'Published when a spell is loaded', required: ['spell']},
title: "Editing Began" spell: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when you have begun changing code"
type: "undefined"
additionalProperties: false
"tome:editing-ended": 'tome:spell-changed': c.object {title: 'Spell Changed', description: 'Published when a spell is changed', required: ['spell']},
title: "Editing Ended" spell: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when you have stopped changing code"
type: "undefined"
additionalProperties: false
"tome:problems-updated": 'tome:editing-began': c.object {title: 'Editing Began', description: 'Published when you have begun changing code'}
title: "Problems Updated"
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when problems have been updated"
type: "object"
properties:
"spell": "object"
"problems": "array"
"isCast": "boolean"
required: ["spell", "problems", "isCast"]
additionalProperties: false
"tome:thang-list-entry-popover-shown": 'tome:editing-ended': c.object {title: 'Editing Ended', description: 'Published when you have stopped changing code'}
title: "Thang List Entry Popover Shown"
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when we show the popover for a thang in the master list"
type: "object"
properties:
"entry": "object"
required: ["entry"]
additionalProperties: false
"tome:spell-shown": 'tome:problems-updated': c.object {title: 'Problems Updated', description: 'Published when problems have been updated', required: ['spell', 'problems', 'isCast']},
title: "Spell Shown" spell: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#" problems: {type: 'array'}
description: "Published when we show a spell" isCast: {type: 'boolean'}
type: "object"
properties:
"thang": "object"
"spell": "object"
required: ["thang", "spell"]
additionalProperties: false
'tome:change-language': 'tome:thang-list-entry-popover-shown': c.object {title: 'Thang List Entry Popover Shown', description: 'Published when we show the popover for a thang in the master list', required: ['entry']},
title: 'Tome Change Language' entry: {type: 'object'}
$schema: 'http://json-schema.org/draft-04/schema#'
description: 'Published when the Tome should update its programming language.'
type: 'object'
additionalProperties: false
properties:
language:
type: 'string'
required: ['language']
'tome:spell-changed-language': 'tome:spell-shown': c.object {title: 'Spell Shown', description: 'Published when we show a spell', required: ['thang', 'spell']},
title: 'Spell Changed Language' thang: {type: 'object'}
$schema: 'http://json-schema.org/draft-04/schema#' spell: {type: 'object'}
description: 'Published when an individual spell has updated its code language.'
type: 'object'
additionalProperties: false
properties:
spell:
type: 'object'
language:
type: 'string'
required: ['spell']
"tome:comment-my-code": 'tome:change-language': c.object {title: 'Tome Change Language', description: 'Published when the Tome should update its programming language', required: ['language']},
title: "Comment My Code" language: {type: 'string'}
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when we comment out a chunk of your code"
type: "undefined"
additionalProperties: false
"tome:change-config": 'tome:spell-changed-language': c.object {title: 'Spell Changed Language', description: 'Published when an individual spell has updated its code language', required: ['spell']},
title: "Change Config" spell: {type: 'object'}
$schema: "http://json-schema.org/draft-04/schema#" language: {type: 'string'}
description: "Published when you change your tome settings"
type: "undefined"
additionalProperties: false
"tome:update-snippets": 'tome:comment-my-code': c.object {title: 'Comment My Code', description: 'Published when we comment out a chunk of your code'}
title: "Update Snippets"
$schema: "http://json-schema.org/draft-04/schema#"
description: "Published when we need to add Zatanna Snippets"
type: "object"
properties:
"propGroups": "object"
"allDocs": "object"
"language": "string"
required: ["propGroups", "allDocs"]
additionalProperties: false
# TODO proposition: add tome to name 'tome:change-config': c.object {title: 'Change Config', description: 'Published when you change your tome settings'}
"focus-editor":
title: "Focus Editor" 'tome:update-snippets': c.object {title: 'Update Snippets', description: 'Published when we need to add Zatanna snippets', required: ['propGroups', 'allDocs']},
$schema: "http://json-schema.org/draft-04/schema#" propGroups: {type: 'object'}
description: "Published whenever we want to give focus back to the editor" allDocs: {type: 'object'}
type: "undefined" language: {type: 'string'}
additionalProperties: false
'tome:insert-snippet': c.object {title: 'Insert Snippet', description: 'Published when we need to insert a Zatanna snippet', required: ['doc', 'language', 'formatted']},
doc: {type: 'object'}
language: {type: 'string'}
formatted: {type: 'object'}
'tome:focus-editor': c.object {title: 'Focus Editor', description: 'Published whenever we want to give focus back to the editor'}
'tome:fullscreen-view': c.object {title: 'Fullscreen View', description: 'Published when we want to make the Tome take up most of the screen'}

View file

@ -1,9 +0,0 @@
module.exports =
'me:synced':
{} # TODO schema
'user-fetched':
{} # TODO schema
'edit-wizard-settings':
{} # TODO schema

View file

@ -1,18 +0,0 @@
module.exports =
'god:user-code-problem':
{} # TODO schema
'god:infinite-loop':
{} # TODO schema
'god:user-code-problem':
{} # TODO schema
'god:new-world-created':
{} # TODO schema
'god:streaming-world-updated':
{} # TODO schema
'god:world-load-progress-changed':
{} # TODO schema

View file

@ -225,6 +225,14 @@ table.table
.ui-slider-handle .ui-slider-handle
border: 1px solid black !important border: 1px solid black !important
// Override jQuery UI widget images that we don't use
.ui-widget-content, .ui-widget-header, .ui-widget-overlay, .ui-widget-shadow
background-image: none
.ui-widget-content, .ui-state-default, .ui-widget-header
.ui-state-default, .ui-state-focus, .ui-state-active, .ui-state-highlight, .ui-state-error
background-image: none
// Fonts // Fonts
.header-font .header-font

View file

@ -6,8 +6,8 @@ $mobile: 1050px
$addPaletteIconColumns: 3 $addPaletteIconColumns: 3
$extantThangsWidth: 300px $extantThangsWidth: 300px
$addPaletteIconWidth: 40px $addPaletteIconWidth: 40px
$addPaletteIconPadding: 2px $addPaletteIconPadding: 0px
$addPaletteIconMargin: 2px $addPaletteIconMargin: 4px
$addPaletteWidth: ($addPaletteIconWidth + 2 * $addPaletteIconPadding + 2 * $addPaletteIconMargin) * $addPaletteIconColumns + 20 $addPaletteWidth: ($addPaletteIconWidth + 2 * $addPaletteIconPadding + 2 * $addPaletteIconMargin) * $addPaletteIconColumns + 20
#toggle #toggle
@ -198,15 +198,26 @@ $mobile: 1050px
padding: $addPaletteIconPadding padding: $addPaletteIconPadding
margin: $addPaletteIconMargin margin: $addPaletteIconMargin
cursor: pointer cursor: pointer
width: $addPaletteIconWidth
height: $addPaletteIconWidth
img img
position: absolute
width: $addPaletteIconWidth width: $addPaletteIconWidth
height: $addPaletteIconWidth height: $addPaletteIconWidth
transition: box-shadow 0.25s ease-out transition: box-shadow 0.25s ease-out
&:hover
$hoverScaleIncreaseFactor: 0.2
outline: 1px dotted blue
img
left: -($hoverScaleIncreaseFactor / 2) * $addPaletteIconWidth
top: -($hoverScaleIncreaseFactor / 2) * $addPaletteIconWidth
width: (1 + $hoverScaleIncreaseFactor) * $addPaletteIconWidth
height: (1 + $hoverScaleIncreaseFactor) * $addPaletteIconWidth
&.selected &.selected
border: 1px solid blue outline: 1px solid blue
margin: $addPaletteIconPadding - 1px
@include box-shadow(0px 5px 25px rgba(79, 79, 213, 0.6)) @include box-shadow(0px 5px 25px rgba(79, 79, 213, 0.6))
background: #add8e6 background: #add8e6

View file

@ -17,25 +17,21 @@
overflow: hidden overflow: hidden
background: white background: white
border: 1px solid #333 border: 1px solid #333
position: relative
-webkit-transition: opacity 0.3s ease-in-out
-moz-transition: opacity 0.3s ease-in-out
-ms-transition: opacity 0.3s ease-in-out
-o-transition: opacity 0.3s ease-in-out
transition: opacity 0.3s ease-in-out
opacity: 0.4
border-radius: 5px border-radius: 5px
.only-one position: relative
-webkit-transition: opacity 0.3s ease-in-out -webkit-transition: opacity 0.3s ease-in-out
-moz-transition: opacity 0.3s ease-in-out -moz-transition: opacity 0.3s ease-in-out
-ms-transition: opacity 0.3s ease-in-out -ms-transition: opacity 0.3s ease-in-out
-o-transition: opacity 0.3s ease-in-out -o-transition: opacity 0.3s ease-in-out
transition: opacity 0.3s ease-in-out transition: opacity 0.3s ease-in-out
.only-one
opacity: 0 opacity: 0
#normal-view:hover
.play-option
opacity: 0.4
.play-option:hover .play-option:hover
opacity: 1 opacity: 1
.only-one .only-one

View file

@ -32,7 +32,7 @@ block content
a(href="/editor/article") a(href="/editor/article")
img(src="/images/pages/community/article.png") img(src="/images/pages/community/article.png")
h2 h2
a.spl(href="/editor/level", data-i18n="editor.article_title") a.spl(href="/editor/article", data-i18n="editor.article_title")
p p
span(data-i18n="community.article_editor_prefix") See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the span(data-i18n="community.article_editor_prefix") See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the
a.spl.spr(href="/editor/article", data-i18n="editor.article_title") a.spl.spr(href="/editor/article", data-i18n="editor.article_title")

View file

@ -5,6 +5,6 @@ div.editor-nano-container.nano
for group in groups for group in groups
h4= group.name h4= group.name
for thangType in group.thangs for thangType in group.thangs
div.add-thang-palette-icon(data-thang-type=thangType.get('name')) div.add-thang-palette-icon(data-thang-type=thangType.get('name'), title=thangType.get('name'))
img(title="Add " + thangType.get('name'), src=thangType.getPortraitURL(), alt="") img(src=thangType.getPortraitURL(), alt="")
div.clearfix div.clearfix

View file

@ -5,6 +5,12 @@ block modal-header-content
block modal-body-content block modal-body-content
h4.language-selection(data-i18n="ladder.select_your_language") Select your language!
.form-group.select-group
select#tome-language(name="language")
for option in languages
option(value=option.id selected=(language === option.id))= option.name
div#noob-view.secret div#noob-view.secret
a(href="/play/level/#{levelID}-tutorial").btn.btn-success.btn-block.btn-lg a(href="/play/level/#{levelID}-tutorial").btn.btn-success.btn-block.btn-lg
p p
@ -18,11 +24,6 @@ block modal-body-content
strong(data-i18n="ladder.tutorial_not_sure") Not sure what's going on? strong(data-i18n="ladder.tutorial_not_sure") Not sure what's going on?
| |
a(href="/play/level/#{levelID}-tutorial", data-i18n="ladder.tutorial_play_first") Play the tutorial first. a(href="/play/level/#{levelID}-tutorial", data-i18n="ladder.tutorial_play_first") Play the tutorial first.
h4.language-selection(data-i18n="ladder.select_your_language") Select your language!
.form-group.select-group
select#tome-language(name="language")
for option in languages
option(value=option.id selected=(language === option.id))= option.name
a(href="/play/level/#{levelID}?team=#{teamID}") a(href="/play/level/#{levelID}?team=#{teamID}")
div.play-option div.play-option
img(src=myPortrait).my-icon.only-one img(src=myPortrait).my-icon.only-one

View file

@ -37,10 +37,6 @@ button.btn.btn-xs.btn-inverse#music-button(title="Toggle Music")
li.selectable#view-keyboard-shortcuts li.selectable#view-keyboard-shortcuts
i.icon-info-sign i.icon-info-sign
span(data-i18n="play_level.keyboard_shortcuts") Key Shortcuts span(data-i18n="play_level.keyboard_shortcuts") Key Shortcuts
li(title="Ctrl/Cmd + G: Toggle grid display").selectable#grid-toggle
i.icon-th
span(data-i18n="play_level.grid") Grid
i.icon-ok.secret.invisible
li.selectable#edit-wizard-settings li.selectable#edit-wizard-settings
i.icon-user i.icon-user
span(data-i18n="play_level.customize_wizard") Customize Wizard span(data-i18n="play_level.customize_wizard") Customize Wizard

View file

@ -1,7 +1,6 @@
RootView = require 'views/kinds/RootView' RootView = require 'views/kinds/RootView'
template = require 'templates/employers' template = require 'templates/employers'
User = require 'models/User' User = require 'models/User'
UserRemark = require 'models/UserRemark'
{me} = require 'lib/auth' {me} = require 'lib/auth'
CocoCollection = require 'collections/CocoCollection' CocoCollection = require 'collections/CocoCollection'
EmployerSignupModal = require 'views/modal/EmployerSignupModal' EmployerSignupModal = require 'views/modal/EmployerSignupModal'
@ -10,10 +9,6 @@ class CandidatesCollection extends CocoCollection
url: '/db/user/x/candidates' url: '/db/user/x/candidates'
model: User model: User
class UserRemarksCollection extends CocoCollection
url: '/db/user.remark?project=contact,contactName,user'
model: UserRemark
module.exports = class EmployersView extends RootView module.exports = class EmployersView extends RootView
id: 'employers-view' id: 'employers-view'
template: template template: template
@ -32,9 +27,12 @@ module.exports = class EmployersView extends RootView
constructor: (options) -> constructor: (options) ->
super options super options
@getCandidates() @candidates = @supermodel.loadCollection(new CandidatesCollection(), 'candidates').model
@setFilterDefaults() @setFilterDefaults()
onLoaded: ->
super()
@setUpScrolling()
afterRender: -> afterRender: ->
super() super()
@ -53,6 +51,7 @@ module.exports = class EmployersView extends RootView
swapFolderIcon: -> swapFolderIcon: ->
$('#folder-icon').toggleClass('glyphicon-folder-close').toggleClass('glyphicon-folder-open') $('#folder-icon').toggleClass('glyphicon-folder-close').toggleClass('glyphicon-folder-open')
onFilterChanged: -> onFilterChanged: ->
@resetFilters() @resetFilters()
that = @ that = @
@ -75,6 +74,7 @@ module.exports = class EmployersView extends RootView
openSignupModal: -> openSignupModal: ->
@openModalView new EmployerSignupModal @openModalView new EmployerSignupModal
handleSelectAllChange: (e) -> handleSelectAllChange: (e) ->
checkedState = e.currentTarget.checked checkedState = e.currentTarget.checked
$('#filters :input').each -> $('#filters :input').each ->
@ -110,6 +110,7 @@ module.exports = class EmployersView extends RootView
return filteredCandidates return filteredCandidates
setFilterDefaults: -> setFilterDefaults: ->
@filters = @filters =
phoneScreenFilter: [true, false] phoneScreenFilter: [true, false]
@ -129,6 +130,7 @@ module.exports = class EmployersView extends RootView
return (_.filter candidates, (c) -> c.get('jobProfile').curated?[filterName] is filterValue).length return (_.filter candidates, (c) -> c.get('jobProfile').curated?[filterName] is filterValue).length
else else
return Math.floor(Math.random() * 500) return Math.floor(Math.random() * 500)
createFilterAlert: -> createFilterAlert: ->
currentFilterSet = _.cloneDeep @filters currentFilterSet = _.cloneDeep @filters
currentSavedFilters = _.cloneDeep me.get('savedEmployerFilterAlerts') ? [] currentSavedFilters = _.cloneDeep me.get('savedEmployerFilterAlerts') ? []
@ -158,7 +160,6 @@ module.exports = class EmployersView extends RootView
for filter, index in savedFilters for filter, index in savedFilters
$("#saved-filter-table tbody").append("""<tr data-filter-index="#{index}"><td>#{@generateFilterAlertDescription(filter)}</td><td class="deletion-col"><a>✗</a></td></tr> """) $("#saved-filter-table tbody").append("""<tr data-filter-index="#{index}"><td>#{@generateFilterAlertDescription(filter)}</td><td class="deletion-col"><a>✗</a></td></tr> """)
generateFilterAlertDescription: (filter) => generateFilterAlertDescription: (filter) =>
descriptionString = "" descriptionString = ""
for key in _.keys(filter).sort() for key in _.keys(filter).sort()
@ -191,8 +192,6 @@ module.exports = class EmployersView extends RootView
ctx.featuredCandidates = ctx.candidates ctx.featuredCandidates = ctx.candidates
ctx.candidatesInFilter = @candidatesInFilter ctx.candidatesInFilter = @candidatesInFilter
ctx.otherCandidates = _.reject ctx.activeCandidates, (c) -> c.get('jobProfileApproved') ctx.otherCandidates = _.reject ctx.activeCandidates, (c) -> c.get('jobProfileApproved')
ctx.remarks = {}
ctx.remarks[remark.get('user')] = remark for remark in @remarks.models
ctx.moment = moment ctx.moment = moment
ctx._ = _ ctx._ = _
ctx.numberOfCandidates = ctx.featuredCandidates.length ctx.numberOfCandidates = ctx.featuredCandidates.length
@ -202,17 +201,7 @@ module.exports = class EmployersView extends RootView
userPermissions = me.get('permissions') ? [] userPermissions = me.get('permissions') ? []
_.contains userPermissions, 'employer' _.contains userPermissions, 'employer'
getCandidates: -> setUpScrolling: =>
@candidates = new CandidatesCollection()
@candidates.fetch()
@remarks = new UserRemarksCollection()
@remarks.fetch()
# Re-render when we have fetched them, but don't wait and show a progress bar while loading.
@listenToOnce @candidates, 'all', @renderCandidatesAndSetupScrolling
@listenToOnce @remarks, 'all', @renderCandidatesAndSetupScrolling
renderCandidatesAndSetupScrolling: =>
@render()
$('.nano').nanoScroller() $('.nano').nanoScroller()
#if window.history?.state?.lastViewedCandidateID #if window.history?.state?.lastViewedCandidateID
# $('.nano').nanoScroller({scrollTo: $('#' + window.history.state.lastViewedCandidateID)}) # $('.nano').nanoScroller({scrollTo: $('#' + window.history.state.lastViewedCandidateID)})
@ -340,9 +329,11 @@ module.exports = class EmployersView extends RootView
8: 8:
'': filterSelectExactMatch '': filterSelectExactMatch
'': filterSelectExactMatch '': filterSelectExactMatch
logoutAccount: -> logoutAccount: ->
window.location.hash = '' window.location.hash = ''
super() super()
onCandidateClicked: (e) -> onCandidateClicked: (e) ->
id = $(e.target).closest('tr').data('candidate-id') id = $(e.target).closest('tr').data('candidate-id')
if id and (@isEmployer() or me.isAdmin()) if id and (@isEmployer() or me.isAdmin())

View file

@ -8,7 +8,6 @@ SpriteBuilder = require 'lib/sprites/SpriteBuilder'
module.exports = class WizardSettingsView extends CocoView module.exports = class WizardSettingsView extends CocoView
id: 'wizard-settings-view' id: 'wizard-settings-view'
template: template template: template
startsLoading: true
events: events:
'click .color-group': (e) -> 'click .color-group': (e) ->
@ -27,13 +26,11 @@ module.exports = class WizardSettingsView extends CocoView
loadWizard: -> loadWizard: ->
@wizardThangType = new ThangType() @wizardThangType = new ThangType()
@wizardThangType.url = -> '/db/thang.type/wizard' @wizardThangType.setURL '/db/thang.type/wizard'
@wizardThangType.fetch() @supermodel.loadModel @wizardThangType, 'wizard'
@listenToOnce(@wizardThangType, 'sync', @initCanvas)
initCanvas: -> onLoaded: ->
@startsLoading = false super()
@render()
@spriteBuilder = new SpriteBuilder(@wizardThangType) @spriteBuilder = new SpriteBuilder(@wizardThangType)
@initStage() @initStage()
@ -56,7 +53,7 @@ module.exports = class WizardSettingsView extends CocoView
c c
afterRender: -> afterRender: ->
return if @startsLoading return unless @supermodel.finished()
wizardSettings = me.get('wizard') or {} wizardSettings = me.get('wizard') or {}
wizardSettings.colorConfig ?= {} wizardSettings.colorConfig ?= {}

View file

@ -1,30 +1,29 @@
RootView = require 'views/kinds/RootView' RootView = require 'views/kinds/RootView'
template = require 'templates/admin/clas' template = require 'templates/admin/clas'
CocoCollection = require 'collections/CocoCollection'
CocoModel = require 'models/CocoModel'
class CLASubmission extends CocoModel
@className: 'CLA'
@schema: require 'schemas/models/cla_submission'
urlRoot: '/db/cla.submission'
class CLACollection extends CocoCollection
url: '/db/cla.submissions'
model: CLASubmission
module.exports = class CLAsView extends RootView module.exports = class CLAsView extends RootView
id: 'admin-clas-view' id: 'admin-clas-view'
template: template template: template
startsLoading: true
constructor: (options) -> constructor: (options) ->
super options super options
@getCLAs() @clas = @supermodel.loadCollection(new CLACollection(), 'clas').model
getCLAs: ->
CLACollection = Backbone.Collection.extend({
url: '/db/cla.submissions'
})
@clas = new CLACollection()
@clas.fetch()
@listenTo(@clas, 'sync', @onCLAsLoaded)
onCLAsLoaded: ->
@startsLoading = false
@render()
getRenderData: -> getRenderData: ->
c = super() c = super()
c.clas = [] c.clas = []
unless @startsLoading if @supermodel.finished()
c.clas = _.uniq (_.sortBy (cla.attributes for cla in @clas.models), (m) -> m.githubUsername?.toLowerCase()), 'githubUsername' c.clas = _.uniq (_.sortBy (cla.attributes for cla in @clas.models), (m) ->
m.githubUsername?.toLowerCase()), 'githubUsername'
c c

View file

@ -23,7 +23,12 @@ module.exports = class CandidatesView extends RootView
constructor: (options) -> constructor: (options) ->
super options super options
@getCandidates() @candidates = @supermodel.loadCollection(new CandidatesCollection(), 'candidates').model
@remarks = @supermodel.loadCollection(new UserRemarksCollection(), 'user_remarks').model
onLoaded: ->
super()
@setUpScrolling()
afterRender: -> afterRender: ->
super() super()
@ -51,17 +56,7 @@ module.exports = class CandidatesView extends RootView
userPermissions = me.get('permissions') ? [] userPermissions = me.get('permissions') ? []
_.contains userPermissions, "employer" _.contains userPermissions, "employer"
getCandidates: -> setUpScrolling: ->
@candidates = new CandidatesCollection()
@candidates.fetch()
@remarks = new UserRemarksCollection()
@remarks.fetch()
# Re-render when we have fetched them, but don't wait and show a progress bar while loading.
@listenToOnce @candidates, 'all', @renderCandidatesAndSetupScrolling
@listenToOnce @remarks, 'all', @renderCandidatesAndSetupScrolling
renderCandidatesAndSetupScrolling: =>
@render()
$(".nano").nanoScroller() $(".nano").nanoScroller()
if window.history?.state?.lastViewedCandidateID if window.history?.state?.lastViewedCandidateID
$(".nano").nanoScroller({scrollTo:$("#" + window.history.state.lastViewedCandidateID)}) $(".nano").nanoScroller({scrollTo:$("#" + window.history.state.lastViewedCandidateID)})

View file

@ -18,7 +18,7 @@ module.exports = class EmployersListView extends RootView
constructor: (options) -> constructor: (options) ->
super options super options
@getEmployers() @employers = @supermodel.loadCollection(new EmployersCollection(), 'employers').model
afterRender: -> afterRender: ->
super() super()
@ -30,12 +30,6 @@ module.exports = class EmployersListView extends RootView
ctx.moment = moment ctx.moment = moment
ctx ctx
getEmployers: ->
@employers = new EmployersCollection()
@employers.fetch()
# Re-render when we have fetched them, but don't wait and show a progress bar while loading.
@listenToOnce @employers, 'all', => @render()
sortTable: -> sortTable: ->
# http://mottie.github.io/tablesorter/docs/example-widget-bootstrap-theme.html # http://mottie.github.io/tablesorter/docs/example-widget-bootstrap-theme.html
$.extend $.tablesorter.themes.bootstrap, $.extend $.tablesorter.themes.bootstrap,

View file

@ -1,10 +1,10 @@
RootView = require 'views/kinds/RootView' RootView = require 'views/kinds/RootView'
template = require 'templates/admin/level_sessions' template = require 'templates/admin/level_sessions'
LevelSession = require 'models/LevelSession' LevelSession = require 'models/LevelSession'
CocoCollection = require 'collections/CocoCollection'
# Placeholder class LevelSessionCollection extends CocoCollection
class LevelSessionCollection extends Backbone.Collection url: '/db/level_session/x/active?project=screenshot,levelName,creatorName'
url: '/db/level_session/x/active'
model: LevelSession model: LevelSession
module.exports = class LevelSessionsView extends RootView module.exports = class LevelSessionsView extends RootView
@ -16,9 +16,7 @@ module.exports = class LevelSessionsView extends RootView
@getLevelSessions() @getLevelSessions()
getLevelSessions: -> getLevelSessions: ->
@sessions = new LevelSessionCollection() @sessions = @supermodel.loadCollection(new LevelSessionCollection(), 'sessions').model
@sessions.fetch()
@listenToOnce @sessions, 'all', @render
getRenderData: => getRenderData: =>
c = super() c = super()

View file

@ -9,7 +9,6 @@ app = require 'application'
module.exports = class AchievementEditView extends RootView module.exports = class AchievementEditView extends RootView
id: 'editor-achievement-edit-view' id: 'editor-achievement-edit-view'
template: template template: template
startsLoading: true
events: events:
'click #save-button': 'saveAchievement' 'click #save-button': 'saveAchievement'
@ -23,21 +22,15 @@ module.exports = class AchievementEditView extends RootView
super options super options
@achievement = new Achievement(_id: @achievementID) @achievement = new Achievement(_id: @achievementID)
@achievement.saveBackups = true @achievement.saveBackups = true
@supermodel.loadModel @achievement, 'achievement'
@achievement.once 'error', (achievement, jqxhr) =>
@hideLoading()
$(@$el).find('.main-content-area').children('*').not('.breadcrumb').remove()
errors.backboneFailure arguments...
@achievement.fetch()
@listenToOnce(@achievement, 'sync', @buildTreema)
@pushChangesToPreview = _.throttle(@pushChangesToPreview, 500) @pushChangesToPreview = _.throttle(@pushChangesToPreview, 500)
onLoaded: ->
super()
@buildTreema()
buildTreema: -> buildTreema: ->
return if @treema? or (not @achievement.loaded) return if @treema? or (not @achievement.loaded)
@startsLoading = false
@render()
data = $.extend(true, {}, @achievement.attributes) data = $.extend(true, {}, @achievement.attributes)
options = options =
data: data data: data
@ -47,7 +40,6 @@ module.exports = class AchievementEditView extends RootView
callbacks: callbacks:
change: @pushChangesToPreview change: @pushChangesToPreview
@treema = @$el.find('#achievement-treema').treema(options) @treema = @$el.find('#achievement-treema').treema(options)
@treema.build() @treema.build()
getRenderData: (context={}) -> getRenderData: (context={}) ->
@ -57,22 +49,17 @@ module.exports = class AchievementEditView extends RootView
context context
afterRender: -> afterRender: ->
super(arguments...) super()
return unless @supermodel.finished()
@pushChangesToPreview() @pushChangesToPreview()
pushChangesToPreview: => pushChangesToPreview: =>
$('#achievement-view').empty() @$el.find('#achievement-view').empty()
if @treema?
for key, value of @treema.data for key, value of @treema.data
@achievement.set key, value @achievement.set key, value
earned = earnedPoints: @achievement.get 'worth'
earned =
earnedPoints: @achievement.get 'worth'
popup = new AchievementPopup achievement: @achievement, earnedAchievement: earned, popup: false, container: $('#achievement-view') popup = new AchievementPopup achievement: @achievement, earnedAchievement: earned, popup: false, container: $('#achievement-view')
openSaveModal: -> openSaveModal: ->
'Maybe later' # TODO patch patch patch 'Maybe later' # TODO patch patch patch

View file

@ -8,7 +8,6 @@ PatchesView = require 'views/editor/PatchesView'
module.exports = class ArticleEditView extends RootView module.exports = class ArticleEditView extends RootView
id: 'editor-article-edit-view' id: 'editor-article-edit-view'
template: template template: template
startsLoading: true
events: events:
'click #preview-button': 'openPreview' 'click #preview-button': 'openPreview'
@ -16,34 +15,23 @@ module.exports = class ArticleEditView extends RootView
'click #save-button': 'openSaveModal' 'click #save-button': 'openSaveModal'
subscriptions: subscriptions:
'save-new-version': 'saveNewArticle' 'editor:save-new-version': 'saveNewArticle'
constructor: (options, @articleID) -> constructor: (options, @articleID) ->
super options super options
@article = new Article(_id: @articleID) @article = new Article(_id: @articleID)
@article.saveBackups = true @article.saveBackups = true
@supermodel.loadModel @article, 'article'
@listenToOnce(@article, 'error',
() =>
@hideLoading()
# Hack: editor components appear after calling insertSubView.
# So we need to hide them first.
$(@$el).find('.main-content-area').children('*').not('#error-view').remove()
@insertSubView(new ErrorView())
)
@article.fetch()
@listenToOnce(@article, 'sync', @buildTreema)
@pushChangesToPreview = _.throttle(@pushChangesToPreview, 500) @pushChangesToPreview = _.throttle(@pushChangesToPreview, 500)
onLoaded: ->
super()
@buildTreema()
buildTreema: -> buildTreema: ->
return if @treema? or (not @article.loaded) return if @treema? or (not @article.loaded)
unless @article.attributes.body unless @article.attributes.body
@article.set('body', '') @article.set('body', '')
@startsLoading = false
@render()
data = $.extend(true, {}, @article.attributes) data = $.extend(true, {}, @article.attributes)
options = options =
data: data data: data
@ -53,7 +41,6 @@ module.exports = class ArticleEditView extends RootView
callbacks: callbacks:
change: @pushChangesToPreview change: @pushChangesToPreview
@treema = @$el.find('#article-treema').treema(options) @treema = @$el.find('#article-treema').treema(options)
@treema.build() @treema.build()
pushChangesToPreview: => pushChangesToPreview: =>
@ -73,7 +60,7 @@ module.exports = class ArticleEditView extends RootView
afterRender: -> afterRender: ->
super() super()
return if @startsLoading return unless @supermodel.finished()
@showReadOnly() if me.get('anonymous') @showReadOnly() if me.get('anonymous')
@patchesView = @insertSubView(new PatchesView(@article), @$el.find('.patches-view')) @patchesView = @insertSubView(new PatchesView(@article), @$el.find('.patches-view'))
@patchesView.load() @patchesView.load()
@ -111,4 +98,4 @@ module.exports = class ArticleEditView extends RootView
showVersionHistory: (e) -> showVersionHistory: (e) ->
versionHistoryView = new VersionHistoryView article: @article, @articleID versionHistoryView = new VersionHistoryView article: @article, @articleID
@openModalView versionHistoryView @openModalView versionHistoryView
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}

View file

@ -72,7 +72,7 @@ module.exports = class LevelEditView extends RootView
super() super()
return unless @supermodel.finished() return unless @supermodel.finished()
@$el.find('a[data-toggle="tab"]').on 'shown.bs.tab', (e) => @$el.find('a[data-toggle="tab"]').on 'shown.bs.tab', (e) =>
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
@insertSubView new ThangsTabView world: @world, supermodel: @supermodel, level: @level @insertSubView new ThangsTabView world: @world, supermodel: @supermodel, level: @level
@insertSubView new SettingsTabView supermodel: @supermodel @insertSubView new SettingsTabView supermodel: @supermodel
@insertSubView new ScriptsTabView world: @world, supermodel: @supermodel, files: @files @insertSubView new ScriptsTabView world: @world, supermodel: @supermodel, files: @files
@ -81,7 +81,7 @@ module.exports = class LevelEditView extends RootView
@insertSubView new RelatedAchievementsView supermodel: @supermodel, level: @level @insertSubView new RelatedAchievementsView supermodel: @supermodel, level: @level
@insertSubView new ComponentDocsView # Don't give it the supermodel, it'll pollute it! @insertSubView new ComponentDocsView # Don't give it the supermodel, it'll pollute it!
Backbone.Mediator.publish 'level-loaded', level: @level Backbone.Mediator.publish 'editor:level-loaded', level: @level
@showReadOnly() if me.get('anonymous') @showReadOnly() if me.get('anonymous')
@patchesView = @insertSubView(new PatchesView(@level), @$el.find('.patches-view')) @patchesView = @insertSubView(new PatchesView(@level), @$el.find('.patches-view'))
@listenTo @patchesView, 'accepted-patch', -> location.reload() @listenTo @patchesView, 'accepted-patch', -> location.reload()
@ -96,7 +96,7 @@ module.exports = class LevelEditView extends RootView
onPlayLevel: (e) -> onPlayLevel: (e) ->
team = $(e.target).data('team') team = $(e.target).data('team')
sendLevel = => sendLevel = =>
@childWindow.Backbone.Mediator.publish 'level-reload-from-data', level: @level, supermodel: @supermodel @childWindow.Backbone.Mediator.publish 'level:reload-from-data', level: @level, supermodel: @supermodel
if @childWindow and not @childWindow.closed if @childWindow and not @childWindow.closed
# Reset the LevelView's world, but leave the rest of the state alone # Reset the LevelView's world, but leave the rest of the state alone
sendLevel() sendLevel()
@ -134,20 +134,20 @@ module.exports = class LevelEditView extends RootView
startPatchingLevel: (e) -> startPatchingLevel: (e) ->
@openModalView new SaveVersionModal({model: @level}) @openModalView new SaveVersionModal({model: @level})
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
startCommittingLevel: (e) -> startCommittingLevel: (e) ->
@openModalView new SaveLevelModal level: @level, supermodel: @supermodel @openModalView new SaveLevelModal level: @level, supermodel: @supermodel
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
startForking: (e) -> startForking: (e) ->
@openModalView new ForkModal model: @level, editorPath: 'level' @openModalView new ForkModal model: @level, editorPath: 'level'
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
showVersionHistory: (e) -> showVersionHistory: (e) ->
versionHistoryView = new VersionHistoryView level: @level, @levelID versionHistoryView = new VersionHistoryView level: @level, @levelID
@openModalView versionHistoryView @openModalView versionHistoryView
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
toggleWatchLevel: -> toggleWatchLevel: ->
button = @$el.find('#level-watch-button') button = @$el.find('#level-watch-button')

View file

@ -14,9 +14,7 @@ module.exports = class ComponentsTabView extends CocoView
className: 'tab-pane' className: 'tab-pane'
subscriptions: subscriptions:
'edit-level-component': 'editLevelComponent' 'editor:level-component-editing-ended': 'onLevelComponentEditingEnded'
'level-component-edited': 'onLevelComponentEdited'
'level-component-editing-ended': 'onLevelComponentEditingEnded'
events: events:
'click #create-new-component-button': 'createNewLevelComponent' 'click #create-new-component-button': 'createNewLevelComponent'
@ -66,14 +64,11 @@ module.exports = class ComponentsTabView extends CocoView
createNewLevelComponent: (e) -> createNewLevelComponent: (e) ->
levelComponentNewView = new LevelComponentNewView supermodel: @supermodel levelComponentNewView = new LevelComponentNewView supermodel: @supermodel
@openModalView levelComponentNewView @openModalView levelComponentNewView
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
editLevelComponent: (e) -> editLevelComponent: (e) ->
@levelComponentEditView = @insertSubView new LevelComponentEditView(original: e.original, majorVersion: e.majorVersion, supermodel: @supermodel) @levelComponentEditView = @insertSubView new LevelComponentEditView(original: e.original, majorVersion: e.majorVersion, supermodel: @supermodel)
onLevelComponentEdited: (e) ->
Backbone.Mediator.publish 'level-components-changed', {}
onLevelComponentEditingEnded: (e) -> onLevelComponentEditingEnded: (e) ->
@removeSubView @levelComponentEditView @removeSubView @levelComponentEditView
@levelComponentEditView = null @levelComponentEditView = null
@ -90,6 +85,3 @@ class LevelComponentNode extends TreemaObjectNode
m.get('original') is @data.original and m.get('version').major is @data.majorVersion m.get('original') is @data.original and m.get('version').major is @data.majorVersion
name = "#{comp.get('system')}.#{comp.get('name')} v#{comp.get('version').major}" name = "#{comp.get('system')}.#{comp.get('name')} v#{comp.get('version').major}"
@buildValueForDisplaySimply valEl, "#{name} (#{count})" @buildValueForDisplaySimply valEl, "#{name} (#{count})"
onEnterPressed: ->
Backbone.Mediator.publish 'edit-level-component', original: @data.original, majorVersion: @data.majorVersion

View file

@ -64,7 +64,6 @@ module.exports = class LevelComponentEditView extends CocoView
# Make sure it validates first? # Make sure it validates first?
for key, value of @componentSettingsTreema.data for key, value of @componentSettingsTreema.data
@levelComponent.set key, value unless key is 'js' # will compile code if needed @levelComponent.set key, value unless key is 'js' # will compile code if needed
Backbone.Mediator.publish 'level-component-edited', levelComponent: @levelComponent
null null
buildConfigSchemaTreema: -> buildConfigSchemaTreema: ->
@ -82,7 +81,6 @@ module.exports = class LevelComponentEditView extends CocoView
onConfigSchemaEdited: => onConfigSchemaEdited: =>
@levelComponent.set 'configSchema', @configSchemaTreema.data @levelComponent.set 'configSchema', @configSchemaTreema.data
Backbone.Mediator.publish 'level-component-edited', levelComponent: @levelComponent
buildCodeEditor: -> buildCodeEditor: ->
@editor?.destroy() @editor?.destroy()
@ -100,21 +98,20 @@ module.exports = class LevelComponentEditView extends CocoView
onEditorChange: => onEditorChange: =>
return if @destroyed return if @destroyed
@levelComponent.set 'code', @editor.getValue() @levelComponent.set 'code', @editor.getValue()
Backbone.Mediator.publish 'level-component-edited', levelComponent: @levelComponent
null null
endEditing: (e) -> endEditing: (e) ->
Backbone.Mediator.publish 'level-component-editing-ended', levelComponent: @levelComponent Backbone.Mediator.publish 'editor:level-component-editing-ended', component: @levelComponent
null null
showVersionHistory: (e) -> showVersionHistory: (e) ->
componentVersionsModal = new ComponentVersionsModal {}, @levelComponent.id componentVersionsModal = new ComponentVersionsModal {}, @levelComponent.id
@openModalView componentVersionsModal @openModalView componentVersionsModal
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
startPatchingComponent: (e) -> startPatchingComponent: (e) ->
@openModalView new SaveVersionModal({model: @levelComponent}) @openModalView new SaveVersionModal({model: @levelComponent})
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
toggleWatchComponent: -> toggleWatchComponent: ->
button = @$el.find('#component-watch-button') button = @$el.find('#component-watch-button')

View file

@ -38,5 +38,4 @@ module.exports = class NewLevelComponentModal extends ModalView
forms.applyErrorsToForm(@$el, JSON.parse(res.responseText)) forms.applyErrorsToForm(@$el, JSON.parse(res.responseText))
res.success => res.success =>
@supermodel.registerModel component @supermodel.registerModel component
Backbone.Mediator.publish 'edit-level-component', original: component.get('_id'), majorVersion: 0
@hide() @hide()

View file

@ -215,9 +215,7 @@ module.exports = class TerrainRandomizeModal extends ModalView
presetType = target.attr 'data-preset-type' presetType = target.attr 'data-preset-type'
presetSize = target.attr 'data-preset-size' presetSize = target.attr 'data-preset-size'
@randomizeThangs presetType, presetSize @randomizeThangs presetType, presetSize
Backbone.Mediator.publish('randomize:terrain-generated', Backbone.Mediator.publish 'editor:random-terrain-generated', thangs: @thangs
'thangs': @thangs
)
@hide() @hide()
randomizeThangs: (presetName, presetSize) -> randomizeThangs: (presetName, presetSize) ->

View file

@ -10,8 +10,8 @@ module.exports = class WorldSelectModal extends ModalView
cache: false cache: false
subscriptions: subscriptions:
'choose-region': 'selectionMade' 'surface:choose-region': 'selectionMade'
'choose-point': 'selectionMade' 'surface:choose-point': 'selectionMade'
events: events:
'click #done-button': 'done' 'click #done-button': 'done'

View file

@ -11,7 +11,7 @@ module.exports = class ScriptsTabView extends CocoView
className: 'tab-pane' className: 'tab-pane'
subscriptions: subscriptions:
'level-loaded': 'onLevelLoaded' 'editor:level-loaded': 'onLevelLoaded'
constructor: (options) -> constructor: (options) ->
super options super options

View file

@ -17,7 +17,7 @@ module.exports = class SettingsTabView extends CocoView
] ]
subscriptions: subscriptions:
'level-loaded': 'onLevelLoaded' 'editor:level-loaded': 'onLevelLoaded'
constructor: (options) -> constructor: (options) ->
super options super options

View file

@ -19,23 +19,14 @@ module.exports = class AddLevelSystemModal extends ModalView
constructor: (options) -> constructor: (options) ->
super options super options
@extantSystems = options.extantSystems ? [] @extantSystems = options.extantSystems ? []
@systems = @supermodel.loadCollection(new LevelSystemSearchCollection(), 'systems').model
render: ->
if not @systems
@systems = @supermodel.getCollection new LevelSystemSearchCollection()
unless @systems.loaded
@listenToOnce(@systems, 'sync', @onSystemsSync)
@systems.fetch()
super() # do afterRender at the end
afterRender: -> afterRender: ->
super() super()
return @showLoading() unless @systems?.loaded return unless @supermodel.finished()
@hideLoading()
@renderAvailableSystems() @renderAvailableSystems()
renderAvailableSystems: -> renderAvailableSystems: ->
return unless @systems
ul = @$el.find('ul.available-systems-list').empty() ul = @$el.find('ul.available-systems-list').empty()
systems = (m.attributes for m in @systems.models) systems = (m.attributes for m in @systems.models)
_.remove systems, (system) => _.remove systems, (system) =>
@ -44,10 +35,6 @@ module.exports = class AddLevelSystemModal extends ModalView
for system in systems for system in systems
ul.append $(availableSystemTemplate(system: system)) ul.append $(availableSystemTemplate(system: system))
onSystemsSync: ->
@supermodel.addCollection @systems
@render()
onAddSystem: (e) -> onAddSystem: (e) ->
id = $(e.currentTarget).data('system-id') id = $(e.currentTarget).data('system-id')
system = _.find @systems.models, id: id system = _.find @systems.models, id: id

View file

@ -58,7 +58,6 @@ module.exports = class LevelSystemEditView extends CocoView
# Make sure it validates first? # Make sure it validates first?
for key, value of @systemSettingsTreema.data for key, value of @systemSettingsTreema.data
@levelSystem.set key, value unless key is 'js' # will compile code if needed @levelSystem.set key, value unless key is 'js' # will compile code if needed
Backbone.Mediator.publish 'level-system-edited', levelSystem: @levelSystem
null null
buildConfigSchemaTreema: -> buildConfigSchemaTreema: ->
@ -76,7 +75,6 @@ module.exports = class LevelSystemEditView extends CocoView
onConfigSchemaEdited: => onConfigSchemaEdited: =>
@levelSystem.set 'configSchema', @configSchemaTreema.data @levelSystem.set 'configSchema', @configSchemaTreema.data
Backbone.Mediator.publish 'level-system-edited', levelSystem: @levelSystem
buildCodeEditor: -> buildCodeEditor: ->
@editor?.destroy() @editor?.destroy()
@ -93,21 +91,20 @@ module.exports = class LevelSystemEditView extends CocoView
onEditorChange: => onEditorChange: =>
@levelSystem.set 'code', @editor.getValue() @levelSystem.set 'code', @editor.getValue()
Backbone.Mediator.publish 'level-system-edited', levelSystem: @levelSystem
null null
endEditing: (e) -> endEditing: (e) ->
Backbone.Mediator.publish 'level-system-editing-ended', levelSystem: @levelSystem Backbone.Mediator.publish 'editor:level-system-editing-ended', system: @levelSystem
null null
showVersionHistory: (e) -> showVersionHistory: (e) ->
systemVersionsModal = new SystemVersionsModal {}, @levelSystem.id systemVersionsModal = new SystemVersionsModal {}, @levelSystem.id
@openModalView systemVersionsModal @openModalView systemVersionsModal
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
startPatchingSystem: (e) -> startPatchingSystem: (e) ->
@openModalView new SaveVersionModal({model: @levelSystem}) @openModalView new SaveVersionModal({model: @levelSystem})
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
toggleWatchSystem: -> toggleWatchSystem: ->
console.log 'toggle watch system?' console.log 'toggle watch system?'

View file

@ -32,5 +32,5 @@ module.exports = class NewLevelSystemModal extends ModalView
forms.applyErrorsToForm(@$el, JSON.parse(res.responseText)) forms.applyErrorsToForm(@$el, JSON.parse(res.responseText))
res.success => res.success =>
@supermodel.registerModel system @supermodel.registerModel system
Backbone.Mediator.publish 'edit-level-system', original: system.get('_id'), majorVersion: 0 Backbone.Mediator.publish 'editor:edit-level-system', original: system.get('_id'), majorVersion: 0
@hide() @hide()

View file

@ -13,11 +13,10 @@ module.exports = class SystemsTabView extends CocoView
className: 'tab-pane' className: 'tab-pane'
subscriptions: subscriptions:
'level-system-added': 'onLevelSystemAdded' 'editor:level-system-added': 'onLevelSystemAdded'
'edit-level-system': 'editLevelSystem' 'editor:edit-level-system': 'editLevelSystem'
'level-system-edited': 'onLevelSystemEdited' 'editor:level-system-editing-ended': 'onLevelSystemEditingEnded'
'level-system-editing-ended': 'onLevelSystemEditingEnded' 'editor:level-loaded': 'onLevelLoaded'
'level-loaded': 'onLevelLoaded'
events: events:
'click #add-system-button': 'addLevelSystem' 'click #add-system-button': 'addLevelSystem'
@ -91,18 +90,15 @@ module.exports = class SystemsTabView extends CocoView
addLevelSystem: (e) -> addLevelSystem: (e) ->
@openModalView new AddLevelSystemModal supermodel: @supermodel, extantSystems: _.cloneDeep @systemsTreema.data @openModalView new AddLevelSystemModal supermodel: @supermodel, extantSystems: _.cloneDeep @systemsTreema.data
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
createNewLevelSystem: (e) -> createNewLevelSystem: (e) ->
@openModalView new NewLevelSystemModal supermodel: @supermodel @openModalView new NewLevelSystemModal supermodel: @supermodel
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
editLevelSystem: (e) -> editLevelSystem: (e) ->
@levelSystemEditView = @insertSubView new LevelSystemEditView(original: e.original, majorVersion: e.majorVersion, supermodel: @supermodel) @levelSystemEditView = @insertSubView new LevelSystemEditView(original: e.original, majorVersion: e.majorVersion, supermodel: @supermodel)
onLevelSystemEdited: (e) ->
Backbone.Mediator.publish 'level-systems-changed', systemsData: @systemsTreema.data
onLevelSystemEditingEnded: (e) -> onLevelSystemEditingEnded: (e) ->
@removeSubView @levelSystemEditView @removeSubView @levelSystemEditView
@levelSystemEditView = null @levelSystemEditView = null
@ -150,7 +146,7 @@ class LevelSystemNode extends TreemaObjectNode
onEnterPressed: (e) -> onEnterPressed: (e) ->
super e super e
Backbone.Mediator.publish 'edit-level-system', original: @data.original, majorVersion: @data.majorVersion Backbone.Mediator.publish 'editor:edit-level-system', original: @data.original, majorVersion: @data.majorVersion
open: (depth) -> open: (depth) ->
super depth super depth

View file

@ -14,7 +14,6 @@ module.exports = class AddThangsView extends CocoView
id: 'add-thangs-column' id: 'add-thangs-column'
className: 'add-thangs-palette thangs-column' className: 'add-thangs-palette thangs-column'
template: add_thangs_template template: add_thangs_template
startsLoading: false
events: events:
'keyup input#thang-search': 'runSearch' 'keyup input#thang-search': 'runSearch'
@ -56,6 +55,10 @@ module.exports = class AddThangsView extends CocoView
afterRender: -> afterRender: ->
super() super()
@buildAddThangPopovers()
buildAddThangPopovers: ->
@$el.find('#thangs-list .add-thang-palette-icon').tooltip(container: 'body', animation: false)
runSearch: (e) => runSearch: (e) =>
if e?.which is 27 if e?.which is 27

View file

@ -56,13 +56,10 @@ module.exports = class LevelThangEditView extends CocoView
saveThang: (e) -> saveThang: (e) ->
# Make sure it validates first? # Make sure it validates first?
event = Backbone.Mediator.publish 'editor:level-thang-edited', thangData: @thangData, thangID: @oldID
thangData: @thangData
id: @oldID
Backbone.Mediator.publish 'level-thang-edited', event
navigateToAllThangs: -> navigateToAllThangs: ->
Backbone.Mediator.publish 'level-thang-done-editing' Backbone.Mediator.publish 'editor:level-thang-done-editing', {}
toggleNameEdit: -> toggleNameEdit: ->
link = @$el.find '#thang-name-link' link = @$el.find '#thang-name-link'

View file

@ -28,22 +28,21 @@ module.exports = class ThangsTabView extends CocoView
id: 'editor-level-thangs-tab-view' id: 'editor-level-thangs-tab-view'
className: 'tab-pane active' className: 'tab-pane active'
template: thangs_template template: thangs_template
startsLoading: true
subscriptions: subscriptions:
'surface:sprite-selected': 'onExtantThangSelected' 'surface:sprite-selected': 'onExtantThangSelected'
'surface:mouse-moved': 'onSurfaceMouseMoved' 'surface:mouse-moved': 'onSurfaceMouseMoved'
'surface:mouse-over': 'onSurfaceMouseOver' 'surface:mouse-over': 'onSurfaceMouseOver'
'surface:mouse-out': 'onSurfaceMouseOut' 'surface:mouse-out': 'onSurfaceMouseOut'
'edit-level-thang': 'editThang' 'editor:edit-level-thang': 'editThang'
'level-thang-edited': 'onLevelThangEdited' 'editor:level-thang-edited': 'onLevelThangEdited'
'level-thang-done-editing': 'onLevelThangDoneEditing' 'editor:level-thang-done-editing': 'onLevelThangDoneEditing'
'level:view-switched': 'onViewSwitched' 'editor:view-switched': 'onViewSwitched'
'sprite:dragged': 'onSpriteDragged' 'sprite:dragged': 'onSpriteDragged'
'sprite:mouse-up': 'onSpriteMouseUp' 'sprite:mouse-up': 'onSpriteMouseUp'
'sprite:double-clicked': 'onSpriteDoubleClicked' 'sprite:double-clicked': 'onSpriteDoubleClicked'
'surface:stage-mouse-up': 'onStageMouseUp' 'surface:stage-mouse-up': 'onStageMouseUp'
'randomize:terrain-generated': 'onRandomizeTerrain' 'editor:random-terrain-generated': 'onRandomTerrainGenerated'
events: events:
'click #extant-thangs-filter button': 'onFilterExtantThangs' 'click #extant-thangs-filter button': 'onFilterExtantThangs'
@ -233,7 +232,7 @@ module.exports = class ThangsTabView extends CocoView
return unless e.thang return unless e.thang
@editThang thangID: e.thang.id @editThang thangID: e.thang.id
onRandomizeTerrain: (e) -> onRandomTerrainGenerated: (e) ->
@thangsBatch = [] @thangsBatch = []
nonRandomThangs = (thang for thang in @thangsTreema.get('') when not /Random/.test thang.id) nonRandomThangs = (thang for thang in @thangsTreema.get('') when not /Random/.test thang.id)
@thangsTreema.set '', nonRandomThangs @thangsTreema.set '', nonRandomThangs
@ -403,7 +402,6 @@ module.exports = class ThangsTabView extends CocoView
thang.isSelectable = not thang.isLand for thang in @world.thangs # let us select walls and such thang.isSelectable = not thang.isLand for thang in @world.thangs # let us select walls and such
@surface?.setWorld @world @surface?.setWorld @world
@selectAddThangType @addThangType, @cloneSourceThang if @addThangType # make another addThang sprite, since the World just refreshed @selectAddThangType @addThangType, @cloneSourceThang if @addThangType # make another addThang sprite, since the World just refreshed
Backbone.Mediator.publish 'level-thangs-changed', thangsData: @thangsTreema.data
null null
onTreemaThangSelected: (e, selectedTreemas) => onTreemaThangSelected: (e, selectedTreemas) =>
@ -450,13 +448,13 @@ module.exports = class ThangsTabView extends CocoView
@editThangView = new LevelThangEditView thangData: thangData, level: @level, world: @world, supermodel: @supermodel # supermodel needed for checkForMissingSystems @editThangView = new LevelThangEditView thangData: thangData, level: @level, world: @world, supermodel: @supermodel # supermodel needed for checkForMissingSystems
@insertSubView @editThangView @insertSubView @editThangView
@$el.find('.thangs-column').hide() @$el.find('.thangs-column').hide()
Backbone.Mediator.publish 'level:view-switched', e Backbone.Mediator.publish 'editor:view-switched', {}
onLevelThangEdited: (e) -> onLevelThangEdited: (e) ->
newThang = e.thangData newThang = e.thangData
@thangsTreema.set "id=#{e.id}", newThang @thangsTreema.set "id=#{e.thangID}", newThang
onLevelThangDoneEditing: -> onLevelThangDoneEditing: (e) ->
@removeSubView @editThangView @removeSubView @editThangView
@editThangView = null @editThangView = null
@onThangsChanged() @onThangsChanged()
@ -531,4 +529,4 @@ class ThangNode extends TreemaObjectNode
@buildValueForDisplaySimply valEl, s @buildValueForDisplaySimply valEl, s
onEnterPressed: -> onEnterPressed: ->
Backbone.Mediator.publish 'edit-level-thang', thangID: @data.id Backbone.Mediator.publish 'editor:edit-level-thang', thangID: @data.id

View file

@ -11,23 +11,22 @@ module.exports = class ThangTypeColorsTabView extends CocoView
offset: 0 offset: 0
constructor: (@thangType, options) -> constructor: (@thangType, options) ->
@listenToOnce(@thangType, 'sync', @tryToBuild) super options
# @listenToOnce(@thangType.schema(), 'sync', @tryToBuild) @supermodel.loadModel @thangType, 'thang'
@colorConfig = {hue: 0, saturation: 0.5, lightness: 0.5} @colorConfig = {hue: 0, saturation: 0.5, lightness: 0.5}
@spriteBuilder = new SpriteBuilder(@thangType) @spriteBuilder = new SpriteBuilder(@thangType)
f = => f = =>
@offset++ @offset++
@updateMovieClip() @updateMovieClip()
@interval = setInterval f, 1000 @interval = setInterval f, 1000
super options
destroy: -> destroy: ->
clearInterval @interval clearInterval @interval
super() super()
onLoaded: -> @render()
afterRender: -> afterRender: ->
super() super()
return unless @supermodel.finished()
@createShapeButtons() @createShapeButtons()
@initStage() @initStage()
@initSliders() @initSliders()

View file

@ -21,7 +21,6 @@ module.exports = class ThangTypeEditView extends RootView
id: 'thang-type-edit-view' id: 'thang-type-edit-view'
className: 'editor' className: 'editor'
template: template template: template
startsLoading: true
resolution: 4 resolution: 4
scale: 3 scale: 3
mockThang: mockThang:
@ -45,7 +44,7 @@ module.exports = class ThangTypeEditView extends RootView
'keyup .play-with-level-input': 'onPlayLevelKeyUp' 'keyup .play-with-level-input': 'onPlayLevelKeyUp'
subscriptions: subscriptions:
'save-new-version': 'saveNewThangType' 'editor:save-new-version': 'saveNewThangType'
# init / render # init / render
@ -439,7 +438,7 @@ module.exports = class ThangTypeEditView extends RootView
level = _.string.slugify level level = _.string.slugify level
if @childWindow and not @childWindow.closed if @childWindow and not @childWindow.closed
# Reset the LevelView's world, but leave the rest of the state alone # Reset the LevelView's world, but leave the rest of the state alone
@childWindow.Backbone.Mediator.publish 'level-reload-thang-type', thangType: @thangType @childWindow.Backbone.Mediator.publish 'level:reload-thang-type', thangType: @thangType
else else
# Create a new Window with a blank LevelView # Create a new Window with a blank LevelView
scratchLevelID = level + '?dev=true' scratchLevelID = level + '?dev=true'

View file

@ -9,7 +9,7 @@ module.exports = class ChooseHeroView extends CocoView
template: template template: template
events: events:
'click #restart-level-confirm-button': -> Backbone.Mediator.publish 'restart-level' 'click #restart-level-confirm-button': -> Backbone.Mediator.publish 'level:restart-level', {}
getRenderData: (context={}) -> getRenderData: (context={}) ->
context = super(context) context = super(context)

View file

@ -61,7 +61,7 @@ module.exports = class OptionsView extends CocoView
volume = @volumeSlider.slider('value') volume = @volumeSlider.slider('value')
me.set 'volume', volume me.set 'volume', volume
@$el.find('#option-volume-value').text (volume * 100).toFixed(0) + '%' @$el.find('#option-volume-value').text (volume * 100).toFixed(0) + '%'
Backbone.Mediator.publish 'level-set-volume', volume: volume Backbone.Mediator.publish 'level:set-volume', volume: volume
onHidden: -> onHidden: ->
if @playerName and @playerName isnt me.get('name') if @playerName and @playerName isnt me.get('name')
@ -72,7 +72,7 @@ module.exports = class OptionsView extends CocoView
@aceConfig.behaviors = @$el.find('#option-behaviors').prop('checked') @aceConfig.behaviors = @$el.find('#option-behaviors').prop('checked')
@aceConfig.liveCompletion = @$el.find('#option-live-completion').prop('checked') @aceConfig.liveCompletion = @$el.find('#option-live-completion').prop('checked')
me.set 'aceConfig', @aceConfig me.set 'aceConfig', @aceConfig
Backbone.Mediator.publish 'tome:change-config' Backbone.Mediator.publish 'tome:change-config', {}
updateMusic: -> updateMusic: ->
me.set 'music', @$el.find('#option-music').prop('checked') me.set 'music', @$el.find('#option-music').prop('checked')

View file

@ -179,7 +179,7 @@ module.exports = class CocoView extends Backbone.View
$('#modal-wrapper .modal').modal(modalOptions).on 'hidden.bs.modal', @modalClosed $('#modal-wrapper .modal').modal(modalOptions).on 'hidden.bs.modal', @modalClosed
window.currentModal = modalView window.currentModal = modalView
@getRootView().stopListeningToShortcuts(true) @getRootView().stopListeningToShortcuts(true)
Backbone.Mediator.publish 'modal-opened', {} Backbone.Mediator.publish 'modal:opened', {}
modalClosed: => modalClosed: =>
visibleModal.willDisappear() if visibleModal visibleModal.willDisappear() if visibleModal
@ -193,7 +193,7 @@ module.exports = class CocoView extends Backbone.View
@openModalView(wm) @openModalView(wm)
else else
@getRootView().listenToShortcuts(true) @getRootView().listenToShortcuts(true)
Backbone.Mediator.publish 'modal-closed', {} Backbone.Mediator.publish 'modal:closed', {}
# Loading RootViews # Loading RootViews

View file

@ -36,8 +36,8 @@ module.exports = class RootView extends CocoView
showNewAchievement: (achievement, earnedAchievement) -> showNewAchievement: (achievement, earnedAchievement) ->
popup = new AchievementPopup achievement: achievement, earnedAchievement: earnedAchievement popup = new AchievementPopup achievement: achievement, earnedAchievement: earnedAchievement
handleNewAchievements: (earnedAchievements) -> handleNewAchievements: (e) ->
_.each earnedAchievements.models, (earnedAchievement) => _.each e.earnedAchievements.models, (earnedAchievement) =>
achievement = new Achievement(_id: earnedAchievement.get('achievement')) achievement = new Achievement(_id: earnedAchievement.get('achievement'))
achievement.fetch achievement.fetch
success: (achievement) => @showNewAchievement(achievement, earnedAchievement) success: (achievement) => @showNewAchievement(achievement, earnedAchievement)

View file

@ -19,8 +19,8 @@ module.exports = class AuthModal extends ModalView
'keyup #name': 'onNameChange' 'keyup #name': 'onNameChange'
subscriptions: subscriptions:
'server-error': 'onServerError' 'errors:server-error': 'onServerError'
'logging-in-with-facebook': 'onLoggingInWithFacebook' 'auth:logging-in-with-facebook': 'onLoggingInWithFacebook'
constructor: (options) -> constructor: (options) ->
@onNameChange = _.debounce @checkNameExists, 500 @onNameChange = _.debounce @checkNameExists, 500
@ -104,4 +104,4 @@ module.exports = class AuthModal extends ModalView
forms.setErrorToProperty @$el, 'name', "That name is taken! How about #{newName}?", true forms.setErrorToProperty @$el, 'name', "That name is taken! How about #{newName}?", true
onGitHubLoginClicked: -> onGitHubLoginClicked: ->
Backbone.Mediator.publish 'github-login' Backbone.Mediator.publish 'auth:log-in-with-github', {}

View file

@ -11,8 +11,8 @@ module.exports = class EmployerSignupModal extends ModalView
closeButton: true closeButton: true
subscriptions: subscriptions:
'server-error': 'onServerError' 'errors:server-error': 'onServerError'
'linkedin-loaded': 'onLinkedInLoaded' 'auth:linkedin-api-loaded': 'onLinkedInLoaded'
'created-user-without-reload': 'createdAccount' 'created-user-without-reload': 'createdAccount'
events: events:

View file

@ -18,7 +18,7 @@ module.exports = class RecoverModal extends ModalView
'keydown input': 'recoverAccount' 'keydown input': 'recoverAccount'
subscriptions: subscriptions:
'server-error': 'onServerError' 'errors:server-error': 'onServerError'
onServerError: (e) -> # TODO: work error handling into a separate forms system onServerError: (e) -> # TODO: work error handling into a separate forms system
@disableModalInProgress(@$el) @disableModalInProgress(@$el)

Some files were not shown because too many files have changed in this diff Show more