mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 01:55:38 -05:00
68cca74b43
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.
127 lines
4.7 KiB
CoffeeScript
127 lines
4.7 KiB
CoffeeScript
CocoView = require 'views/kinds/CocoView'
|
|
template = require 'templates/play/level/tome/cast_button'
|
|
{me} = require 'lib/auth'
|
|
|
|
module.exports = class CastButtonView extends CocoView
|
|
id: 'cast-button-view'
|
|
template: template
|
|
|
|
events:
|
|
'click .cast-button': 'onCastButtonClick'
|
|
'click .cast-real-time-button': 'onCastRealTimeButtonClick'
|
|
|
|
subscriptions:
|
|
'tome:spell-changed': 'onSpellChanged'
|
|
'tome:cast-spells': 'onCastSpells'
|
|
'god:world-load-progress-changed': 'onWorldLoadProgressChanged'
|
|
'god:new-world-created': 'onNewWorld'
|
|
'realtime-multiplayer:joined-game': 'onJoinedRealTimeMultiplayerGame'
|
|
'realtime-multiplayer:left-game': 'onLeftRealTimeMultiplayerGame'
|
|
|
|
constructor: (options) ->
|
|
super options
|
|
@spells = options.spells
|
|
@levelID = options.levelID
|
|
@castShortcut = '⇧↵'
|
|
|
|
getRenderData: (context={}) ->
|
|
context = super context
|
|
shift = $.i18n.t 'keyboard_shortcuts.shift'
|
|
enter = $.i18n.t 'keyboard_shortcuts.enter'
|
|
castShortcutVerbose = "#{shift}+#{enter}"
|
|
castRealTimeShortcutVerbose = (if @isMac() then 'Cmd' else 'Ctrl') + '+' + castShortcutVerbose
|
|
context.castVerbose = castShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.cast_spell')
|
|
context.castRealTimeVerbose = castRealTimeShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.run_real_time')
|
|
context
|
|
|
|
afterRender: ->
|
|
super()
|
|
@castButton = $('.cast-button', @$el)
|
|
@castButtonGroup = $('.cast-button-group', @$el)
|
|
@castOptions = $('.autocast-delays', @$el)
|
|
delay = me.get('autocastDelay')
|
|
delay ?= 90019001
|
|
@setAutocastDelay delay
|
|
|
|
attachTo: (spellView) ->
|
|
@$el.detach().prependTo(spellView.toolbarView.$el).show()
|
|
|
|
onCastButtonClick: (e) ->
|
|
Backbone.Mediator.publish 'tome:manual-cast', {}
|
|
|
|
onCastRealTimeButtonClick: (e) ->
|
|
if @multiplayerSession
|
|
Backbone.Mediator.publish 'realtime-multiplayer:manual-cast', {}
|
|
# Wait for multiplayer session to be up and running
|
|
@multiplayerSession.on 'change', (e) =>
|
|
if @multiplayerSession.get('state') is 'running'
|
|
# Real-time multiplayer session is ready to go, so resume normal cast
|
|
@multiplayerSession.off()
|
|
Backbone.Mediator.publish 'tome:manual-cast', {realTime: true}
|
|
else
|
|
Backbone.Mediator.publish 'tome:manual-cast', {realTime: true}
|
|
|
|
onCastOptionsClick: (e) =>
|
|
Backbone.Mediator.publish 'tome:focus-editor', {}
|
|
@castButtonGroup.removeClass 'open'
|
|
@setAutocastDelay $(e.target).attr 'data-delay'
|
|
false
|
|
|
|
onSpellChanged: (e) ->
|
|
@updateCastButton()
|
|
|
|
onCastSpells: (e) ->
|
|
return if e.preload
|
|
@casting = true
|
|
if @hasStartedCastingOnce # Don't play this sound the first time
|
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'cast', volume: 0.5
|
|
@hasStartedCastingOnce = true
|
|
@updateCastButton()
|
|
@onWorldLoadProgressChanged progress: 0
|
|
|
|
onWorldLoadProgressChanged: (e) ->
|
|
return # trying out showing progress on the canvas instead
|
|
overlay = @castButtonGroup.find '.button-progress-overlay'
|
|
overlay.css 'width', e.progress * @castButton.outerWidth() + 1
|
|
|
|
onNewWorld: (e) ->
|
|
@casting = false
|
|
if @hasCastOnce # Don't play this sound the first time
|
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'cast-end', volume: 0.5
|
|
@hasCastOnce = true
|
|
@updateCastButton()
|
|
|
|
updateCastButton: ->
|
|
return if _.some @spells, (spell) => not spell.loaded
|
|
|
|
async.some _.values(@spells), (spell, callback) =>
|
|
spell.hasChangedSignificantly spell.getSource(), null, callback
|
|
, (castable) =>
|
|
Backbone.Mediator.publish 'tome:spell-has-changed-significantly-calculation', hasChangedSignificantly: castable
|
|
@castButtonGroup.toggleClass('castable', castable).toggleClass('casting', @casting)
|
|
if @casting
|
|
s = $.i18n.t('play_level.tome_cast_button_casting', defaultValue: 'Casting')
|
|
else if castable
|
|
s = $.i18n.t('play_level.tome_cast_button_castable', defaultValue: 'Cast Spell') + ' ' + @castShortcut
|
|
else
|
|
s = $.i18n.t('play_level.tome_cast_button_cast', defaultValue: 'Spell Cast')
|
|
@castButton.text s
|
|
@castButton.prop 'disabled', not castable
|
|
|
|
setAutocastDelay: (delay) ->
|
|
#console.log 'Set autocast delay to', delay
|
|
return unless delay
|
|
@autocastDelay = delay = parseInt delay
|
|
me.set('autocastDelay', delay)
|
|
me.patch()
|
|
spell.view?.setAutocastDelay delay for spellKey, spell of @spells
|
|
@castOptions.find('a').each ->
|
|
$(@).toggleClass('selected', parseInt($(@).attr('data-delay')) is delay)
|
|
|
|
onJoinedRealTimeMultiplayerGame: (item) ->
|
|
@multiplayerSession = item
|
|
|
|
onLeftRealTimeMultiplayerGame: () ->
|
|
if @multiplayerSession
|
|
@multiplayerSession.off()
|
|
@multiplayerSession = null
|