mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-14 05:55:00 -04:00
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:
parent
6cb8a2a019
commit
42b52f5593
13 changed files with 50 additions and 25 deletions
app
lib/surface
locale
models
templates/play
views
server/levels
|
@ -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
|
||||
|
|
|
@ -383,6 +383,7 @@
|
|||
guide: "Guide"
|
||||
restart: "Restart"
|
||||
goals: "Goals"
|
||||
goal: "Goal"
|
||||
success: "Success!"
|
||||
incomplete: "Incomplete"
|
||||
timed_out: "Ran out of time"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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={}) ->
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -27,6 +27,7 @@ LevelHandler = class LevelHandler extends Handler
|
|||
'showsGuide'
|
||||
'banner'
|
||||
'employerDescription'
|
||||
'terrain'
|
||||
]
|
||||
|
||||
postEditableProperties: ['name']
|
||||
|
|
Loading…
Add table
Reference in a new issue