mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-24 08:08:15 -05:00
Integrated the new PlayHeroesModal into the game, refactoring PlayLevelModal into LevelSetupManager.
This commit is contained in:
parent
790dd8e7e0
commit
424c3a6d3e
13 changed files with 221 additions and 259 deletions
79
app/lib/LevelSetupManager.coffee
Normal file
79
app/lib/LevelSetupManager.coffee
Normal 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]
|
||||
}
|
|
@ -23,7 +23,7 @@
|
|||
right: 35px
|
||||
bottom: 20px
|
||||
|
||||
#inventory-view #available-equipment
|
||||
#inventory-modal #available-equipment
|
||||
bottom: 60px
|
||||
|
||||
.modal-dialog
|
||||
|
|
|
@ -19,9 +19,15 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin
|
|||
@include box-shadow(0 0 10px #28f)
|
||||
z-index: 9001
|
||||
|
||||
#inventory-view
|
||||
position: relative
|
||||
height: $inventoryHeight
|
||||
#inventory-modal
|
||||
.modal-dialog
|
||||
margin: 30px auto 0 auto
|
||||
width: 720px
|
||||
|
||||
.modal-body
|
||||
height: 450px
|
||||
margin: 0
|
||||
|
||||
+user-select(none)
|
||||
|
||||
h3
|
||||
|
@ -34,7 +40,7 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin
|
|||
#equipped
|
||||
width: $equippedWidth
|
||||
position: absolute
|
||||
left: 0
|
||||
left: 20px
|
||||
top: 0
|
||||
bottom: 0
|
||||
//bottom: $selectedAreaHeight + 10
|
||||
|
@ -197,7 +203,7 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin
|
|||
#available-equipment
|
||||
width: $stashWidth
|
||||
position: absolute
|
||||
right: 0
|
||||
right: 20px
|
||||
top: 0
|
||||
bottom: 0
|
||||
overflow-y: scroll
|
|
@ -5,15 +5,13 @@ block modal-header
|
|||
block modal-body-content
|
||||
.button.close(type="button", data-dismiss="modal", aria-hidden="true") ×
|
||||
.tabbable.tabs-left
|
||||
- var submenus = ["inventory", "choose-hero", "save-load", "options", "guide", "multiplayer"]
|
||||
- var submenus = ["save-load", "options", "guide", "multiplayer"]
|
||||
- if (!showsGuide) {
|
||||
- submenus.splice(4, 1);
|
||||
- }
|
||||
- if (!showDevBits) { // Not done yet.
|
||||
- submenus.splice(2, 1);
|
||||
- }
|
||||
- if (!showInventory)
|
||||
- if (!showDevBits) { // Not done yet.
|
||||
- submenus.splice(0, 1);
|
||||
- }
|
||||
ul.nav.nav-tabs#game-menu-nav
|
||||
for submenu, index in submenus
|
||||
li(class=submenu === showTab || index === 0 && !showTab ? "active" : "")
|
||||
|
|
68
app/templates/game-menu/inventory-modal.jade
Normal file
68
app/templates/game-menu/inventory-modal.jade
Normal 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
|
|
@ -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")
|
||||
|
|
@ -7,7 +7,7 @@ block modal-header-content
|
|||
block modal-body-content
|
||||
#choose-hero-view
|
||||
|
||||
#inventory-view
|
||||
#inventory-modal
|
||||
|
||||
block modal-footer-content
|
||||
button#choose-inventory-button.btn.btn-lg.btn-success.choose-hero-active.secret(data-i18n="play.next") Next
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
ModalView = require 'views/kinds/ModalView'
|
||||
template = require 'templates/game-menu/game-menu-modal'
|
||||
submenuViews = [
|
||||
require 'views/game-menu/InventoryView'
|
||||
require 'views/game-menu/ChooseHeroView'
|
||||
require 'views/game-menu/SaveLoadView'
|
||||
require 'views/game-menu/OptionsView'
|
||||
require 'views/game-menu/GuideView'
|
||||
|
@ -21,7 +19,6 @@ module.exports = class GameMenuModal extends ModalView
|
|||
constructor: (options) ->
|
||||
super options
|
||||
@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.levelID = @options.level.get('slug')
|
||||
@options.startingSessionHeroConfig = $.extend {}, true, (@options.session.get('heroConfig') ? {})
|
||||
|
@ -30,7 +27,6 @@ module.exports = class GameMenuModal extends ModalView
|
|||
getRenderData: (context={}) ->
|
||||
context = super(context)
|
||||
context.showDevBits = @options.showDevBits
|
||||
context.showInventory = @options.showInventory
|
||||
context.showTab = @options.showTab
|
||||
docs = @options.level.get('documentation') ? {}
|
||||
context.showsGuide = docs.specificArticles?.length or docs.generalArticles?.length
|
||||
|
@ -43,56 +39,17 @@ module.exports = class GameMenuModal extends ModalView
|
|||
firstView = switch @options.showTab
|
||||
when 'multiplayer' then @subviews.multiplayer_view
|
||||
unless firstView?
|
||||
firstView = (if @options.showInventory then @subviews.inventory_view else @subviews.choose_hero_view)
|
||||
firstView = (@subviews.options_view)
|
||||
firstView.$el.addClass 'active'
|
||||
firstView.onShown?()
|
||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
||||
|
||||
onTabShown: (e) ->
|
||||
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?()
|
||||
|
||||
onHidden: ->
|
||||
super()
|
||||
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 '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
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
CocoView = require 'views/kinds/CocoView'
|
||||
template = require 'templates/game-menu/inventory-view'
|
||||
ModalView = require 'views/kinds/ModalView'
|
||||
template = require 'templates/game-menu/inventory-modal'
|
||||
{me} = require 'lib/auth'
|
||||
ThangType = require 'models/ThangType'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
ItemView = require './ItemView'
|
||||
SpriteBuilder = require 'lib/sprites/SpriteBuilder'
|
||||
|
||||
module.exports = class InventoryView extends CocoView
|
||||
id: 'inventory-view'
|
||||
className: 'tab-pane'
|
||||
hasGoneFullScreenOnce = false
|
||||
|
||||
module.exports = class InventoryModal extends ModalView
|
||||
id: 'inventory-modal'
|
||||
className: 'modal fade play-modal'
|
||||
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
|
||||
|
||||
|
@ -19,12 +21,13 @@ module.exports = class InventoryView extends CocoView
|
|||
'doubletap #available-equipment .list-group-item:not(.equipped)': 'onAvailableItemDoubleClick'
|
||||
'dblclick .item-slot .item-view': 'onEquippedItemDoubleClick'
|
||||
'doubletap .item-slot .item-view': 'onEquippedItemDoubleClick'
|
||||
|
||||
subscriptions:
|
||||
'level:hero-selection-updated': 'onHeroSelectionUpdated'
|
||||
'shown.bs.modal': 'onShown'
|
||||
'click #choose-hero-button': 'onClickChooseHero'
|
||||
'click #play-level-button': 'onClickPlayLevel'
|
||||
|
||||
shortcuts:
|
||||
'esc': 'clearSelection'
|
||||
'enter': 'onClickPlayLevel'
|
||||
|
||||
initialize: (options) ->
|
||||
super(arguments...)
|
||||
|
@ -378,8 +381,7 @@ module.exports = class InventoryView extends CocoView
|
|||
for item in me.items() when not (item in @allowedItems)
|
||||
@allowedItems.push item
|
||||
|
||||
onHeroSelectionUpdated: (e) ->
|
||||
@selectedHero = e.hero
|
||||
setHero: (@selectedHero) ->
|
||||
@loadHero()
|
||||
@$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
|
||||
@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 =
|
||||
'simple-boots': '53e237bf53457600003e3f05'
|
|
@ -3,7 +3,7 @@ template = require 'templates/play/world-map-view'
|
|||
LevelSession = require 'models/LevelSession'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
AudioPlayer = require 'lib/AudioPlayer'
|
||||
PlayLevelModal = require 'views/play/modal/PlayLevelModal'
|
||||
LevelSetupManager = require 'lib/LevelSetupManager'
|
||||
ThangType = require 'models/ThangType'
|
||||
MusicPlayer = require 'lib/surface/MusicPlayer'
|
||||
storage = require 'lib/storage'
|
||||
|
@ -149,8 +149,8 @@ module.exports = class WorldMapView extends RootView
|
|||
@startLevel $(e.target).parents('.level-info-container')
|
||||
|
||||
startLevel: (levelElement) ->
|
||||
playLevelModal = new PlayLevelModal supermodel: @supermodel, levelID: levelElement.data('level-id'), levelPath: levelElement.data('level-path'), levelName: levelElement.data('level-name'), hadEverChosenHero: @hadEverChosenHero
|
||||
@openModalView playLevelModal
|
||||
setupManager = new LevelSetupManager supermodel: @supermodel, levelID: levelElement.data('level-id'), levelPath: levelElement.data('level-path'), levelName: levelElement.data('level-name'), hadEverChosenHero: @hadEverChosenHero, parent: @
|
||||
setupManager.open()
|
||||
@$levelInfo?.hide()
|
||||
|
||||
onMouseEnterLevel: (e) ->
|
||||
|
|
|
@ -36,6 +36,7 @@ HeroVictoryModal = require './modal/HeroVictoryModal'
|
|||
InfiniteLoopModal = require './modal/InfiniteLoopModal'
|
||||
GameMenuModal = require 'views/game-menu/GameMenuModal'
|
||||
MultiplayerStatusView = require './MultiplayerStatusView'
|
||||
LevelSetupManager = require 'lib/LevelSetupManager'
|
||||
|
||||
PROFILE_ME = false
|
||||
|
||||
|
@ -276,7 +277,9 @@ module.exports = class PlayLevelView extends RootView
|
|||
onSessionLoaded: (e) ->
|
||||
# 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 ? {}
|
||||
@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']
|
||||
|
||||
onLoaded: ->
|
||||
|
|
|
@ -20,6 +20,7 @@ module.exports = class PlayHeroesModal extends ModalView
|
|||
shortcuts:
|
||||
'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'
|
||||
'enter': 'saveAndHide'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
|
@ -87,8 +88,8 @@ module.exports = class PlayHeroesModal extends ModalView
|
|||
@preloadHero heroIndex + 1
|
||||
@preloadHero heroIndex - 1
|
||||
@selectedHero = hero unless hero.locked
|
||||
Backbone.Mediator.publish 'level:hero-selection-updated', hero: @selectedHero
|
||||
$('#choose-inventory-button').prop 'disabled', hero.locked
|
||||
@trigger 'hero-loaded', {hero: hero}
|
||||
|
||||
getFullHero: (original) ->
|
||||
url = "/db/thang.type/#{original}/version"
|
||||
|
@ -178,7 +179,7 @@ module.exports = class PlayHeroesModal extends ModalView
|
|||
@session.patch() if changed
|
||||
|
||||
changed = @updateHeroConfig(me, hero)
|
||||
aceConfig = _.clone(me.get('aceConfig'))
|
||||
aceConfig = _.clone(me.get('aceConfig')) or {}
|
||||
if @codeLanguage isnt aceConfig.language
|
||||
aceConfig.language = @codeLanguage
|
||||
me.set 'aceConfig', aceConfig
|
||||
|
@ -187,6 +188,7 @@ module.exports = class PlayHeroesModal extends ModalView
|
|||
me.patch() if changed
|
||||
|
||||
@hide()
|
||||
@trigger 'confirm-click', hero: @selectedHero
|
||||
|
||||
updateHeroConfig: (model, hero) ->
|
||||
heroConfig = _.clone(model.get('heroConfig')) or {}
|
||||
|
|
|
@ -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 @
|
Loading…
Reference in a new issue