Merge branch 'master' into production

This commit is contained in:
Nick Winter 2014-09-21 22:19:11 -07:00
commit 7b8333be71
14 changed files with 64 additions and 28 deletions

View file

@ -94,7 +94,7 @@ module.exports = class LevelLoader extends CocoClass
heroConfig ?= me.get('heroConfig')
heroConfig ?= {inventory: {}, thangType: '529ffbf1cf1818f2be000001'} # If we got here not from PlayLevelModal (like level editor preview), assign Tharin as the hero.
session.set 'heroConfig', heroConfig unless _.isEqual heroConfig, session.get('heroConfig')
url = "/db/thang.type/#{heroConfig.thangType}/version?project=name,components,original"
url = "/db/thang.type/#{heroConfig.thangType}/version"
@worldNecessities.push @maybeLoadURL(url, ThangType, 'thang')
for itemThangType in _.values(heroConfig.inventory)

View file

@ -34,7 +34,7 @@ module.exports = Surface = class Surface extends CocoClass
currentFrame: 0
lastFrame: null
totalFramesDrawn: 0
playing: false # play vs. pause
playing: false # play vs. pause -- match default button state in playback.jade
dead: false # if we kill it for some reason
imagesLoaded: false
worldLoaded: false
@ -204,6 +204,7 @@ module.exports = Surface = class Surface extends CocoClass
if @mouseInBounds isnt mib
Backbone.Mediator.publish('surface:mouse-' + (if mib then 'over' else 'out'), {})
@mouseInBounds = mib
@mouseIsDown = false
restoreWorldState: ->
frame = @world.getFrame(@getCurrentFrame())
@ -218,6 +219,8 @@ module.exports = Surface = class Surface extends CocoClass
updateState: (frameChanged) ->
# world state must have been restored in @restoreWorldState
if @playing and @heroSprite and not @mouseIsDown and @camera.newTarget isnt @heroSprite.imageObject and @camera.target isnt @heroSprite.imageObject
@camera.zoomTo @heroSprite.imageObject, @camera.zoom, 750
@camera.updateZoom()
@spriteBoss.update frameChanged
@dimmer?.setSprites @spriteBoss.sprites
@ -464,12 +467,14 @@ module.exports = Surface = class Surface extends CocoClass
event = onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e, worldPos: wop
Backbone.Mediator.publish 'surface:stage-mouse-down', event
Backbone.Mediator.publish 'tome:focus-editor', {}
@mouseIsDown = true
onMouseUp: (e) =>
return if @disabled
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 'tome:focus-editor', {}
@mouseIsDown = false
onMouseWheel: (e) =>
# https://github.com/brandonaaron/jquery-mousewheel
@ -483,7 +488,6 @@ module.exports = Surface = class Surface extends CocoClass
Backbone.Mediator.publish 'surface:mouse-scrolled', event unless @disabled
#- Canvas callbacks
onResize: (e) =>
@ -515,6 +519,10 @@ module.exports = Surface = class Surface extends CocoClass
@camera.onResize newWidth, newHeight
#- Camera focus on hero
focusOnHero: ->
@heroSprite = @spriteBoss.spriteFor 'Hero Placeholder'
#- Real-time playback

View file

@ -383,6 +383,7 @@
guide: "Guide"
restart: "Restart"
goals: "Goals"
goal: "Goal"
success: "Success!"
incomplete: "Incomplete"
timed_out: "Ran out of time"

View file

@ -24,7 +24,7 @@ module.exports = class Level extends CocoModel
# Figure out ThangTypes' Components
tmap = {}
tmap[t.thangType] = true for t in o.thangs ? []
o.thangTypes = (original: tt.get('original'), name: tt.get('name'), components: $.extend(true, [], tt.get('components')) for tt in supermodel.getModels ThangType when tmap[tt.get('original')] or tt.get('components'))
o.thangTypes = (original: tt.get('original'), name: tt.get('name'), components: $.extend(true, [], tt.get('components')) for tt in supermodel.getModels ThangType when tmap[tt.get('original')] or (tt.get('components') and not tt.notInLevel))
@sortThangComponents o.thangTypes, o.levelComponents, 'ThangType'
@fillInDefaultComponentConfiguration o.thangTypes, o.levelComponents

View file

@ -13,11 +13,11 @@
canvas(width=924, height=589)#surface
#canvas-left-gradient.gradient
#canvas-top-gradient.gradient
#goals-view.secret
#goals-view
#level-flags-view.secret
#level-flags-view
#gold-view.secret.expanded
#gold-view
#level-chat-view

View file

@ -1,4 +1,4 @@
button.btn.btn-xs.btn-inverse#play-button.playing(title="Ctrl/Cmd + P: Toggle level play/pause")
button.btn.btn-xs.btn-inverse#play-button.paused(title="Ctrl/Cmd + P: Toggle level play/pause")
i.icon-play.icon-white.big
i.icon-pause.icon-white.big
i.icon-repeat.icon-white.big

View file

@ -40,6 +40,7 @@ module.exports = class InventoryView extends CocoView
onLoaded: ->
@items.models = _.filter(@items.models, (item) => item.get('original') in @allowedItems) if @allowedItems
item.notInLevel = true for item in @items.models
super()
getRenderData: (context={}) ->

View file

@ -8,6 +8,7 @@ multiplayerFlagDelay = 0.5 # Long, static second delay for now; should be more
module.exports = class LevelFlagsView extends CocoView
id: 'level-flags-view'
template: template
className: 'secret'
subscriptions:
'playback:real-time-playback-started': 'onRealTimePlaybackStarted'

View file

@ -11,6 +11,9 @@ stateIconMap =
module.exports = class LevelGoalsView extends CocoView
id: 'goals-view'
template: template
className: 'secret expanded'
playbackEnded: false
mouseEntered: false
subscriptions:
'goal-manager:new-goal-states': 'onNewGoalStates'
@ -67,6 +70,7 @@ module.exports = class LevelGoalsView extends CocoView
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'goal-incomplete-again', volume: 1
@previousGoalStatus[goal.id] = state.status
@$el.removeClass('secret') if goals.length > 0
@updatePlacement()
onSurfacePlaybackRestarted: ->
@playbackEnded = false
@ -78,14 +82,6 @@ module.exports = class LevelGoalsView extends CocoView
@$el.addClass 'brighter'
@updatePlacement()
render: ->
super()
@$el.addClass('secret').addClass('expanded')
afterRender: ->
super()
@updatePlacement()
updatePlacement: ->
expand = @playbackEnded or @mouseEntered
return if expand is @expanded

View file

@ -1,5 +1,6 @@
CocoView = require 'views/kinds/CocoView'
template = require 'templates/play/level/level_loading'
utils = require 'lib/utils'
module.exports = class LevelLoadingView extends CocoView
id: 'level-loading-view'
@ -22,9 +23,17 @@ module.exports = class LevelLoadingView extends CocoView
onLevelLoaded: (e) ->
@level = e.level
goalList = @$el.find('.level-loading-goals').removeClass('secret').find('ul')
goalContainer = @$el.find('.level-loading-goals')
goalList = goalContainer.find('ul')
goalCount = 0
for goalID, goal of @level.get('goals') when (not goal.team or goal.team is e.team) and not goal.hiddenGoal
goalList.append $('<li class="list-group-item header-font">' + goal.name + '</li>')
name = utils.i18n goal, 'name'
goalList.append $('<li class="list-group-item header-font">' + name + '</li>')
++goalCount
if goalCount
goalContainer.removeClass('secret')
if goalCount is 1
goalContainer.find('.panel-heading').text $.i18n.t 'play_level.goal' # Not plural
showReady: ->
return if @shownReady

View file

@ -351,6 +351,17 @@ module.exports = class PlayLevelView extends RootView
console.debug "Level unveiled after #{(loadDuration / 1000).toFixed(2)}s"
application.tracker?.trackEvent 'Finished Level Load', level: @levelID, label: @levelID, loadDuration: loadDuration, ['Google Analytics']
application.tracker?.trackTiming loadDuration, 'Level Load Time', @levelID, @levelID
@playAmbientSound()
playAmbientSound: ->
return if @ambientSound
return unless file = {Dungeon: 'ambient-dungeon', Grass: 'ambient-grass'}[@level.get('terrain')]
src = "/file/interface/#{file}#{AudioPlayer.ext}"
unless AudioPlayer.getStatus(src)?.loaded
AudioPlayer.preloadSound src
Backbone.Mediator.subscribeOnce 'audio-player:loaded', @playAmbientSound, @
return
@ambientSound = createjs.Sound.play src, loop: -1
restoreSessionState: ->
return if @alreadyLoadedState
@ -360,6 +371,7 @@ module.exports = class PlayLevelView extends RootView
Backbone.Mediator.publish 'level:set-time', time: 0, frameOffset: state.frame
if @level.get('type', true) is 'hero'
Backbone.Mediator.publish 'tome:select-primary-sprite', {}
@surface.focusOnHero()
else if state.selected
# TODO: Should also restore selected spell here by saving spellName
Backbone.Mediator.publish 'level:select-sprite', thangID: state.selected, spellName: null
@ -601,6 +613,7 @@ module.exports = class PlayLevelView extends RootView
@god?.destroy()
@goalManager?.destroy()
@scriptManager?.destroy()
@ambientSound.stop()
$(window).off 'resize', @onWindowResize
delete window.world # not sure where this is set, but this is one way to clean it up
clearInterval(@pointerInterval)

View file

@ -11,9 +11,6 @@ module.exports = class ThangListView extends CocoView
id: 'thang-list-view'
template: template
subscriptions:
'tome:select-primary-sprite': 'onSelectPrimarySprite'
constructor: (options) ->
super options
@spells = options.spells
@ -75,6 +72,9 @@ module.exports = class ThangListView extends CocoView
return entry.spells[0]
null
selectPrimarySprite: ->
@entries[0]?.select()
adjustThangs: (spells, thangs) ->
# TODO: it would be nice to not have to do this any more, like if we migrate to the hero levels.
# Recreating all the ThangListEntryViews and their ThangAvatarViews is pretty slow.
@ -90,9 +90,6 @@ module.exports = class ThangListView extends CocoView
@sortThangs()
@addThangListEntries()
onSelectPrimarySprite: (e) ->
@entries[0]?.select()
destroy: ->
entry.destroy() for entry in @entries
super()

View file

@ -52,6 +52,7 @@ module.exports = class TomeView extends CocoView
'surface:sprite-selected': 'onSpriteSelected'
'god:new-world-created': 'onNewWorld'
'tome:comment-my-code': 'onCommentMyCode'
'tome:select-primary-sprite': 'onSelectPrimarySprite'
events:
'click #spell-view': 'onSpellViewClick'
@ -63,7 +64,7 @@ module.exports = class TomeView extends CocoView
programmableThangs = _.filter @options.thangs, 'isProgrammable'
@createSpells programmableThangs, programmableThangs[0]?.world # Do before spellList, thangList, and castButton
@spellList = @insertSubView new SpellListView spells: @spells, supermodel: @supermodel
@thangList = @insertSubView new ThangListView spells: @spells, thangs: @options.thangs, supermodel: @supermodel
@thangList = @insertSubView new ThangListView spells: @spells, thangs: @options.thangs, supermodel: @supermodel unless @options.level.get('type', true) is 'hero'
@castButton = @insertSubView new CastButtonView spells: @spells, levelID: @options.levelID
@teamSpellMap = @generateTeamSpellMap(@spells)
unless programmableThangs.length
@ -77,7 +78,7 @@ module.exports = class TomeView extends CocoView
thangs = _.filter e.world.thangs, 'inThangList'
programmableThangs = _.filter thangs, 'isProgrammable'
@createSpells programmableThangs, e.world
@thangList.adjustThangs @spells, thangs
@thangList?.adjustThangs @spells, thangs
@spellList.adjustSpells @spells
onCommentMyCode: (e) ->
@ -200,7 +201,7 @@ module.exports = class TomeView extends CocoView
@$el.find('#' + @spellView.id).after(@spellView.el).remove()
@$el.find('#' + @spellTabView.id).after(@spellTabView.el).remove()
@castButton.attachTo @spellView
@thangList.$el.hide()
@thangList?.$el.hide()
Backbone.Mediator.publish 'tome:spell-shown', thang: thang, spell: spell
@spellList.setThangAndSpell thang, spell
@spellView?.setThang thang
@ -218,9 +219,11 @@ module.exports = class TomeView extends CocoView
selectedThangSpells = (@spells[spellKey] for spellKey in @thangSpells[thang.id])
if spellName
spell = _.find selectedThangSpells, {name: spellName}
else
else if @thangList
spell = @thangList.topSpellForThang thang
#spell = selectedThangSpells[0] # TODO: remember last selected spell for this thang
else
spell = _.find selectedThangSpells, (spell) -> true # Just grab one
spell
reloadAllCode: ->
@ -231,6 +234,12 @@ module.exports = class TomeView extends CocoView
spell.updateLanguageAether e.language for spellKey, spell of @spells when spell.canWrite()
@cast()
onSelectPrimarySprite: (e) ->
if @thangList
@thangList.selectPrimarySprite()
else
Backbone.Mediator.publish 'level:select-sprite', thangID: 'Hero Placeholder'
destroy: ->
spell.destroy() for spellKey, spell of @spells
@worker?.terminate()

View file

@ -27,6 +27,7 @@ LevelHandler = class LevelHandler extends Handler
'showsGuide'
'banner'
'employerDescription'
'terrain'
]
postEditableProperties: ['name']