mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-30 10:56:53 -05:00
Added new LevelDialogueView. Messed around with dimming a bit more.
This commit is contained in:
parent
4cb641689c
commit
1b94868197
15 changed files with 225 additions and 17 deletions
|
@ -638,8 +638,9 @@ module.exports = Lank = class Lank extends CocoClass
|
||||||
|
|
||||||
onDialogue: (e) ->
|
onDialogue: (e) ->
|
||||||
return unless @thang?.id is e.spriteID
|
return unless @thang?.id is e.spriteID
|
||||||
label = @addLabel 'dialogue', Label.STYLE_DIALOGUE
|
unless @thang?.id is 'Hero Placeholder' # Don't show these for heroes, because they aren't actually first-person, just LevelDialogueView narration
|
||||||
label.setText e.blurb or '...'
|
label = @addLabel 'dialogue', Label.STYLE_DIALOGUE
|
||||||
|
label.setText e.blurb or '...'
|
||||||
sound = e.sound ? AudioPlayer.soundForDialogue e.message, @thangType.get 'soundTriggers'
|
sound = e.sound ? AudioPlayer.soundForDialogue e.message, @thangType.get 'soundTriggers'
|
||||||
@dialogueSoundInstance?.stop()
|
@dialogueSoundInstance?.stop()
|
||||||
if @dialogueSoundInstance = @playSound sound, false
|
if @dialogueSoundInstance = @playSound sound, false
|
||||||
|
|
|
@ -235,7 +235,6 @@
|
||||||
tome_available_spells: "Available Spells"
|
tome_available_spells: "Available Spells"
|
||||||
tome_your_skills: "Your Skills"
|
tome_your_skills: "Your Skills"
|
||||||
tome_current_method: "Current Method"
|
tome_current_method: "Current Method"
|
||||||
hud_continue: "Continue (shift+space)"
|
|
||||||
hud_continue_short: "Continue"
|
hud_continue_short: "Continue"
|
||||||
code_saved: "Code Saved"
|
code_saved: "Code Saved"
|
||||||
skip_tutorial: "Skip (esc)"
|
skip_tutorial: "Skip (esc)"
|
||||||
|
|
|
@ -50,6 +50,8 @@ $level-resize-transition-time: 0.5s
|
||||||
#stop-real-time-playback-button
|
#stop-real-time-playback-button
|
||||||
display: block
|
display: block
|
||||||
z-index: 20
|
z-index: 20
|
||||||
|
#level-dialogue-view
|
||||||
|
display: none
|
||||||
|
|
||||||
.level-content
|
.level-content
|
||||||
margin: 0px auto
|
margin: 0px auto
|
||||||
|
|
|
@ -8,9 +8,11 @@
|
||||||
overflow: visible
|
overflow: visible
|
||||||
|
|
||||||
&.controls-disabled
|
&.controls-disabled
|
||||||
@include opacity(0.5)
|
|
||||||
pointer-events: none
|
pointer-events: none
|
||||||
|
|
||||||
|
.wood-background, .hinge, .avatar-wrapper-container, .center
|
||||||
|
@include filter(brightness(50%))
|
||||||
|
|
||||||
.wood-background
|
.wood-background
|
||||||
position: absolute
|
position: absolute
|
||||||
left: 0
|
left: 0
|
||||||
|
@ -19,7 +21,7 @@
|
||||||
background-size: auto 100%
|
background-size: auto 100%
|
||||||
width: 100%
|
width: 100%
|
||||||
height: 100px
|
height: 100px
|
||||||
z-index: 2
|
z-index: 4
|
||||||
|
|
||||||
.hinge
|
.hinge
|
||||||
position: absolute
|
position: absolute
|
||||||
|
@ -28,7 +30,7 @@
|
||||||
width: 27px
|
width: 27px
|
||||||
height: 44px
|
height: 44px
|
||||||
background-size: contain
|
background-size: contain
|
||||||
z-index: 2
|
z-index: 4
|
||||||
pointer-events: none
|
pointer-events: none
|
||||||
|
|
||||||
.hinge-0
|
.hinge-0
|
||||||
|
@ -50,7 +52,7 @@
|
||||||
left: 18%
|
left: 18%
|
||||||
left: -webkit-calc(50% - (560px - 100px) / 2 - 10px)
|
left: -webkit-calc(50% - (560px - 100px) / 2 - 10px)
|
||||||
left: calc(50% - (560px - 100px) / 2 - 10px)
|
left: calc(50% - (560px - 100px) / 2 - 10px)
|
||||||
z-index: 3
|
z-index: 5
|
||||||
|
|
||||||
.thang-canvas-wrapper
|
.thang-canvas-wrapper
|
||||||
width: 80px
|
width: 80px
|
||||||
|
@ -99,7 +101,7 @@
|
||||||
font-family: Open Sans Condensed
|
font-family: Open Sans Condensed
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
font-size: 16px
|
font-size: 16px
|
||||||
z-index: 2
|
z-index: 4
|
||||||
@include transition(0.5s ease)
|
@include transition(0.5s ease)
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
|
|
91
app/styles/play/level/level-dialogue-view.sass
Normal file
91
app/styles/play/level/level-dialogue-view.sass
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
@import "app/styles/mixins"
|
||||||
|
@import "app/styles/bootstrap/variables"
|
||||||
|
|
||||||
|
#level-dialogue-view
|
||||||
|
+keyframes(speakingPulse)
|
||||||
|
from
|
||||||
|
@include box-shadow(0px 0px 8px #333)
|
||||||
|
color: white
|
||||||
|
50%
|
||||||
|
@include box-shadow(0px 0px 35px skyblue)
|
||||||
|
color: skyblue
|
||||||
|
to
|
||||||
|
@include box-shadow(0px 0px 8px #333)
|
||||||
|
color: white
|
||||||
|
|
||||||
|
width: 417px
|
||||||
|
height: 296px
|
||||||
|
background: transparent url(/images/level/code_palette_wood_background.png)
|
||||||
|
background-size: 100% auto
|
||||||
|
position: absolute
|
||||||
|
bottom: -296px + 40px
|
||||||
|
//left: -webkit-calc(27.5% - 417px / 2)
|
||||||
|
left: -webkit-calc(55% - 417px)
|
||||||
|
// Bounce in
|
||||||
|
@include transition(1s cubic-bezier(.17,.89,.42,1.36))
|
||||||
|
z-index: 2
|
||||||
|
|
||||||
|
&.active
|
||||||
|
display: block
|
||||||
|
bottom: -20px
|
||||||
|
|
||||||
|
&.speaking
|
||||||
|
.dialogue-area
|
||||||
|
.bubble
|
||||||
|
@include animation(speakingPulse 1.5s infinite)
|
||||||
|
|
||||||
|
.dialogue-area
|
||||||
|
position: relative
|
||||||
|
height: 100%
|
||||||
|
width: 100%
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
.bubble
|
||||||
|
position: relative
|
||||||
|
margin: 20px
|
||||||
|
padding: 10px 10px 30px 10px
|
||||||
|
color: white
|
||||||
|
font-weight: bold
|
||||||
|
background: rgb(45, 35, 234)
|
||||||
|
border: black solid 1px
|
||||||
|
border-radius: 10px
|
||||||
|
font-size: 18px
|
||||||
|
line-height: 20px
|
||||||
|
|
||||||
|
strong
|
||||||
|
color: #09B057
|
||||||
|
|
||||||
|
.hud-hint
|
||||||
|
font-weight: normal
|
||||||
|
color: #ddd
|
||||||
|
font-size: 14px
|
||||||
|
line-height: 16px
|
||||||
|
vertical-align: middle
|
||||||
|
|
||||||
|
.enter
|
||||||
|
position: absolute
|
||||||
|
right: 10px
|
||||||
|
bottom: 10px
|
||||||
|
div.dot
|
||||||
|
background: #337
|
||||||
|
width: 8px
|
||||||
|
height: 8px
|
||||||
|
position: absolute
|
||||||
|
right: 8px
|
||||||
|
top: 9px
|
||||||
|
border-radius: 5px
|
||||||
|
|
||||||
|
button, .alert
|
||||||
|
padding: 2px 5px
|
||||||
|
|
||||||
|
.enter button.with-dot
|
||||||
|
padding-right: 20px
|
||||||
|
|
||||||
|
h3
|
||||||
|
margin: 0
|
||||||
|
font-size: 16px
|
||||||
|
line-height: 16px
|
||||||
|
color: #338
|
||||||
|
|
||||||
|
button
|
||||||
|
margin-left: 10px
|
|
@ -12,7 +12,11 @@
|
||||||
background-size: 100% 100%
|
background-size: 100% 100%
|
||||||
// Counteract 50px height of absolutely positioned control bar, but overlap by 10px of jagged transparent top.
|
// Counteract 50px height of absolutely positioned control bar, but overlap by 10px of jagged transparent top.
|
||||||
margin-top: 50px - 10px
|
margin-top: 50px - 10px
|
||||||
z-index: 2
|
z-index: 3
|
||||||
|
|
||||||
|
&.controls-disabled
|
||||||
|
pointer-events: none
|
||||||
|
@include filter(brightness(50%))
|
||||||
|
|
||||||
button
|
button
|
||||||
font-size: 26px
|
font-size: 26px
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
&.read-only
|
&.read-only
|
||||||
background: linear-gradient(to bottom, rgba(0,0,0,0.25) 0%,rgba(0,0,0,0.25) 100%), url(/images/level/code_editor_top_bar_wood_background.png)
|
background: linear-gradient(to bottom, rgba(0,0,0,0.25) 0%,rgba(0,0,0,0.25) 100%), url(/images/level/code_editor_top_bar_wood_background.png)
|
||||||
background-size: 100% 100%
|
background-size: 100% 100%
|
||||||
> *
|
> *:not(.spell-tool-buttons)
|
||||||
@include opacity(0.5)
|
@include opacity(0.5)
|
||||||
|
|
||||||
.thang-avatar-view
|
.thang-avatar-view
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
#thang-hud
|
#thang-hud
|
||||||
|
|
||||||
|
#level-dialogue-view
|
||||||
|
|
||||||
button.btn.btn-lg.btn-warning.banner.header-font#stop-real-time-playback-button(title="Stop real-time playback", data-i18n="play_level.skip") Skip
|
button.btn.btn-lg.btn-warning.banner.header-font#stop-real-time-playback-button(title="Stop real-time playback", data-i18n="play_level.skip") Skip
|
||||||
|
|
||||||
.footer
|
.footer
|
||||||
|
|
2
app/templates/play/level/level-dialogue-view.jade
Normal file
2
app/templates/play/level/level-dialogue-view.jade
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.dialogue-area
|
||||||
|
p.bubble.dialogue-bubble
|
|
@ -495,9 +495,9 @@ requiredGearByLevel =
|
||||||
'descending-further': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'}
|
'descending-further': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'}
|
||||||
'the-second-kithmaze': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'}
|
'the-second-kithmaze': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'}
|
||||||
'dread-door': {'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i'}
|
'dread-door': {'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i'}
|
||||||
'known-enemy': {'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i'}
|
'known-enemy': {'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i', torso: 'leather-tunic'}
|
||||||
'master-of-names': {feet: 'simple-boots', 'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
'master-of-names': {feet: 'simple-boots', 'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses', torso: 'leather-tunic'}
|
||||||
'lowly-kithmen': {feet: 'simple-boots', 'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
'lowly-kithmen': {feet: 'simple-boots', 'right-hand': 'simple-sword', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses', torso: 'leather-tunic'}
|
||||||
'closing-the-distance': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic', eyes: 'crude-glasses'}
|
'closing-the-distance': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic', eyes: 'crude-glasses'}
|
||||||
'tactical-strike': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic', eyes: 'crude-glasses'}
|
'tactical-strike': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic', eyes: 'crude-glasses'}
|
||||||
'the-final-kithmaze': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
'the-final-kithmaze': {feet: 'simple-boots', 'right-hand': 'simple-sword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
||||||
|
|
|
@ -9,7 +9,7 @@ module.exports = class DialogueAnimator
|
||||||
@childrenToAdd = _.map(d[0].childNodes, (e) -> return e)
|
@childrenToAdd = _.map(d[0].childNodes, (e) -> return e)
|
||||||
@t0 = new Date()
|
@t0 = new Date()
|
||||||
@charsAdded = 0
|
@charsAdded = 0
|
||||||
@charsPerSecond = 50
|
@charsPerSecond = 25
|
||||||
|
|
||||||
tick: ->
|
tick: ->
|
||||||
if not @charsToAdd and not @childAnimator
|
if not @charsToAdd and not @childAnimator
|
||||||
|
|
104
app/views/play/level/LevelDialogueView.coffee
Normal file
104
app/views/play/level/LevelDialogueView.coffee
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
CocoView = require 'views/kinds/CocoView'
|
||||||
|
template = require 'templates/play/level/level-dialogue-view'
|
||||||
|
DialogueAnimator = require './DialogueAnimator'
|
||||||
|
|
||||||
|
module.exports = class LevelDialogueView extends CocoView
|
||||||
|
id: 'level-dialogue-view'
|
||||||
|
template: template
|
||||||
|
|
||||||
|
subscriptions:
|
||||||
|
'sprite:speech-updated': 'onSpriteDialogue'
|
||||||
|
'level:sprite-clear-dialogue': 'onSpriteClearDialogue'
|
||||||
|
'level:shift-space-pressed': 'onShiftSpacePressed'
|
||||||
|
'level:escape-pressed': 'onEscapePressed'
|
||||||
|
'sprite:dialogue-sound-completed': 'onDialogueSoundCompleted'
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click': 'onClick'
|
||||||
|
|
||||||
|
onClick: (e) ->
|
||||||
|
Backbone.Mediator.publish 'tome:focus-editor', {}
|
||||||
|
|
||||||
|
onFrameChanged: (e) ->
|
||||||
|
@timeProgress = e.progress
|
||||||
|
@update()
|
||||||
|
|
||||||
|
onSpriteDialogue: (e) ->
|
||||||
|
return unless e.message
|
||||||
|
@$el.addClass 'active speaking'
|
||||||
|
@setMessage e.message, e.mood, e.responses
|
||||||
|
|
||||||
|
window.tracker?.trackEvent 'Heard Sprite', {message: e.message, label: e.message}, ['Google Analytics']
|
||||||
|
|
||||||
|
onDialogueSoundCompleted: ->
|
||||||
|
@$el.removeClass 'speaking'
|
||||||
|
|
||||||
|
onSpriteClearDialogue: ->
|
||||||
|
@$el.removeClass 'active speaking'
|
||||||
|
|
||||||
|
setMessage: (message, mood, responses) ->
|
||||||
|
message = marked message
|
||||||
|
# Fix old HTML icons like <i class='icon-play'></i> in the Markdown
|
||||||
|
message = message.replace /<i class='(.+?)'><\/i>/, "<i class='$1'></i>"
|
||||||
|
clearInterval(@messageInterval) if @messageInterval
|
||||||
|
@bubble = $('.dialogue-bubble', @$el)
|
||||||
|
@bubble.removeClass(@lastMood) if @lastMood
|
||||||
|
@lastMood = mood
|
||||||
|
@bubble.text('')
|
||||||
|
group = $('<div class="enter secret"></div>')
|
||||||
|
@bubble.append(group)
|
||||||
|
if responses
|
||||||
|
@lastResponses = responses
|
||||||
|
for response in responses
|
||||||
|
button = $('<button class="btn btn-small banner"></button>').text(response.text)
|
||||||
|
button.addClass response.buttonClass if response.buttonClass
|
||||||
|
group.append(button)
|
||||||
|
response.button = $('button:last', group)
|
||||||
|
else
|
||||||
|
s = $.i18n.t('play_level.hud_continue_short', defaultValue: 'Continue')
|
||||||
|
sk = $.i18n.t('play_level.skip_tutorial', defaultValue: 'skip: esc')
|
||||||
|
if not @escapePressed
|
||||||
|
group.append('<span class="hud-hint">' + sk + '</span>')
|
||||||
|
group.append($('<button class="btn btn-small banner with-dot">' + s + ' <div class="dot"></div></button>'))
|
||||||
|
@lastResponses = null
|
||||||
|
@animator = new DialogueAnimator(message, @bubble)
|
||||||
|
@messageInterval = setInterval(@addMoreMessage, 1000 / 30) # 30 FPS
|
||||||
|
|
||||||
|
addMoreMessage: =>
|
||||||
|
if @animator.done()
|
||||||
|
clearInterval(@messageInterval)
|
||||||
|
@messageInterval = null
|
||||||
|
$('.enter', @bubble).removeClass('secret').css('opacity', 0.0).delay(500).animate({opacity: 1.0}, 500, @animateEnterButton)
|
||||||
|
if @lastResponses
|
||||||
|
buttons = $('.enter button')
|
||||||
|
for response, i in @lastResponses
|
||||||
|
channel = response.channel.replace 'level-set-playing', 'level:set-playing' # Easier than migrating all those victory buttons.
|
||||||
|
f = (r) => => setTimeout((-> Backbone.Mediator.publish(channel, r.event or {})), 10)
|
||||||
|
$(buttons[i]).click(f(response))
|
||||||
|
else
|
||||||
|
$('.enter', @bubble).click(-> Backbone.Mediator.publish('script:end-current-script', {}))
|
||||||
|
return
|
||||||
|
@animator.tick()
|
||||||
|
|
||||||
|
onShiftSpacePressed: (e) ->
|
||||||
|
@shiftSpacePressed = (@shiftSpacePressed || 0) + 1
|
||||||
|
# We don't need to handle script:end-current-script--that's done--but if we do have
|
||||||
|
# custom buttons, then we need to trigger the one that should fire (the last one).
|
||||||
|
# If we decide that always having the last one fire is bad, we should make it smarter.
|
||||||
|
return unless @lastResponses?.length
|
||||||
|
r = @lastResponses[@lastResponses.length - 1]
|
||||||
|
channel = r.channel.replace 'level-set-playing', 'level:set-playing'
|
||||||
|
_.delay (-> Backbone.Mediator.publish(channel, r.event or {})), 10
|
||||||
|
|
||||||
|
onEscapePressed: (e) ->
|
||||||
|
@escapePressed = true
|
||||||
|
|
||||||
|
animateEnterButton: =>
|
||||||
|
return unless @bubble
|
||||||
|
button = $('.enter', @bubble)
|
||||||
|
dot = $('.dot', button)
|
||||||
|
dot.animate({opacity: 0.2}, 300).animate({opacity: 1.9}, 600, @animateEnterButton)
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
clearInterval(@messageInterval) if @messageInterval
|
||||||
|
super()
|
|
@ -1,7 +1,6 @@
|
||||||
CocoView = require 'views/kinds/CocoView'
|
CocoView = require 'views/kinds/CocoView'
|
||||||
template = require 'templates/play/level/hud'
|
template = require 'templates/play/level/hud'
|
||||||
prop_template = require 'templates/play/level/hud_prop'
|
prop_template = require 'templates/play/level/hud_prop'
|
||||||
DialogueAnimator = require './DialogueAnimator'
|
|
||||||
|
|
||||||
module.exports = class LevelHUDView extends CocoView
|
module.exports = class LevelHUDView extends CocoView
|
||||||
id: 'thang-hud'
|
id: 'thang-hud'
|
||||||
|
@ -180,6 +179,4 @@ module.exports = class LevelHUDView extends CocoView
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
@stage?.stopTalking()
|
@stage?.stopTalking()
|
||||||
clearInterval(@messageInterval) if @messageInterval
|
|
||||||
clearTimeout @hintNextSelectionTimeout if @hintNextSelectionTimeout
|
|
||||||
super()
|
super()
|
||||||
|
|
|
@ -141,6 +141,7 @@ module.exports = class LevelPlaybackView extends CocoView
|
||||||
console.warn('error disabling scrubber', error)
|
console.warn('error disabling scrubber', error)
|
||||||
@timePopup?.disable()
|
@timePopup?.disable()
|
||||||
$('#volume-button', @$el).removeClass('disabled')
|
$('#volume-button', @$el).removeClass('disabled')
|
||||||
|
@$el.addClass 'controls-disabled'
|
||||||
|
|
||||||
onEnableControls: (e) ->
|
onEnableControls: (e) ->
|
||||||
return if @realTime
|
return if @realTime
|
||||||
|
@ -152,6 +153,7 @@ module.exports = class LevelPlaybackView extends CocoView
|
||||||
catch error
|
catch error
|
||||||
console.warn('error enabling scrubber', error)
|
console.warn('error enabling scrubber', error)
|
||||||
@timePopup?.enable()
|
@timePopup?.enable()
|
||||||
|
@$el.removeClass 'controls-disabled'
|
||||||
|
|
||||||
onSetPlaying: (e) ->
|
onSetPlaying: (e) ->
|
||||||
@playing = (e ? {}).playing ? true
|
@playing = (e ? {}).playing ? true
|
||||||
|
|
|
@ -27,6 +27,7 @@ ProblemAlertView = require './tome/ProblemAlertView'
|
||||||
TomeView = require './tome/TomeView'
|
TomeView = require './tome/TomeView'
|
||||||
ChatView = require './LevelChatView'
|
ChatView = require './LevelChatView'
|
||||||
HUDView = require './LevelHUDView'
|
HUDView = require './LevelHUDView'
|
||||||
|
LevelDialogueView = require './LevelDialogueView'
|
||||||
ControlBarView = require './ControlBarView'
|
ControlBarView = require './ControlBarView'
|
||||||
LevelPlaybackView = require './LevelPlaybackView'
|
LevelPlaybackView = require './LevelPlaybackView'
|
||||||
GoalsView = require './LevelGoalsView'
|
GoalsView = require './LevelGoalsView'
|
||||||
|
@ -246,6 +247,7 @@ module.exports = class PlayLevelView extends RootView
|
||||||
@insertSubView new LevelFlagsView world: @world if (@levelID in ['sky-span', 'coinucopia']) or @level.get('type', true) in ['hero-ladder', 'hero-coop'] # TODO: figure out when flags are available
|
@insertSubView new LevelFlagsView world: @world if (@levelID in ['sky-span', 'coinucopia']) or @level.get('type', true) in ['hero-ladder', 'hero-coop'] # TODO: figure out when flags are available
|
||||||
@insertSubView new GoldView {}
|
@insertSubView new GoldView {}
|
||||||
@insertSubView new HUDView {level: @level}
|
@insertSubView new HUDView {level: @level}
|
||||||
|
@insertSubView new LevelDialogueView {level: @level}
|
||||||
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
|
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
|
||||||
if @level.get('type') in ['ladder', 'hero-ladder']
|
if @level.get('type') in ['ladder', 'hero-ladder']
|
||||||
@insertSubView new MultiplayerStatusView levelID: @levelID, session: @session, level: @level
|
@insertSubView new MultiplayerStatusView levelID: @levelID, session: @session, level: @level
|
||||||
|
|
Loading…
Reference in a new issue