mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-25 16:47:58 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
7b8333be71
14 changed files with 64 additions and 28 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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…
Reference in a new issue