No more ThangListView for hero levels. Fixed pluralization of level loading goals when there's only one goal. Fixed default playback state to paused. Started playing ambient dungeon/grass sounds. Fixed bug with goals not showing up at first. Refactored how goals, gold, and flags hide themselves initially. Ignored InventoryView ThangTypes when sorting Components during level serialization.

This commit is contained in:
Nick Winter 2014-09-21 22:10:52 -07:00
parent 6cb8a2a019
commit 42b52f5593
13 changed files with 50 additions and 25 deletions

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

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

@ -23,10 +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
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
@ -602,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']