mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 01:55:38 -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
|
right: 35px
|
||||||
bottom: 20px
|
bottom: 20px
|
||||||
|
|
||||||
#inventory-view #available-equipment
|
#inventory-modal #available-equipment
|
||||||
bottom: 60px
|
bottom: 60px
|
||||||
|
|
||||||
.modal-dialog
|
.modal-dialog
|
||||||
|
|
|
@ -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
|
|
@ -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" : "")
|
||||||
|
|
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
|
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
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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'
|
|
@ -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) ->
|
||||||
|
|
|
@ -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: ->
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
|
@ -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