2014-08-08 14:36:41 -04:00
|
|
|
CocoView = require 'views/kinds/CocoView'
|
|
|
|
template = require 'templates/game-menu/multiplayer-view'
|
|
|
|
{me} = require 'lib/auth'
|
|
|
|
ThangType = require 'models/ThangType'
|
2014-08-10 20:26:30 -04:00
|
|
|
LadderSubmissionView = require 'views/play/common/LadderSubmissionView'
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
RealTimeCollection = require 'collections/RealTimeCollection'
|
2014-08-08 14:36:41 -04:00
|
|
|
|
|
|
|
module.exports = class MultiplayerView extends CocoView
|
|
|
|
id: 'multiplayer-view'
|
|
|
|
className: 'tab-pane'
|
|
|
|
template: template
|
|
|
|
|
2014-08-10 20:26:30 -04:00
|
|
|
subscriptions:
|
|
|
|
'ladder:game-submitted': 'onGameSubmitted'
|
|
|
|
|
|
|
|
events:
|
|
|
|
'click textarea': 'onClickLink'
|
|
|
|
'change #multiplayer': 'updateLinkSection'
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
'click #create-game-button': 'onCreateGame'
|
|
|
|
'click #join-game-button': 'onJoinGame'
|
|
|
|
'click #leave-game-button': 'onLeaveGame'
|
2014-08-10 20:26:30 -04:00
|
|
|
|
|
|
|
constructor: (options) ->
|
|
|
|
super(options)
|
|
|
|
@level = options.level
|
|
|
|
@session = options.session
|
|
|
|
@listenTo @session, 'change:multiplayer', @updateLinkSection
|
2014-08-30 00:46:26 -04:00
|
|
|
@initMultiplayerSessions()
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
|
|
|
|
destroy: ->
|
|
|
|
@multiplayerSessions?.off()
|
|
|
|
@currentMultiplayerSession?.off()
|
2014-08-29 18:10:04 -04:00
|
|
|
collection.off() for id, collection of @playersCollections
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
super()
|
|
|
|
|
2014-08-10 20:26:30 -04:00
|
|
|
getRenderData: ->
|
|
|
|
c = super()
|
|
|
|
c.joinLink = "#{document.location.href.replace(/\?.*/, '').replace('#', '')}?session=#{@session.id}"
|
|
|
|
c.multiplayer = @session.get 'multiplayer'
|
|
|
|
c.team = @session.get 'team'
|
|
|
|
c.levelSlug = @level?.get 'slug'
|
|
|
|
# For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet.
|
2014-10-18 17:51:43 -04:00
|
|
|
if @level?.get('type') in ['ladder', 'hero-ladder']
|
2014-08-10 20:26:30 -04:00
|
|
|
c.ladderGame = true
|
|
|
|
c.readyToRank = @session?.readyToRank()
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
|
|
|
|
c.levelID = @session.get('levelID')
|
|
|
|
c.multiplayerSessions = @multiplayerSessions.models
|
|
|
|
c.currentMultiplayerSession = @currentMultiplayerSession if @currentMultiplayerSession
|
|
|
|
c.playersCollections = @playersCollections if @playersCollections
|
2014-08-10 20:26:30 -04:00
|
|
|
c
|
2014-08-08 14:36:41 -04:00
|
|
|
|
|
|
|
afterRender: ->
|
|
|
|
super()
|
2014-08-10 20:26:30 -04:00
|
|
|
@updateLinkSection()
|
|
|
|
@ladderSubmissionView = new LadderSubmissionView session: @session, level: @level
|
|
|
|
@insertSubView @ladderSubmissionView, @$el.find('.ladder-submission-view')
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
@$el.find('#created-multiplayer-session').toggle Boolean(@currentMultiplayerSession?)
|
2014-08-29 18:10:04 -04:00
|
|
|
@$el.find('#create-game-button').toggle Boolean(not (@currentMultiplayerSession?))
|
2014-08-10 20:26:30 -04:00
|
|
|
|
|
|
|
onClickLink: (e) ->
|
|
|
|
e.target.select()
|
|
|
|
|
|
|
|
onGameSubmitted: (e) ->
|
|
|
|
ladderURL = "/play/ladder/#{@level.get('slug')}#my-matches"
|
|
|
|
Backbone.Mediator.publish 'router:navigate', route: ladderURL
|
|
|
|
|
|
|
|
updateLinkSection: ->
|
|
|
|
multiplayer = @$el.find('#multiplayer').prop('checked')
|
|
|
|
la = @$el.find('#link-area')
|
2014-10-18 17:51:43 -04:00
|
|
|
la.toggle if @level?.get('type') in ['ladder', 'hero-ladder'] then false else Boolean(multiplayer)
|
2014-08-10 20:26:30 -04:00
|
|
|
true
|
|
|
|
|
|
|
|
onHidden: ->
|
|
|
|
multiplayer = Boolean(@$el.find('#multiplayer').prop('checked'))
|
|
|
|
@session.set('multiplayer', multiplayer)
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
|
|
|
|
# TODO: shouldn't have to open MultiplayerView to read existing multiplayerSession?
|
2014-08-30 00:46:26 -04:00
|
|
|
# TODO: if someone leaves your game, it should go back to 'creating' state
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
|
2014-08-30 00:46:26 -04:00
|
|
|
initMultiplayerSessions: ->
|
|
|
|
@playersCollections = {}
|
|
|
|
# TODO: only request sessions for this level, !team, etc.
|
|
|
|
# TODO: don't hard code this path all over the place
|
|
|
|
@multiplayerSessions = new RealTimeCollection('multiplayer_level_sessions/')
|
|
|
|
@multiplayerSessions.on 'add', @onMultiplayerSessionAdded
|
|
|
|
@multiplayerSessions.on 'remove', @onMultiplayerSessionRemoved
|
|
|
|
@multiplayerSessions.each (ms) => @initMultiplayerSession ms
|
|
|
|
|
|
|
|
initMultiplayerSession: (ms) ->
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
# TODO: double check these players events are needed on top of onMultiplayerSessionChanged
|
2014-08-30 00:46:26 -04:00
|
|
|
@playersCollections[ms.id] = new RealTimeCollection('multiplayer_level_sessions/' + ms.id + '/players')
|
|
|
|
@playersCollections[ms.id].on 'add', @onPlayerAdded
|
|
|
|
@playersCollections[ms.id].on 'remove', @onPlayerRemoved
|
|
|
|
if not @currentMultiplayerSession and ms.get('levelID') is @session.get('levelID')
|
|
|
|
@playersCollections[ms.id].each (player) =>
|
2014-08-29 18:10:04 -04:00
|
|
|
if player.id is me.id and player.get('team') is @session.get('team')
|
2014-08-30 00:46:26 -04:00
|
|
|
@currentMultiplayerSession = ms
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
@currentMultiplayerSession.on 'change', @onMultiplayerSessionChanged
|
2014-08-29 18:10:04 -04:00
|
|
|
Backbone.Mediator.publish 'real-time-multiplayer:joined-game', session: @currentMultiplayerSession
|
2014-09-21 02:06:28 -04:00
|
|
|
|
2014-08-30 00:46:26 -04:00
|
|
|
onMultiplayerSessionAdded: (e) =>
|
2014-09-21 02:06:28 -04:00
|
|
|
#console.log 'onMultiplayerSessionAdded', e
|
2014-08-30 00:46:26 -04:00
|
|
|
@initMultiplayerSession e
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
@render()
|
|
|
|
|
|
|
|
onMultiplayerSessionRemoved: (e) =>
|
|
|
|
@playersCollections[e.id].off()
|
|
|
|
delete @playersCollections[e.id]
|
|
|
|
@render()
|
|
|
|
|
|
|
|
onMultiplayerSessionChanged: (e) =>
|
|
|
|
@render()
|
|
|
|
|
|
|
|
onPlayerAdded: (e) =>
|
2014-08-29 18:10:04 -04:00
|
|
|
# TODO: listeners not being unhooked
|
|
|
|
@render?()
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
|
|
|
|
onPlayerRemoved: (e) =>
|
2014-08-29 18:10:04 -04:00
|
|
|
# TODO: listeners not being unhooked
|
|
|
|
@render?()
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
|
|
|
|
onCreateGame: ->
|
|
|
|
s = @multiplayerSessions.create {
|
|
|
|
creator: @session.get('creator')
|
|
|
|
creatorName: @session.get('creatorName')
|
|
|
|
levelID: @session.get('levelID')
|
2014-08-29 18:10:04 -04:00
|
|
|
created: (new Date()).toISOString()
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
state: 'creating'
|
|
|
|
}
|
|
|
|
@currentMultiplayerSession = @multiplayerSessions.get(s.id)
|
|
|
|
@currentMultiplayerSession.on 'change', @onMultiplayerSessionChanged
|
|
|
|
players = new RealTimeCollection('multiplayer_level_sessions/' + @currentMultiplayerSession.id + '/players')
|
|
|
|
players.create {id: me.id, name: @session.get('creatorName'), team: @session.get('team')}
|
2014-08-29 18:10:04 -04:00
|
|
|
Backbone.Mediator.publish 'real-time-multiplayer:joined-game', session: @currentMultiplayerSession
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
@render()
|
|
|
|
|
|
|
|
onJoinGame: (e) ->
|
|
|
|
return if @currentMultiplayerSession
|
|
|
|
item = @$el.find(e.target).data('item')
|
|
|
|
@currentMultiplayerSession = @multiplayerSessions.get(item.id)
|
|
|
|
@currentMultiplayerSession.on 'change', @onMultiplayerSessionChanged
|
|
|
|
if @playersCollections[item.id]
|
|
|
|
@playersCollections[item.id].create {id: me.id, name: @session.get('creatorName'), team: @session.get('team')}
|
|
|
|
else
|
|
|
|
console.error 'onJoinGame did not have a players collection', @currentMultiplayerSession
|
2014-08-29 18:10:04 -04:00
|
|
|
Backbone.Mediator.publish 'real-time-multiplayer:joined-game', session: @currentMultiplayerSession
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
if @playersCollections[item.id]?.length is 2
|
|
|
|
@currentMultiplayerSession.set 'state', 'coding'
|
|
|
|
# TODO: close multiplayer view?
|
|
|
|
@render()
|
|
|
|
|
|
|
|
onLeaveGame: (e) ->
|
|
|
|
# TODO: This doesn't update open games or current game
|
|
|
|
if @currentMultiplayerSession
|
|
|
|
players = @playersCollections[@currentMultiplayerSession.id]
|
|
|
|
for i in [0...players.length]
|
|
|
|
player = players.at(i)
|
|
|
|
if player.get('id') is me.id
|
|
|
|
players.remove(player)
|
|
|
|
# NOTE: remove(@something) doesn't stick locally, only remotely
|
|
|
|
cms = @currentMultiplayerSession
|
|
|
|
@currentMultiplayerSession.off()
|
|
|
|
@currentMultiplayerSession = null
|
|
|
|
if players.length is 0
|
|
|
|
@multiplayerSessions.remove(cms)
|
|
|
|
break
|
|
|
|
console.error "Tried to leave a game we hadn't joined!" if @currentMultiplayerSession
|
2014-08-29 18:10:04 -04:00
|
|
|
Backbone.Mediator.publish 'real-time-multiplayer:left-game', {}
|
Real-time multiplayer initial commit
Simple matchmaking, synchronous multiplayer PVP, flags!
Rough matchmaking is under the game menu multiplayer tab, for ladder
games only. After creating a 2-person game there, you can exit that
modal and real-time cast to play against each other.
If you’re the first person to cast, you’ll sit at the real-time level
playback view waiting until the other player casts. When they do, you
both should start the real-time playback (and start placing flags like
crazy people).
If in a multiplayer session, the real-time simulation runs the players’
code against each other. Your multiplayer opponent’s name should be up
near the level name.
Multiplayer sessions are stored completely in Firebase for now, and
removed if both players leave the game. There’s plenty of bugs,
synchronization issues, and minimal polish to add before we push it to
master.
2014-08-29 02:34:07 -04:00
|
|
|
else
|
|
|
|
console.error "Tried to leave a game with no currentMultiplayerSession"
|
|
|
|
@render()
|