Removed Wizards from hero levels. Fixed issues with GameMenuModal width and swapping of hero config. No need to click start with ?dev=true. Hero is always selected in hero levels. GameMenuModal shows up while loading if no heroConfig is detected.

This commit is contained in:
Nick Winter 2014-09-21 20:19:27 -07:00
parent 949f4594af
commit 600e985259
14 changed files with 82 additions and 48 deletions

View file

@ -63,7 +63,7 @@ module.exports = class LevelLoader extends CocoClass
loadSession: ->
return if @headless
if @sessionID
url = "/db/level_session/#{@sessionID}"
url = "/db/level.session/#{@sessionID}"
else
url = "/db/level/#{@levelID}/session"
url += "?team=#{@team}" if @team
@ -72,14 +72,15 @@ module.exports = class LevelLoader extends CocoClass
@sessionResource = @supermodel.loadModel(session, 'level_session', {cache: false})
@session = @sessionResource.model
if @session.loaded
@session.setURL '/db/level.session/' + @session.id
@loadDependenciesForSession @session
else
@listenToOnce @session, 'sync', ->
@session.url = -> '/db/level.session/' + @id
@session.setURL '/db/level.session/' + @session.id
@loadDependenciesForSession @session
if @opponentSessionID
opponentSession = new LevelSession().setURL "/db/level_session/#{@opponentSessionID}"
opponentSession = new LevelSession().setURL "/db/level.session/#{@opponentSessionID}"
@opponentSessionResource = @supermodel.loadModel(opponentSession, 'opponent_session')
@opponentSession = @opponentSessionResource.model
if @opponentSession.loaded
@ -100,6 +101,9 @@ module.exports = class LevelLoader extends CocoClass
url = "/db/thang.type/#{itemThangType}/version?project=name,components,original"
@worldNecessities.push @maybeLoadURL(url, ThangType, 'thang')
if session is @session
Backbone.Mediator.publish 'level:session-loaded', level: @level, session: @session
# Grabbing the rest of the required data for the level
populateLevel: ->

View file

@ -81,6 +81,10 @@ module.exports =
level: {type: 'object'}
team: {type: ['string', 'null', 'undefined']}
'level:session-loaded': c.object {required: ['level', 'session']},
level: {type: 'object'}
session: {type: 'object'}
'level:loading-view-unveiling': c.object {}
'level:loading-view-unveiled': c.object {required: ['view']},

View file

@ -28,7 +28,8 @@
.modal-dialog
margin-top: 0
width: 963px
.nav-tabs
h2
margin: 0

View file

@ -25,6 +25,7 @@
left: 50%
$WIDTH: 1000px
width: $WIDTH
min-height: 60px
margin-left: (-$WIDTH / 2)
z-index: 100
background-color: rgba(220, 255, 230, 0.6)

View file

@ -8,7 +8,7 @@
.replace-me(data-item-id=equipment[slot].get('original'))
.item-slot-column.pull-left
for slot in ['torso', 'gloves', 'left-hand', 'minion']
for slot in ['minion', 'torso', 'gloves', 'left-hand']
.item-slot(data-slot=slot)
.placeholder
.item-container
@ -26,7 +26,7 @@
span.glyphicon.glyphicon-transfer
.item-slot-column.pull-right
for slot in ['waist', 'feet', 'right-hand', 'pet']
for slot in ['pet', 'waist', 'feet', 'right-hand']
.item-slot(data-slot=slot)
.placeholder
.item-container

View file

@ -23,7 +23,6 @@ module.exports = class ChooseHeroView extends CocoView
constructor: (options) ->
super options
@heroes = new CocoCollection([], {model: ThangType})
@equipment = options.equipment or @options.session?.get('heroConfig')?.inventory or {}
@heroes.url = '/db/thang.type?view=heroes&project=original,name,slug,soundTriggers'
@supermodel.loadCollection(@heroes, 'heroes')
@stages = {}

View file

@ -11,7 +11,6 @@ submenuViews = [
module.exports = class GameMenuModal extends ModalView
template: template
modalWidthPercent: 95
id: 'game-menu-modal'
instant: true
@ -52,7 +51,7 @@ module.exports = class GameMenuModal extends ModalView
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
updateConfig: ->
sessionHeroConfig = @options.session.get('heroConfig') ? {}
sessionHeroConfig = $.extend {}, true, (@options.session.get('heroConfig') ? {})
lastHeroConfig = me.get('heroConfig') ? {}
thangType = @subviews.choose_hero_view.selectedHero.get 'original'
inventory = @subviews.inventory_view.getCurrentEquipmentConfig()
@ -72,8 +71,11 @@ module.exports = class GameMenuModal extends ModalView
me.set 'aceConfig', aceConfig
if patchSession
@options.session.set 'heroConfig', sessionHeroConfig
@options.session.patch success: ->
success = ->
_.defer -> Backbone.Mediator.publish 'level:hero-config-changed', {}
error = (model, res) ->
console.error 'error patching session', model, res, res.responseJSON, res.status, res.statusText
@options.session.patch success: success, error: error
if patchMe
me.set 'heroConfig', lastHeroConfig
me.patch()

View file

@ -29,6 +29,7 @@ module.exports = class InventoryView extends CocoView
super(arguments...)
@items = new CocoCollection([], {model: ThangType})
@equipment = options.equipment or @options.session?.get('heroConfig')?.inventory or me.get('heroConfig')?.inventory or {}
@equipment = $.extend true, {}, @equipment
@assignLevelEquipment()
@items.url = '/db/thang.type?view=items&project=name,components,original,rasterIcon'
@supermodel.loadCollection(@items, 'items')
@ -88,6 +89,7 @@ module.exports = class InventoryView extends CocoView
cursorAt: {left: 35.5, top: 35.5}
helper: -> dragHelper
revertDuration: 200
distance: 10
scroll: false
zIndex: 100
itemView.$el.on 'dragstart', =>
@ -137,6 +139,8 @@ module.exports = class InventoryView extends CocoView
@onSelectionChanged()
onAvailableItemDoubleClick: (e) ->
@selectAvailableItem $(e.target).closest('.list-group-item')
@onSelectionChanged()
slot = @getSelectedSlot()
slot = @$el.find('.item-slot:not(.disabled):first') if not slot.length
@unequipItemFromSlot(slot)

View file

@ -24,7 +24,6 @@ module.exports = class MultiplayerView extends CocoView
super(options)
@level = options.level
@session = options.session
@playableTeams = options.playableTeams
@listenTo @session, 'change:multiplayer', @updateLinkSection
@initMultiplayerSessions()
@ -40,7 +39,6 @@ module.exports = class MultiplayerView extends CocoView
c.multiplayer = @session.get 'multiplayer'
c.team = @session.get 'team'
c.levelSlug = @level?.get 'slug'
c.playableTeams = @playableTeams
# For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet.
if @level?.get('type') is 'ladder'
c.ladderGame = true

View file

@ -98,9 +98,9 @@ module.exports = class SpectateLevelView extends RootView
$('body').addClass('is-playing')
onLoaded: ->
_.defer => @onLevelLoaded()
_.defer => @onLevelLoaderLoaded()
onLevelLoaded: ->
onLevelLoaderLoaded: ->
@grabLevelLoaderData()
#at this point, all requisite data is loaded, and sessions are not denormalized
team = @world.teamForPlayer(0)
@ -119,18 +119,19 @@ module.exports = class SpectateLevelView extends RootView
@register()
@controlBar.setBus(@bus)
@surface.showLevel()
if me.id isnt @session.get 'creator'
@surface.createOpponentWizard
id: @session.get('creator')
name: @session.get('creatorName')
team: @session.get('team')
levelSlug: @level.get('slug')
if @level.get('type', true) isnt 'hero'
if me.id isnt @session.get 'creator'
@surface.createOpponentWizard
id: @session.get('creator')
name: @session.get('creatorName')
team: @session.get('team')
levelSlug: @level.get('slug')
@surface.createOpponentWizard
id: @otherSession.get('creator')
name: @otherSession.get('creatorName')
team: @otherSession.get('team')
levelSlug: @level.get('slug')
@surface.createOpponentWizard
id: @otherSession.get('creator')
name: @otherSession.get('creatorName')
team: @otherSession.get('team')
levelSlug: @level.get('slug')
grabLevelLoaderData: ->
@session = @levelLoader.session
@ -186,7 +187,7 @@ module.exports = class SpectateLevelView extends RootView
ctx.fillText("Loaded #{@modelsLoaded} thingies",50,50)
insertSubviews: ->
@insertSubView @tome = new TomeView levelID: @levelID, session: @session, thangs: @world.thangs, supermodel: @supermodel, spectateView: true, spectateOpponentCodeLanguage: @otherSession?.get('submittedCodeLanguage')
@insertSubView @tome = new TomeView levelID: @levelID, session: @session, thangs: @world.thangs, supermodel: @supermodel, spectateView: true, spectateOpponentCodeLanguage: @otherSession?.get('submittedCodeLanguage'), level: @level
@insertSubView new PlaybackView {}
@insertSubView new GoldView {}
@ -205,7 +206,7 @@ module.exports = class SpectateLevelView extends RootView
initSurface: ->
surfaceCanvas = $('canvas#surface', @$el)
@surface = new Surface(@world, surfaceCanvas, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, spectateGame: true)
@surface = new Surface(@world, surfaceCanvas, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, spectateGame: true, wizards: @level.get('type', true) isnt 'hero')
worldBounds = @world.getBounds()
bounds = [{x:worldBounds.left, y:worldBounds.top}, {x:worldBounds.right, y:worldBounds.bottom}]
@surface.camera.setBounds(bounds)

View file

@ -32,7 +32,6 @@ module.exports = class ControlBarView extends CocoView
@worldName = options.worldName
@session = options.session
@level = options.level
@playableTeams = options.playableTeams
@spectateGame = options.spectateGame ? false
super options
@ -83,7 +82,7 @@ module.exports = class ControlBarView extends CocoView
@guideHighlightInterval = null
showGameMenuModal: ->
@openModalView new GameMenuModal level: @level, session: @session, playableTeams: @playableTeams
@openModalView new GameMenuModal level: @level, session: @session
onJoinedRealTimeMultiplayerGame: (e) ->
@multiplayerSession = e.session

View file

@ -6,11 +6,11 @@ module.exports = class LevelLoadingView extends CocoView
template: template
events:
'mousedown .start-level-button': 'startUnveiling' # split into two for animation smoothness
'mousedown .start-level-button': 'startUnveiling' # Split into two for animation smoothness.
'click .start-level-button': 'onClickStartLevel'
subscriptions:
'level:loaded': 'onLevelLoaded'
'level:loaded': 'onLevelLoaded' # If Level loads after level loading view.
afterRender: ->
@$el.find('.tip.rare').remove() if _.random(1, 10) < 9
@ -18,13 +18,13 @@ module.exports = class LevelLoadingView extends CocoView
tip = _.sample(tips)
$(tip).removeClass('to-remove')
@$el.find('.to-remove').remove()
@onLevelLoaded level: @options.level if @options.level?.get('goals') # If Level was already loaded.
onLevelLoaded: (e) ->
@level = e.level
goalList = @$el.find('.level-loading-goals').removeClass('secret').find('ul')
for goalID, goal of @level.get('goals') when not goal.team or goal.team is e.team
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>')
console.log 'got goals', @level.get('goals'), 'team', e.team
showReady: ->
return if @shownReady
@ -32,7 +32,11 @@ module.exports = class LevelLoadingView extends CocoView
ready = $.i18n.t('play_level.loading_ready', defaultValue: 'Ready!')
@$el.find('#tip-wrapper .tip').addClass('ready').text ready
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'level_loaded', volume: 0.75 # old: loading_ready
@$el.find('.start-level-button').removeClass 'secret'
if @options.autoUnveil
@startUnveiling()
@unveil()
else
@$el.find('.start-level-button').removeClass 'secret'
startUnveiling: (e) ->
Backbone.Mediator.publish 'level:loading-view-unveiling', {}

View file

@ -33,6 +33,7 @@ LevelFlagsView = require './LevelFlagsView'
GoldView = require './LevelGoldView'
VictoryModal = require './modal/VictoryModal'
InfiniteLoopModal = require './modal/InfiniteLoopModal'
GameMenuModal = require 'views/game-menu/GameMenuModal'
PROFILE_ME = false
@ -64,6 +65,8 @@ module.exports = class PlayLevelView extends RootView
'level:started': 'onLevelStarted'
'level:loading-view-unveiling': 'onLoadingViewUnveiling'
'level:loading-view-unveiled': 'onLoadingViewUnveiled'
'level:loaded': 'onLevelLoaded'
'level:session-loaded': 'onSessionLoaded'
'playback:real-time-playback-waiting': 'onRealTimePlaybackWaiting'
'playback:real-time-playback-started': 'onRealTimePlaybackStarted'
'playback:real-time-playback-ended': 'onRealTimePlaybackEnded'
@ -171,14 +174,13 @@ module.exports = class PlayLevelView extends RootView
afterRender: ->
super()
window.onPlayLevelViewLoaded? @ # still a hack
@insertSubView @loadingView = new LevelLoadingView {}
@insertSubView @loadingView = new LevelLoadingView autoUnveil: @options.autoUnveil, level: @level # May not have @level loaded yet
@$el.find('#level-done-button').hide()
$('body').addClass('is-playing')
$('body').bind('touchmove', false) if @isIPadApp()
afterInsert: ->
super()
@showWizardSettingsModal() if not me.get('name') and not @isIPadApp()
# Partially Loaded Setup ####################################################
@ -252,7 +254,7 @@ module.exports = class PlayLevelView extends RootView
@god.setGoalManager @goalManager
insertSubviews: ->
@insertSubView @tome = new TomeView levelID: @levelID, session: @session, otherSession: @otherSession, thangs: @world.thangs, supermodel: @supermodel
@insertSubView @tome = new TomeView levelID: @levelID, session: @session, otherSession: @otherSession, thangs: @world.thangs, supermodel: @supermodel, level: @level
@insertSubView new LevelPlaybackView session: @session
@insertSubView new GoalsView {}
@insertSubView new LevelFlagsView world: @world
@ -260,7 +262,7 @@ module.exports = class PlayLevelView extends RootView
@insertSubView new HUDView {}
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
worldName = utils.i18n @level.attributes, 'name'
@controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel, playableTeams: @world.playableTeams}
@controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel}
Backbone.Mediator.publish('level:set-debug', debug: true) if @isIPadApp() # if me.displayName() is 'Nick'
initVolume: ->
@ -280,10 +282,19 @@ module.exports = class PlayLevelView extends RootView
# Load Completed Setup ######################################################
onLoaded: ->
_.defer => @onLevelLoaded()
onLevelLoaded: (e) ->
# Just the level has been loaded by the level loader
@showWizardSettingsModal() if not me.get('name') and not @isIPadApp() and e.level.get('type', true) isnt 'hero'
onLevelLoaded: ->
onSessionLoaded: (e) ->
# Just the level and session have been loaded by the level loader
if e.level.get('type', true) is 'hero' and not _.size e.session.get('heroConfig')?.inventory ? {}
@openModalView new GameMenuModal level: e.level, session: e.session
onLoaded: ->
_.defer => @onLevelLoaderLoaded()
onLevelLoaderLoaded: ->
# Everything is now loaded
return unless @levelLoader.progress() is 1 # double check, since closing the guide may trigger this early
@ -306,7 +317,7 @@ module.exports = class PlayLevelView extends RootView
initSurface: ->
surfaceCanvas = $('canvas#surface', @$el)
@surface = new Surface(@world, surfaceCanvas, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview)
@surface = new Surface(@world, surfaceCanvas, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, wizards: @level.get('type', true) isnt 'hero')
worldBounds = @world.getBounds()
bounds = [{x: worldBounds.left, y: worldBounds.top}, {x: worldBounds.right, y: worldBounds.bottom}]
@surface.camera.setBounds(bounds)
@ -320,9 +331,12 @@ module.exports = class PlayLevelView extends RootView
if window.currentModal and not window.currentModal.destroyed
return Backbone.Mediator.subscribeOnce 'modal:closed', @onLevelStarted, @
@surface.showLevel()
if @otherSession
if @otherSession and @level.get('type', true) isnt 'hero'
# TODO: colorize name and cloud by team, colorize wizard by user's color config
@surface.createOpponentWizard id: @otherSession.get('creator'), name: @otherSession.get('creatorName'), team: @otherSession.get('team'), levelSlug: @level.get('slug'), codeLanguage: @otherSession.get('submittedCodeLanguage')
if @isEditorPreview
@loadingView.startUnveiling()
@loadingView.unveil()
onLoadingViewUnveiling: (e) ->
@restoreSessionState()
@ -342,13 +356,13 @@ module.exports = class PlayLevelView extends RootView
return if @alreadyLoadedState
@alreadyLoadedState = true
state = @originalSessionState
if state.frame and @level.get('type') isnt 'ladder' # https://github.com/codecombat/codecombat/issues/714
if state.frame and @level.get('type', true) isnt 'ladder' # https://github.com/codecombat/codecombat/issues/714
Backbone.Mediator.publish 'level:set-time', time: 0, frameOffset: state.frame
if state.selected
if @level.get('type', true) is 'hero'
Backbone.Mediator.publish 'tome:select-primary-sprite', {}
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
else if @isIPadApp()
Backbone.Mediator.publish 'tome:select-primary-sprite', {}
if state.playing?
Backbone.Mediator.publish 'level:set-playing', playing: state.playing
@ -378,10 +392,12 @@ module.exports = class PlayLevelView extends RootView
#@setLevel @level, @supermodel
#Backbone.Mediator.publish 'tome:cast-spell', {}
# We'll just make a new PlayLevelView instead
console.log 'Hero config changed; reload the level.'
Backbone.Mediator.publish 'router:navigate', {
route: window.location.pathname,
viewClass: PlayLevelView,
viewArgs: [{supermodel: @supermodel}, @levelID]}
viewArgs: [{supermodel: @supermodel, autoUnveil: true}, @levelID]
}
onWindowResize: (s...) ->
$('#pointer').css('opacity', 0.0)

View file

@ -183,6 +183,7 @@ module.exports = class TomeView extends CocoView
@thangList?.$el.show()
onSpriteSelected: (e) ->
return if @spellView and @options.level.get('type', true) is 'hero' # Never deselect the hero in the Tome.
thang = e.thang
spellName = e.spellName
@spellList?.$el.hide()