Integrated the new PlayHeroesModal into the game, refactoring PlayLevelModal into LevelSetupManager.

This commit is contained in:
Scott Erickson 2014-11-06 16:23:23 -08:00
parent 790dd8e7e0
commit 424c3a6d3e
13 changed files with 221 additions and 259 deletions

View file

@ -0,0 +1,79 @@
CocoClass = require 'lib/CocoClass'
PlayHeroesModal = require 'views/play/modal/PlayHeroesModal'
InventoryModal = require 'views/game-menu/InventoryModal'
PlayLevelView = require 'views/play/level/PlayLevelView'
LadderView = require 'views/play/ladder/LadderView'
LevelSession = require 'models/LevelSession'
SuperModel = require 'models/SuperModel'
module.exports = class LevelSetupManager extends CocoClass
constructor: (@options) ->
super()
@options.showDevBits = true #?
@supermodel = new SuperModel()
@session = @options.session
if @session
@fillSessionWithDefaults()
else
@loadSession(@supermodel)
# build modals and prevent them from disappearing.
@heroesModal = new PlayHeroesModal({supermodel: @supermodel, session: @session, confirmButtonI18N: 'play.next', levelID: options.levelID})
@inventoryModal = new InventoryModal({supermodel: @supermodel, session: @session, levelID: options.levelID})
@heroesModalDestroy = @heroesModal.destroy
@inventoryModalDestroy = @inventoryModal.destroy
@heroesModal.destroy = @inventoryModal.destroy = _.noop
@listenTo @heroesModal, 'confirm-click', @onHeroesModalConfirmClicked
@listenToOnce @heroesModal, 'hero-loaded', @onceHeroLoaded
@listenTo @inventoryModal, 'choose-hero-click', @onChooseHeroClicked
@listenTo @inventoryModal, 'play-click', @onInventoryModalPlayClicked
loadSession: (supermodel) ->
url = "/db/level/#{@options.levelID}/session"
#url += "?team=#{@team}" if @options.team # TODO: figure out how to get the teams for multiplayer PVP hero style
@session = new LevelSession().setURL url
@listenToOnce @session, 'sync', ->
@session.url = -> '/db/level.session/' + @id
@fillSessionWithDefaults()
supermodel.loadModel(@session, 'level_session').model
fillSessionWithDefaults: ->
heroConfig = _.merge {}, me.get('heroConfig'), @session.get('heroConfig')
@session.set('heroConfig', heroConfig)
open: ->
firstModal = if @options.hadEverChosenHero then @inventoryModal else @heroesModal
@options.parent.openModalView(firstModal)
# @inventoryModal.onShown() # replace?
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
#- Modal events
onceHeroLoaded: (e) ->
@inventoryModal.setHero(e.hero)
onHeroesModalConfirmClicked: (e) ->
@options.parent.openModalView(@inventoryModal)
@inventoryModal.render()
@inventoryModal.didReappear()
@inventoryModal.onShown()
@inventoryModal.setHero(e.hero)
window.tracker?.trackEvent 'Play Level Modal', Action: 'Choose Inventory'
onChooseHeroClicked: ->
@options.parent.openModalView(@heroesModal)
@heroesModal.render()
@heroesModal.didReappear()
@inventoryModal.endHighlight()
window.tracker?.trackEvent 'Play Level Modal', Action: 'Choose Hero'
onInventoryModalPlayClicked: ->
@navigatingToPlay = true
viewClass = if @options.levelPath is 'ladder' then LadderView else PlayLevelView
Backbone.Mediator.publish 'router:navigate', {
route: "/play/#{@options.levelPath || 'level'}/#{@options.levelID}"
viewClass: viewClass
viewArgs: [{supermodel: @supermodel}, @options.levelID]
}

View file

@ -23,7 +23,7 @@
right: 35px right: 35px
bottom: 20px bottom: 20px
#inventory-view #available-equipment #inventory-modal #available-equipment
bottom: 60px bottom: 60px
.modal-dialog .modal-dialog

View file

@ -19,9 +19,15 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin
@include box-shadow(0 0 10px #28f) @include box-shadow(0 0 10px #28f)
z-index: 9001 z-index: 9001
#inventory-view #inventory-modal
position: relative .modal-dialog
height: $inventoryHeight margin: 30px auto 0 auto
width: 720px
.modal-body
height: 450px
margin: 0
+user-select(none) +user-select(none)
h3 h3
@ -34,7 +40,7 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin
#equipped #equipped
width: $equippedWidth width: $equippedWidth
position: absolute position: absolute
left: 0 left: 20px
top: 0 top: 0
bottom: 0 bottom: 0
//bottom: $selectedAreaHeight + 10 //bottom: $selectedAreaHeight + 10
@ -197,7 +203,7 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin
#available-equipment #available-equipment
width: $stashWidth width: $stashWidth
position: absolute position: absolute
right: 0 right: 20px
top: 0 top: 0
bottom: 0 bottom: 0
overflow-y: scroll overflow-y: scroll

View file

@ -5,15 +5,13 @@ block modal-header
block modal-body-content block modal-body-content
.button.close(type="button", data-dismiss="modal", aria-hidden="true") × .button.close(type="button", data-dismiss="modal", aria-hidden="true") ×
.tabbable.tabs-left .tabbable.tabs-left
- var submenus = ["inventory", "choose-hero", "save-load", "options", "guide", "multiplayer"] - var submenus = ["save-load", "options", "guide", "multiplayer"]
- if (!showsGuide) { - if (!showsGuide) {
- submenus.splice(4, 1);
- }
- if (!showDevBits) { // Not done yet.
- submenus.splice(2, 1); - submenus.splice(2, 1);
- } - }
- if (!showInventory) - if (!showDevBits) { // Not done yet.
- submenus.splice(0, 1); - submenus.splice(0, 1);
- }
ul.nav.nav-tabs#game-menu-nav ul.nav.nav-tabs#game-menu-nav
for submenu, index in submenus for submenu, index in submenus
li(class=submenu === showTab || index === 0 && !showTab ? "active" : "") li(class=submenu === showTab || index === 0 && !showTab ? "active" : "")

View file

@ -0,0 +1,68 @@
extends /templates/modal/modal_base
block modal-header-content
h1#choose-inventory-header.choose-inventory-active(data-i18n="inventory.choose_inventory") Equip Items
block modal-body-content
#equipped
.item-slot-row
for slot in ['left-ring', 'neck', 'eyes', 'head', 'wrists', 'right-ring']
.item-slot(data-slot=slot)
.placeholder
.item-container
if equipment[slot]
.replace-me(data-item-id=equipment[slot].get('original'))
.item-slot-column.pull-left
// TODO: add in 'misc-0' again somehow? Used to be where 'flag' is now.
for slot in ['minion', 'torso', 'gloves', 'left-hand', 'flag']
.item-slot(data-slot=slot)
.placeholder
.item-container
if equipment[slot]
.replace-me(data-item-id=equipment[slot].get('original'))
.hero-container
canvas.equipped-hero-canvas
.hero-feature-image
img
#selected-items
#selected-equipped-item.well
h3(data-i18n="inventory.equipped_item") Equipped
.item-view-stub
#selected-available-item.well
h3(data-i18n="inventory.available_item") Available
.item-view-stub
.item-slot-column.pull-right
for slot in ['pet', 'waist', 'feet', 'right-hand', 'programming-book']
.item-slot(data-slot=slot)
.placeholder
.item-container
if equipment[slot]
.replace-me(data-item-id=equipment[slot].get('original'))
// TODO: work in misc 1 again
//hr.slot-row-separator
//
//.item-slot-row.row-4
// for slot in ['misc-1']
// .item-slot(data-slot=slot)
// .placeholder
// .item-container
// if equipment[slot]
// .replace-me(data-item-id=equipment[slot].get('original'))
#available-equipment
h4#unlocked-description
ul.list-group
for item in unlockedItems
li.list-group-item(class=item.classes, data-item-id=item.get('original'))
h4#locked-description
ul.list-group
for item in lockedItems
li.list-group-item(class=item.classes, data-item-id=item.get('original'), style="display: none")
block modal-footer-content
button#choose-hero-button.btn.btn-lg.btn-primary.choose-inventory-active.pull-left(data-i18n="play.change_hero") Change Hero
button#play-level-button.btn.btn-lg.btn-success.choose-inventory-active(data-i18n="common.play") Play

View file

@ -1,59 +0,0 @@
#equipped
.item-slot-row
for slot in ['left-ring', 'neck', 'eyes', 'head', 'wrists', 'right-ring']
.item-slot(data-slot=slot)
.placeholder
.item-container
if equipment[slot]
.replace-me(data-item-id=equipment[slot].get('original'))
.item-slot-column.pull-left
// TODO: add in 'misc-0' again somehow? Used to be where 'flag' is now.
for slot in ['minion', 'torso', 'gloves', 'left-hand', 'flag']
.item-slot(data-slot=slot)
.placeholder
.item-container
if equipment[slot]
.replace-me(data-item-id=equipment[slot].get('original'))
.hero-container
canvas.equipped-hero-canvas
.hero-feature-image
img
#selected-items
#selected-equipped-item.well
h3(data-i18n="inventory.equipped_item") Equipped
.item-view-stub
#selected-available-item.well
h3(data-i18n="inventory.available_item") Available
.item-view-stub
.item-slot-column.pull-right
for slot in ['pet', 'waist', 'feet', 'right-hand', 'programming-book']
.item-slot(data-slot=slot)
.placeholder
.item-container
if equipment[slot]
.replace-me(data-item-id=equipment[slot].get('original'))
// TODO: work in misc 1 again
//hr.slot-row-separator
//
//.item-slot-row.row-4
// for slot in ['misc-1']
// .item-slot(data-slot=slot)
// .placeholder
// .item-container
// if equipment[slot]
// .replace-me(data-item-id=equipment[slot].get('original'))
#available-equipment
h4#unlocked-description
ul.list-group
for item in unlockedItems
li.list-group-item(class=item.classes, data-item-id=item.get('original'))
h4#locked-description
ul.list-group
for item in lockedItems
li.list-group-item(class=item.classes, data-item-id=item.get('original'), style="display: none")

View file

@ -7,7 +7,7 @@ block modal-header-content
block modal-body-content block modal-body-content
#choose-hero-view #choose-hero-view
#inventory-view #inventory-modal
block modal-footer-content block modal-footer-content
button#choose-inventory-button.btn.btn-lg.btn-success.choose-hero-active.secret(data-i18n="play.next") Next button#choose-inventory-button.btn.btn-lg.btn-success.choose-hero-active.secret(data-i18n="play.next") Next

View file

@ -1,8 +1,6 @@
ModalView = require 'views/kinds/ModalView' ModalView = require 'views/kinds/ModalView'
template = require 'templates/game-menu/game-menu-modal' template = require 'templates/game-menu/game-menu-modal'
submenuViews = [ submenuViews = [
require 'views/game-menu/InventoryView'
require 'views/game-menu/ChooseHeroView'
require 'views/game-menu/SaveLoadView' require 'views/game-menu/SaveLoadView'
require 'views/game-menu/OptionsView' require 'views/game-menu/OptionsView'
require 'views/game-menu/GuideView' require 'views/game-menu/GuideView'
@ -21,7 +19,6 @@ module.exports = class GameMenuModal extends ModalView
constructor: (options) -> constructor: (options) ->
super options super options
@options.showDevBits = me.isAdmin() or /https?:\/\/localhost/.test(window.location.href) @options.showDevBits = me.isAdmin() or /https?:\/\/localhost/.test(window.location.href)
@options.showInventory = @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
@options.showTab = options.showTab @options.showTab = options.showTab
@options.levelID = @options.level.get('slug') @options.levelID = @options.level.get('slug')
@options.startingSessionHeroConfig = $.extend {}, true, (@options.session.get('heroConfig') ? {}) @options.startingSessionHeroConfig = $.extend {}, true, (@options.session.get('heroConfig') ? {})
@ -30,7 +27,6 @@ module.exports = class GameMenuModal extends ModalView
getRenderData: (context={}) -> getRenderData: (context={}) ->
context = super(context) context = super(context)
context.showDevBits = @options.showDevBits context.showDevBits = @options.showDevBits
context.showInventory = @options.showInventory
context.showTab = @options.showTab context.showTab = @options.showTab
docs = @options.level.get('documentation') ? {} docs = @options.level.get('documentation') ? {}
context.showsGuide = docs.specificArticles?.length or docs.generalArticles?.length context.showsGuide = docs.specificArticles?.length or docs.generalArticles?.length
@ -43,56 +39,17 @@ module.exports = class GameMenuModal extends ModalView
firstView = switch @options.showTab firstView = switch @options.showTab
when 'multiplayer' then @subviews.multiplayer_view when 'multiplayer' then @subviews.multiplayer_view
unless firstView? unless firstView?
firstView = (if @options.showInventory then @subviews.inventory_view else @subviews.choose_hero_view) firstView = (@subviews.options_view)
firstView.$el.addClass 'active' firstView.$el.addClass 'active'
firstView.onShown?() firstView.onShown?()
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1 Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
onTabShown: (e) -> onTabShown: (e) ->
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-tab-switch', volume: 1 Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-tab-switch', volume: 1
@subviews.inventory_view.selectedHero = @subviews.choose_hero_view.selectedHero
@subviews[e.target.hash.substring(1).replace(/-/g, '_')].onShown?() @subviews[e.target.hash.substring(1).replace(/-/g, '_')].onShown?()
onHidden: -> onHidden: ->
super() super()
subview.onHidden?() for subviewKey, subview of @subviews subview.onHidden?() for subviewKey, subview of @subviews
patchingMe = @updateConfig()
me.patch() unless patchingMe # Might need to patch for options menu, too
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1 Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
Backbone.Mediator.publish 'music-player:exit-menu', {} Backbone.Mediator.publish 'music-player:exit-menu', {}
updateConfig: ->
sessionHeroConfig = @options.startingSessionHeroConfig
lastHeroConfig = me.get('heroConfig') ? {}
thangType = @subviews.choose_hero_view.selectedHero?.get 'original'
inventory = @subviews.inventory_view.getCurrentEquipmentConfig()
patchSession = patchMe = false
props = {}
if thangType or not sessionHeroConfig.thangType
props.thangType = thangType ? '529ffbf1cf1818f2be000001' # Default to Tharin if it somehow doesn't get set.
if _.size(inventory) or not sessionHeroConfig.inventory
props.inventory = inventory
for key, val of props when val
patchSession ||= not _.isEqual val, sessionHeroConfig[key]
patchMe ||= not _.isEqual val, lastHeroConfig[key]
sessionHeroConfig[key] = val
lastHeroConfig[key] = val
if (codeLanguage = @subviews.choose_hero_view.codeLanguage) and @subviews.choose_hero_view.codeLanguageChanged
patchSession ||= codeLanguage isnt @options.session.get('codeLanguage')
patchMe ||= codeLanguage isnt me.get('aceConfig')?.language
@options.session.set 'codeLanguage', codeLanguage
aceConfig = me.get('aceConfig', true) ? {}
aceConfig.language = codeLanguage
me.set 'aceConfig', aceConfig
console.log 'update config from game menu modal; props:', props, 'patch session?', patchSession, 'patch me?', patchMe
if patchSession
@options.session.set 'heroConfig', sessionHeroConfig
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()
patchMe

View file

@ -1,14 +1,16 @@
CocoView = require 'views/kinds/CocoView' ModalView = require 'views/kinds/ModalView'
template = require 'templates/game-menu/inventory-view' template = require 'templates/game-menu/inventory-modal'
{me} = require 'lib/auth' {me} = require 'lib/auth'
ThangType = require 'models/ThangType' ThangType = require 'models/ThangType'
CocoCollection = require 'collections/CocoCollection' CocoCollection = require 'collections/CocoCollection'
ItemView = require './ItemView' ItemView = require './ItemView'
SpriteBuilder = require 'lib/sprites/SpriteBuilder' SpriteBuilder = require 'lib/sprites/SpriteBuilder'
module.exports = class InventoryView extends CocoView hasGoneFullScreenOnce = false
id: 'inventory-view'
className: 'tab-pane' module.exports = class InventoryModal extends ModalView
id: 'inventory-modal'
className: 'modal fade play-modal'
template: template template: template
slots: ['head', 'eyes', 'neck', 'torso', 'wrists', 'gloves', 'left-ring', 'right-ring', 'right-hand', 'left-hand', 'waist', 'feet', 'programming-book', 'pet', 'minion', 'flag'] #, 'misc-0', 'misc-1'] # TODO: bring in misc slot(s) again when we have space slots: ['head', 'eyes', 'neck', 'torso', 'wrists', 'gloves', 'left-ring', 'right-ring', 'right-hand', 'left-hand', 'waist', 'feet', 'programming-book', 'pet', 'minion', 'flag'] #, 'misc-0', 'misc-1'] # TODO: bring in misc slot(s) again when we have space
@ -19,12 +21,13 @@ module.exports = class InventoryView extends CocoView
'doubletap #available-equipment .list-group-item:not(.equipped)': 'onAvailableItemDoubleClick' 'doubletap #available-equipment .list-group-item:not(.equipped)': 'onAvailableItemDoubleClick'
'dblclick .item-slot .item-view': 'onEquippedItemDoubleClick' 'dblclick .item-slot .item-view': 'onEquippedItemDoubleClick'
'doubletap .item-slot .item-view': 'onEquippedItemDoubleClick' 'doubletap .item-slot .item-view': 'onEquippedItemDoubleClick'
'shown.bs.modal': 'onShown'
subscriptions: 'click #choose-hero-button': 'onClickChooseHero'
'level:hero-selection-updated': 'onHeroSelectionUpdated' 'click #play-level-button': 'onClickPlayLevel'
shortcuts: shortcuts:
'esc': 'clearSelection' 'esc': 'clearSelection'
'enter': 'onClickPlayLevel'
initialize: (options) -> initialize: (options) ->
super(arguments...) super(arguments...)
@ -378,8 +381,7 @@ module.exports = class InventoryView extends CocoView
for item in me.items() when not (item in @allowedItems) for item in me.items() when not (item in @allowedItems)
@allowedItems.push item @allowedItems.push item
onHeroSelectionUpdated: (e) -> setHero: (@selectedHero) ->
@selectedHero = e.hero
@loadHero() @loadHero()
@$el.removeClass('Warrior Ranger Wizard').addClass(@selectedHero.get('heroClass')) @$el.removeClass('Warrior Ranger Wizard').addClass(@selectedHero.get('heroClass'))
@ -433,6 +435,40 @@ module.exports = class InventoryView extends CocoView
# Called when the modal itself is dismissed # Called when the modal itself is dismissed
@endHighlight() @endHighlight()
onClickChooseHero: ->
@hide()
@trigger 'choose-hero-click'
onClickPlayLevel: (e) ->
return if @$el.find('#play-level-button').prop 'disabled'
@showLoading()
ua = navigator.userAgent.toLowerCase()
unless hasGoneFullScreenOnce or (/safari/.test(ua) and not /chrome/.test(ua)) or $(window).height() >= 658 # Min vertical resolution needed at 1366px wide
@toggleFullscreen()
hasGoneFullScreenOnce = true
@updateConfig =>
@trigger 'play-click'
window.tracker?.trackEvent 'Play Level Modal', Action: 'Play'
updateConfig: (callback, skipSessionSave) ->
sessionHeroConfig = @options.session.get('heroConfig') ? {}
lastHeroConfig = me.get('heroConfig') ? {}
inventory = @getCurrentEquipmentConfig()
patchSession = patchMe = false
patchSession ||= not _.isEqual inventory, sessionHeroConfig.inventory
patchMe ||= not _.isEqual inventory, lastHeroConfig.inventory
sessionHeroConfig.inventory = inventory
lastHeroConfig.inventory = inventory
if patchMe
console.log 'setting me.heroConfig to', JSON.stringify(lastHeroConfig)
me.set 'heroConfig', lastHeroConfig
me.patch()
if patchSession
console.log 'setting session.heroConfig to', JSON.stringify(sessionHeroConfig)
@options.session.set 'heroConfig', sessionHeroConfig
@options.session.patch success: callback unless skipSessionSave
else
callback?()
gear = gear =
'simple-boots': '53e237bf53457600003e3f05' 'simple-boots': '53e237bf53457600003e3f05'

View file

@ -3,7 +3,7 @@ template = require 'templates/play/world-map-view'
LevelSession = require 'models/LevelSession' LevelSession = require 'models/LevelSession'
CocoCollection = require 'collections/CocoCollection' CocoCollection = require 'collections/CocoCollection'
AudioPlayer = require 'lib/AudioPlayer' AudioPlayer = require 'lib/AudioPlayer'
PlayLevelModal = require 'views/play/modal/PlayLevelModal' LevelSetupManager = require 'lib/LevelSetupManager'
ThangType = require 'models/ThangType' ThangType = require 'models/ThangType'
MusicPlayer = require 'lib/surface/MusicPlayer' MusicPlayer = require 'lib/surface/MusicPlayer'
storage = require 'lib/storage' storage = require 'lib/storage'
@ -149,8 +149,8 @@ module.exports = class WorldMapView extends RootView
@startLevel $(e.target).parents('.level-info-container') @startLevel $(e.target).parents('.level-info-container')
startLevel: (levelElement) -> startLevel: (levelElement) ->
playLevelModal = new PlayLevelModal supermodel: @supermodel, levelID: levelElement.data('level-id'), levelPath: levelElement.data('level-path'), levelName: levelElement.data('level-name'), hadEverChosenHero: @hadEverChosenHero setupManager = new LevelSetupManager supermodel: @supermodel, levelID: levelElement.data('level-id'), levelPath: levelElement.data('level-path'), levelName: levelElement.data('level-name'), hadEverChosenHero: @hadEverChosenHero, parent: @
@openModalView playLevelModal setupManager.open()
@$levelInfo?.hide() @$levelInfo?.hide()
onMouseEnterLevel: (e) -> onMouseEnterLevel: (e) ->

View file

@ -36,6 +36,7 @@ HeroVictoryModal = require './modal/HeroVictoryModal'
InfiniteLoopModal = require './modal/InfiniteLoopModal' InfiniteLoopModal = require './modal/InfiniteLoopModal'
GameMenuModal = require 'views/game-menu/GameMenuModal' GameMenuModal = require 'views/game-menu/GameMenuModal'
MultiplayerStatusView = require './MultiplayerStatusView' MultiplayerStatusView = require './MultiplayerStatusView'
LevelSetupManager = require 'lib/LevelSetupManager'
PROFILE_ME = false PROFILE_ME = false
@ -276,7 +277,9 @@ module.exports = class PlayLevelView extends RootView
onSessionLoaded: (e) -> onSessionLoaded: (e) ->
# Just the level and session have been loaded by the level loader # Just the level and session have been loaded by the level loader
if e.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] and not _.size e.session.get('heroConfig')?.inventory ? {} if e.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] and not _.size e.session.get('heroConfig')?.inventory ? {}
@openModalView new GameMenuModal level: e.level, session: e.session, supermodel: @supermodel setupManager = new LevelSetupManager({supermodel: @supermodel, levelID: @levelID, parent: @})
setupManager.open()
@onRealTimeMultiplayerLevelLoaded e.session if e.level.get('type') in ['ladder', 'hero-ladder'] @onRealTimeMultiplayerLevelLoaded e.session if e.level.get('type') in ['ladder', 'hero-ladder']
onLoaded: -> onLoaded: ->

View file

@ -20,6 +20,7 @@ module.exports = class PlayHeroesModal extends ModalView
shortcuts: shortcuts:
'left': -> @$el.find('#hero-carousel').carousel('prev') if @heroes.models.length and not @$el.hasClass 'secret' 'left': -> @$el.find('#hero-carousel').carousel('prev') if @heroes.models.length and not @$el.hasClass 'secret'
'right': -> @$el.find('#hero-carousel').carousel('next') if @heroes.models.length and not @$el.hasClass 'secret' 'right': -> @$el.find('#hero-carousel').carousel('next') if @heroes.models.length and not @$el.hasClass 'secret'
'enter': 'saveAndHide'
constructor: (options) -> constructor: (options) ->
super options super options
@ -87,8 +88,8 @@ module.exports = class PlayHeroesModal extends ModalView
@preloadHero heroIndex + 1 @preloadHero heroIndex + 1
@preloadHero heroIndex - 1 @preloadHero heroIndex - 1
@selectedHero = hero unless hero.locked @selectedHero = hero unless hero.locked
Backbone.Mediator.publish 'level:hero-selection-updated', hero: @selectedHero
$('#choose-inventory-button').prop 'disabled', hero.locked $('#choose-inventory-button').prop 'disabled', hero.locked
@trigger 'hero-loaded', {hero: hero}
getFullHero: (original) -> getFullHero: (original) ->
url = "/db/thang.type/#{original}/version" url = "/db/thang.type/#{original}/version"
@ -178,7 +179,7 @@ module.exports = class PlayHeroesModal extends ModalView
@session.patch() if changed @session.patch() if changed
changed = @updateHeroConfig(me, hero) changed = @updateHeroConfig(me, hero)
aceConfig = _.clone(me.get('aceConfig')) aceConfig = _.clone(me.get('aceConfig')) or {}
if @codeLanguage isnt aceConfig.language if @codeLanguage isnt aceConfig.language
aceConfig.language = @codeLanguage aceConfig.language = @codeLanguage
me.set 'aceConfig', aceConfig me.set 'aceConfig', aceConfig
@ -187,6 +188,7 @@ module.exports = class PlayHeroesModal extends ModalView
me.patch() if changed me.patch() if changed
@hide() @hide()
@trigger 'confirm-click', hero: @selectedHero
updateHeroConfig: (model, hero) -> updateHeroConfig: (model, hero) ->
heroConfig = _.clone(model.get('heroConfig')) or {} heroConfig = _.clone(model.get('heroConfig')) or {}

View file

@ -1,128 +0,0 @@
ModalView = require 'views/kinds/ModalView'
template = require 'templates/play/modal/play-level-modal'
ChooseHeroView = require 'views/game-menu/ChooseHeroView'
InventoryView = require 'views/game-menu/InventoryView'
PlayLevelView = require 'views/play/level/PlayLevelView'
LadderView = require 'views/play/ladder/LadderView'
LevelSession = require 'models/LevelSession'
hasGoneFullScreenOnce = false
module.exports = class PlayLevelModal extends ModalView
className: 'modal fade play-modal'
template: template
id: 'play-level-modal'
events:
'click #choose-inventory-button': 'onClickChooseInventory'
'click #choose-hero-button': 'onClickChooseHero'
'click #play-level-button': 'onClickPlayLevel'
shortcuts:
'enter': 'onEnterPressed'
constructor: (options) ->
super options
@options.showDevBits = true
@loadSession()
loadSession: ->
url = "/db/level/#{@options.levelID}/session"
#url += "?team=#{@team}" if @options.team # TODO: figure out how to get the teams for multiplayer PVP hero style
session = new LevelSession().setURL url
@session = @supermodel.loadModel(session, 'level_session').model
@options.session = @session
getRenderData: (context={}) ->
context = super(context)
context.levelID = @options.levelID
context.levelPath = @options.levelPath
context.levelName = @options.levelName
context
afterRender: ->
super()
return unless @supermodel.finished()
@session.url = -> '/db/level.session/' + @id
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
@insertSubView @chooseHeroView = new ChooseHeroView @options
@insertSubView @inventoryView = new InventoryView @options
if @options.hadEverChosenHero
@$el.find('.choose-hero-active').add(@chooseHeroView.$el).addClass 'secret'
@$el.find('.choose-inventory-active').removeClass 'secret'
@inventoryView.onShown()
else
@$el.find('.choose-inventory-active').add(@inventoryView.$el).addClass 'secret'
@$el.find('.choose-hero-active').removeClass 'secret'
@chooseHeroView.onShown()
onHidden: ->
unless @navigatingToPlay
skipSessionSave = not @options.session.get('levelName')? # Has to have been already started.
@updateConfig null, skipSessionSave
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
super()
updateConfig: (callback, skipSessionSave) ->
sessionHeroConfig = @options.session.get('heroConfig') ? {}
lastHeroConfig = me.get('heroConfig') ? {}
thangType = @subviews.choose_hero_view.selectedHero?.get('original') ? sessionHeroConfig.thangType ? lastHeroConfig.thangType
inventory = @subviews.inventory_view.getCurrentEquipmentConfig()
patchSession = patchMe = false
props = thangType: thangType, inventory: inventory
for key, val of props when val
patchSession ||= not _.isEqual val, sessionHeroConfig[key]
patchMe ||= not _.isEqual val, lastHeroConfig[key]
sessionHeroConfig[key] = val
lastHeroConfig[key] = val
if (codeLanguage = @subviews.choose_hero_view.codeLanguage) and (@subviews.choose_hero_view.codeLanguageChanged or not me.get('aceConfig'))
patchSession ||= codeLanguage isnt @options.session.get('codeLanguage')
patchMe ||= codeLanguage isnt me.get('aceConfig')?.language
@options.session.set 'codeLanguage', codeLanguage
aceConfig = me.get('aceConfig', true) ? {}
aceConfig.language = codeLanguage
me.set 'aceConfig', aceConfig
if patchMe
console.log 'setting me.heroConfig to', lastHeroConfig
me.set 'heroConfig', lastHeroConfig
me.patch()
if patchSession
console.log 'setting session.heroConfig to', sessionHeroConfig
@options.session.set 'heroConfig', sessionHeroConfig
@options.session.patch success: callback unless skipSessionSave
else
callback?()
onClickChooseInventory: (e) ->
@chooseHeroView.$el.add('#choose-inventory-button, #choose-hero-header').addClass 'secret'
@inventoryView.$el.add('#choose-hero-button, #play-level-button, #choose-inventory-header').removeClass 'secret'
@inventoryView.selectedHero = @chooseHeroView.selectedHero
@inventoryView.onShown()
window.tracker?.trackEvent 'Play Level Modal', Action: 'Choose Inventory'
onClickChooseHero: (e) ->
@chooseHeroView.$el.add('#choose-inventory-button, #choose-hero-header').removeClass 'secret'
@inventoryView.$el.add('#choose-hero-button, #play-level-button, #choose-inventory-header').addClass 'secret'
@chooseHeroView.onShown()
@inventoryView.endHighlight()
window.tracker?.trackEvent 'Play Level Modal', Action: 'Choose Hero'
onClickPlayLevel: (e) ->
return if @$el.find('#play-level-button').prop 'disabled'
@showLoading()
ua = navigator.userAgent.toLowerCase()
unless hasGoneFullScreenOnce or (/safari/.test(ua) and not /chrome/.test(ua)) or $(window).height() >= 658 # Min vertical resolution needed at 1366px wide
@toggleFullscreen()
hasGoneFullScreenOnce = true
@updateConfig =>
@navigatingToPlay = true
viewClass = if @options.levelPath is 'ladder' then LadderView else PlayLevelView
Backbone.Mediator.publish 'router:navigate', {
route: "/play/#{@options.levelPath || 'level'}/#{@options.levelID}"
viewClass: viewClass
viewArgs: [{supermodel: @supermodel}, @options.levelID]
}
window.tracker?.trackEvent 'Play Level Modal', Action: 'Play'
onEnterPressed: (e) ->
(if @chooseHeroView.$el.hasClass('secret') then @onClickPlayLevel else @onClickChooseInventory).apply @