codecombat/app/views/play/level/ControlBarView.coffee

173 lines
6.6 KiB
CoffeeScript
Raw Normal View History

2014-07-17 20:20:11 -04:00
CocoView = require 'views/kinds/CocoView'
2014-01-03 13:32:13 -05:00
template = require 'templates/play/level/control_bar'
{me} = require 'lib/auth'
2014-01-03 13:32:13 -05:00
GameMenuModal = require 'views/game-menu/GameMenuModal'
RealTimeModel = require 'models/RealTimeModel'
RealTimeCollection = require 'collections/RealTimeCollection'
LevelSetupManager = require 'lib/LevelSetupManager'
GameMenuModal = require 'views/game-menu/GameMenuModal'
2014-01-03 13:32:13 -05:00
2014-07-17 20:20:11 -04:00
module.exports = class ControlBarView extends CocoView
2014-06-30 22:16:26 -04:00
id: 'control-bar-view'
2014-01-03 13:32:13 -05:00
template: template
subscriptions:
'bus:player-states-changed': 'onPlayerStatesChanged'
'level:disable-controls': 'onDisableControls'
'level:enable-controls': 'onEnableControls'
'ipad:memory-warning': 'onIPadMemoryWarning'
2014-01-03 13:32:13 -05:00
events:
'click #next-game-button': -> Backbone.Mediator.publish 'level:next-game-pressed', {}
'click #game-menu-button': 'showGameMenuModal'
'click': -> Backbone.Mediator.publish 'tome:focus-editor', {}
'click .home a': 'onClickHome'
'click .multiplayer-area': 'onClickMultiplayer'
2014-01-03 13:32:13 -05:00
constructor: (options) ->
@worldName = options.worldName
@session = options.session
@level = options.level
@levelID = @level.get('slug')
2014-03-12 20:51:09 -04:00
@spectateGame = options.spectateGame ? false
2014-01-03 13:32:13 -05:00
super options
if @isMultiplayerLevel = @level.get('type') in ['hero-ladder']
@multiplayerStatusManager = new MultiplayerStatusManager @levelID, @onMultiplayerStateChanged
2014-01-03 13:32:13 -05:00
setBus: (@bus) ->
onPlayerStatesChanged: (e) ->
2014-02-12 15:41:41 -05:00
# TODO: this doesn't fire any more. Replacement?
2014-01-03 13:32:13 -05:00
return unless @bus is e.bus
numPlayers = _.keys(e.players).length
return if numPlayers is @numPlayers
@numPlayers = numPlayers
text = 'Multiplayer'
text += " (#{numPlayers})" if numPlayers > 1
$('#multiplayer-button', @$el).text(text)
onMultiplayerStateChanged: => @render?()
getRenderData: (c={}) ->
super c
c.worldName = @worldName
c.multiplayerEnabled = @session.get('multiplayer')
c.ladderGame = @level.get('type') in ['ladder', 'hero-ladder']
if c.isMultiplayerLevel = @isMultiplayerLevel
c.multiplayerStatus = @multiplayerStatusManager?.status
2014-03-12 20:51:09 -04:00
c.spectateGame = @spectateGame
@homeViewArgs = [{supermodel: if @hasReceivedMemoryWarning then null else @supermodel}]
if @level.get('type', true) in ['ladder', 'ladder-tutorial', 'hero-ladder']
levelID = @level.get('slug').replace /\-tutorial$/, ''
@homeLink = c.homeLink = '/play/ladder/' + levelID
@homeViewClass = require 'views/play/ladder/LadderView'
@homeViewArgs.push levelID
else if @level.get('type', true) in ['hero', 'hero-coop']
@homeLink = c.homeLink = '/play'
@homeViewClass = require 'views/play/WorldMapView'
campaign = @getCampaignForSlug @level.get 'slug'
if campaign isnt 'dungeon'
@homeLink += '/' + campaign
@homeViewArgs.push campaign
2014-05-05 18:33:08 -04:00
else
@homeLink = c.homeLink = '/'
@homeViewClass = require 'views/HomeView'
c.editorLink = "/editor/level/#{@level.get('slug')}"
c.homeLink = @homeLink
c
2014-01-03 13:32:13 -05:00
showGameMenuModal: ->
gameMenuModal = new GameMenuModal level: @level, session: @session, supermodel: @supermodel
@openModalView gameMenuModal
@listenToOnce gameMenuModal, 'change-hero', ->
@setupManager?.destroy()
@setupManager = new LevelSetupManager({supermodel: @supermodel, levelID: @levelID, parent: @, session: @session})
@setupManager.open()
onClickHome: (e) ->
e.preventDefault()
e.stopImmediatePropagation()
Backbone.Mediator.publish 'router:navigate', route: @homeLink, viewClass: @homeViewClass, viewArgs: @homeViewArgs
onClickMultiplayer: (e) ->
@openModalView new GameMenuModal showTab: 'multiplayer', level: @level, session: @session, supermodel: @supermodel
onDisableControls: (e) -> @toggleControls e, false
onEnableControls: (e) -> @toggleControls e, true
toggleControls: (e, enabled) ->
return if e.controls and not ('level' in e.controls)
return if enabled is @controlsEnabled
@controlsEnabled = enabled
@$el.toggleClass 'controls-disabled', not enabled
getCampaignForSlug: (slug) ->
for campaign in require('views/play/WorldMapView').campaigns
for level in campaign.levels
return campaign.id if level.id is slug
onIPadMemoryWarning: (e) ->
@hasReceivedMemoryWarning = true
destroy: ->
@setupManager?.destroy()
@multiplayerStatusManager?.destroy()
super()
# MultiplayerStatusManager ######################################################
#
# Manages the multiplayer status, and calls @statusChangedCallback when it changes.
#
# It monitors these:
# Real-time multiplayer players
# Internal multiplayer status
#
# Real-time state variables:
# @playersCollection - Real-time multiplayer players
#
# TODO: Not currently using player counts. Should remove if we keep simple design.
#
class MultiplayerStatusManager
constructor: (@levelID, @statusChangedCallback) ->
@status = ''
# @players = {}
# @playersCollection = new RealTimeCollection('multiplayer_players/' + @levelID)
# @playersCollection.on 'add', @onPlayerAdded
# @playersCollection.each (player) => @onPlayerAdded player
Backbone.Mediator.subscribe 'real-time-multiplayer:player-status', @onMultiplayerPlayerStatus
destroy: ->
Backbone.Mediator.unsubscribe 'real-time-multiplayer:player-status', @onMultiplayerPlayerStatus
# @playersCollection?.off 'add', @onPlayerAdded
# player.off 'change', @onPlayerChanged for id, player of @players
onMultiplayerPlayerStatus: (e) =>
@status = e.status
@statusChangedCallback()
# onPlayerAdded: (player) =>
# unless player.id is me.id
# @players[player.id] = new RealTimeModel('multiplayer_players/' + @levelID + '/' + player.id)
# @players[player.id].on 'change', @onPlayerChanged
# @countPlayers player
#
# onPlayerChanged: (player) =>
# @countPlayers player
#
# countPlayers: (changedPlayer) =>
# # TODO: save this stale hearbeat threshold setting somewhere
# staleHeartbeat = new Date()
# staleHeartbeat.setMinutes staleHeartbeat.getMinutes() - 3
# @playerCount = 0
# @playersCollectionAvailable = 0
# @playersCollectionUnavailable = 0
# @playersCollection.each (player) =>
# # Assume changedPlayer is fresher than entry in @playersCollection collection
# player = changedPlayer if changedPlayer? and player.id is changedPlayer.id
# unless staleHeartbeat >= new Date(player.get('heartbeat'))
# @playerCount++
# @playersCollectionAvailable++ if player.get('state') is 'available'
# @playersCollectionUnavailable++ if player.get('state') is 'unavailable'
# @statusChangedCallback()