mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-29 02:25:37 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
bf0013ea0a
12 changed files with 103 additions and 135 deletions
|
@ -4,22 +4,4 @@ module.exports = [
|
||||||
noteChain: []
|
noteChain: []
|
||||||
id: "Introduction"
|
id: "Introduction"
|
||||||
}
|
}
|
||||||
{
|
|
||||||
channel: "world:won"
|
|
||||||
noteChain: []
|
|
||||||
id: "Victory Playback"
|
|
||||||
scriptPrereqs: ["Introduction"]
|
|
||||||
}
|
|
||||||
{
|
|
||||||
channel: "level:set-playing"
|
|
||||||
noteChain: []
|
|
||||||
scriptPrereqs: ["Victory Playback"]
|
|
||||||
id: "Victory Playback Started"
|
|
||||||
}
|
|
||||||
{
|
|
||||||
channel: "surface:frame-changed"
|
|
||||||
noteChain: []
|
|
||||||
scriptPrereqs: ["Victory Playback Started"]
|
|
||||||
id: "Show Victory"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -256,7 +256,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
|
||||||
@publishNote(note)
|
@publishNote(note)
|
||||||
|
|
||||||
publishNote: (note) ->
|
publishNote: (note) ->
|
||||||
Backbone.Mediator.publish 'playback:real-time-playback-ended', {}
|
Backbone.Mediator.publish 'playback:real-time-playback-ended', {} unless @session.get('heroConfig') # Only old levels need this, to stop interfering with old victory coolcams.
|
||||||
Backbone.Mediator.publish note.channel, note.event ? {}
|
Backbone.Mediator.publish note.channel, note.event ? {}
|
||||||
|
|
||||||
# ENDING NOTES
|
# ENDING NOTES
|
||||||
|
|
|
@ -408,9 +408,10 @@
|
||||||
tome_minion_spells: "Your Minions' Spells"
|
tome_minion_spells: "Your Minions' Spells"
|
||||||
tome_read_only_spells: "Read-Only Spells"
|
tome_read_only_spells: "Read-Only Spells"
|
||||||
tome_other_units: "Other Units"
|
tome_other_units: "Other Units"
|
||||||
tome_cast_button_castable: "Cast Spell"
|
tome_cast_button_run: "Run"
|
||||||
tome_cast_button_casting: "Casting"
|
tome_cast_button_running: "Running"
|
||||||
tome_cast_button_cast: "Spell Cast"
|
tome_cast_button_ran: "Ran"
|
||||||
|
tome_submit_button: "Submit"
|
||||||
tome_select_spell: "Select a Spell"
|
tome_select_spell: "Select a Spell"
|
||||||
tome_select_a_thang: "Select Someone for "
|
tome_select_a_thang: "Select Someone for "
|
||||||
tome_available_spells: "Available Spells"
|
tome_available_spells: "Available Spells"
|
||||||
|
|
|
@ -4,86 +4,55 @@
|
||||||
+keyframes(castablePulse)
|
+keyframes(castablePulse)
|
||||||
from
|
from
|
||||||
@include box-shadow(0px 0px 8px #333)
|
@include box-shadow(0px 0px 8px #333)
|
||||||
50%
|
|
||||||
@include box-shadow(0px 0px 35px skyblue)
|
|
||||||
to
|
|
||||||
@include box-shadow(0px 0px 8px #333)
|
|
||||||
|
|
||||||
+keyframes(castablePulseButton)
|
|
||||||
from
|
|
||||||
color: white
|
color: white
|
||||||
50%
|
50%
|
||||||
|
@include box-shadow(0px 0px 35px skyblue)
|
||||||
color: skyblue
|
color: skyblue
|
||||||
to
|
to
|
||||||
|
@include box-shadow(0px 0px 8px #333)
|
||||||
|
color: white
|
||||||
|
|
||||||
|
+keyframes(winnablePulse)
|
||||||
|
from
|
||||||
|
@include box-shadow(0px 0px 8px #333)
|
||||||
|
color: white
|
||||||
|
50%
|
||||||
|
@include box-shadow(0px 0px 35px #87FFCE)
|
||||||
|
color: #87FFFF
|
||||||
|
to
|
||||||
|
@include box-shadow(0px 0px 8px #333)
|
||||||
color: white
|
color: white
|
||||||
|
|
||||||
#cast-button-view
|
#cast-button-view
|
||||||
display: none
|
display: none
|
||||||
position: absolute
|
position: absolute
|
||||||
width: 35%
|
|
||||||
|
|
||||||
.cast-button-group
|
z-index: 2
|
||||||
z-index: 2
|
width: 100%
|
||||||
|
border-radius: 6px
|
||||||
|
|
||||||
|
.btn
|
||||||
|
padding: 3px 10px
|
||||||
|
height: 40px
|
||||||
|
|
||||||
|
.submit-button
|
||||||
|
margin-left: 20px
|
||||||
|
|
||||||
|
.cast-button
|
||||||
|
margin-left: 10px
|
||||||
@include opacity(0.77)
|
@include opacity(0.77)
|
||||||
width: 100%
|
|
||||||
border-radius: 6px
|
|
||||||
|
|
||||||
.button-progress-overlay
|
|
||||||
position: absolute
|
|
||||||
left: -1px
|
|
||||||
top: -1px
|
|
||||||
bottom: -1px
|
|
||||||
border-radius: 6px
|
|
||||||
z-index: 10
|
|
||||||
pointer-events: none
|
|
||||||
// This transition time should roughly match the world progress update interval
|
|
||||||
@include transition(width .2s linear)
|
|
||||||
@include transition(box-shadow .2s linear)
|
|
||||||
|
|
||||||
&.casting .button-progress-overlay
|
|
||||||
background-color: green
|
|
||||||
@include opacity(0.5)
|
|
||||||
@include box-shadow(0px 0px 15px green)
|
|
||||||
|
|
||||||
&:hover, &.castable
|
&:hover, &.castable
|
||||||
@include opacity(1)
|
@include opacity(1)
|
||||||
|
|
||||||
&.castable
|
&:not(.winnable) .cast-button.castable
|
||||||
-webkit-animation-name: castablePulse
|
font-weight: bold
|
||||||
-webkit-animation-duration: 3s
|
-webkit-animation-name: castablePulse
|
||||||
-webkit-animation-iteration-count: infinite
|
-webkit-animation-duration: 3s
|
||||||
|
-webkit-animation-iteration-count: infinite
|
||||||
|
|
||||||
.cast-button
|
&.winnable .submit-button
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
-webkit-animation-name: castablePulseButton
|
-webkit-animation-name: winnablePulse
|
||||||
-webkit-animation-duration: 3s
|
-webkit-animation-duration: 3s
|
||||||
-webkit-animation-iteration-count: infinite
|
-webkit-animation-iteration-count: infinite
|
||||||
&:not(.castable):not(:hover)
|
|
||||||
.cast-options-button
|
|
||||||
// Mimic the disabled visuals
|
|
||||||
@include opacity(0.65)
|
|
||||||
background-image: none
|
|
||||||
@include box-shadow(none)
|
|
||||||
|
|
||||||
.btn
|
|
||||||
padding: 3px 10px
|
|
||||||
height: 40px
|
|
||||||
|
|
||||||
.cast-button
|
|
||||||
width: 80%
|
|
||||||
width: -webkit-calc(100% - 40px)
|
|
||||||
width: calc(100% - 40px)
|
|
||||||
border-top-left-radius: 6px
|
|
||||||
border-bottom-left-radius: 6px
|
|
||||||
|
|
||||||
@media screen and (max-width: 1440px)
|
|
||||||
font-size: 16px
|
|
||||||
@media screen and (max-width: 1280px)
|
|
||||||
font-size: 14px
|
|
||||||
@media screen and (max-width: 1024px)
|
|
||||||
font-size: 12px
|
|
||||||
|
|
||||||
.cast-real-time-button
|
|
||||||
width: 20%
|
|
||||||
width: -webkit-calc(40px)
|
|
||||||
width: calc(40px)
|
|
||||||
|
|
|
@ -16,9 +16,8 @@ block modal-footer-content
|
||||||
else if level.get('type') === 'ladder'
|
else if level.get('type') === 'ladder'
|
||||||
a.btn.btn-primary(href="/play/ladder/#{level.get('slug')}#my-matches", data-dismiss="modal", data-i18n="play_level.victory_go_ladder") Return to Ladder
|
a.btn.btn-primary(href="/play/ladder/#{level.get('slug')}#my-matches", data-dismiss="modal", data-i18n="play_level.victory_go_ladder") Return to Ladder
|
||||||
else if hasNextLevel
|
else if hasNextLevel
|
||||||
button.btn.btn-primary.next-level-button(data-dismiss="modal", data-i18n="play_level.victory_play_next_level") Play Next Level
|
button.btn.btn-success.next-level-button(data-dismiss="modal", data-i18n="play_level.victory_play_next_level") Play Next Level
|
||||||
else
|
a.btn.btn-primary(href="/play-hero", data-dismiss="modal", data-i18n="play_level.victory_go_home") Go Home
|
||||||
a.btn.btn-primary(href="/", data-dismiss="modal", data-i18n="play_level.victory_go_home") Go Home
|
|
||||||
if me.get('anonymous')
|
if me.get('anonymous')
|
||||||
p.sign-up-poke
|
p.sign-up-poke
|
||||||
button.btn.btn-success.sign-up-button.btn-large(data-toggle="coco-modal", data-target="modal/SignupModal", data-i18n="play_level.victory_sign_up") Sign Up to Save Progress
|
button.btn.btn-success.sign-up-button.btn-large(data-toggle="coco-modal", data-target="modal/SignupModal", data-i18n="play_level.victory_sign_up") Sign Up to Save Progress
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
div.btn-group.btn-group-lg.cast-button-group
|
button.btn.btn-lg.btn-inverse.banner.cast-button(title=castVerbose, data-i18n="play_level.tome_run_button_ran") Ran
|
||||||
.button-progress-overlay
|
|
||||||
button.btn.btn-inverse.banner.cast-button(title=castVerbose, data-i18n="play_level.tome_cast_button_cast") Spell Cast
|
button.btn.btn-lg.btn-success.banner.submit-button(title=castRealTimeVerbose) Submit
|
||||||
button.btn.btn-inverse.banner.cast-real-time-button(title=castRealTimeVerbose)
|
|
||||||
i.glyphicon.glyphicon-play
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ module.exports = class DeltaView extends CocoView
|
||||||
TreemaNode.make(rightEl, options).build()
|
TreemaNode.make(rightEl, options).build()
|
||||||
|
|
||||||
if deltaData.action is 'text-diff'
|
if deltaData.action is 'text-diff'
|
||||||
|
return console.error "Couldn't show diff for left: #{deltaData.left}, right: #{deltaData.right} of delta:", deltaData unless deltaData.left? and deltaData.right?
|
||||||
left = difflib.stringAsLines deltaData.left
|
left = difflib.stringAsLines deltaData.left
|
||||||
right = difflib.stringAsLines deltaData.right
|
right = difflib.stringAsLines deltaData.right
|
||||||
sm = new difflib.SequenceMatcher(left, right)
|
sm = new difflib.SequenceMatcher(left, right)
|
||||||
|
|
|
@ -587,7 +587,7 @@ hero = [
|
||||||
difficulty: 1
|
difficulty: 1
|
||||||
id: 'kithgard-gates'
|
id: 'kithgard-gates'
|
||||||
image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png'
|
image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png'
|
||||||
description: 'Board up Kithguard and escape into the forest.'
|
description: 'Escape the Kithgard dungeons and don\'t let the guardians get you.'
|
||||||
x: 47.38
|
x: 47.38
|
||||||
y: 70.55
|
y: 70.55
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,10 @@ module.exports = class ControlBarView extends CocoView
|
||||||
c.multiplayerEnabled = @session.get('multiplayer')
|
c.multiplayerEnabled = @session.get('multiplayer')
|
||||||
c.ladderGame = @level.get('type') is 'ladder'
|
c.ladderGame = @level.get('type') is 'ladder'
|
||||||
c.spectateGame = @spectateGame
|
c.spectateGame = @spectateGame
|
||||||
if @level.get('type') in ['ladder', 'ladder-tutorial']
|
if @level.get('type', true) in ['ladder', 'ladder-tutorial']
|
||||||
c.homeLink = '/play/ladder/' + @level.get('slug').replace /\-tutorial$/, ''
|
c.homeLink = '/play/ladder/' + @level.get('slug').replace /\-tutorial$/, ''
|
||||||
|
else if @level.get('type', true) is 'hero'
|
||||||
|
c.homeLink = '/play-hero'
|
||||||
else
|
else
|
||||||
c.homeLink = '/'
|
c.homeLink = '/'
|
||||||
c.editorLink = "/editor/level/#{@level.get('slug')}"
|
c.editorLink = "/editor/level/#{@level.get('slug')}"
|
||||||
|
|
|
@ -146,7 +146,11 @@ module.exports = class LevelHUDView extends CocoView
|
||||||
createProperties: ->
|
createProperties: ->
|
||||||
props = @$el.find('.thang-props')
|
props = @$el.find('.thang-props')
|
||||||
props.find(':not(.thang-name)').remove()
|
props.find(':not(.thang-name)').remove()
|
||||||
props.find('.thang-name').text(if @thang.type then "#{@thang.id} - #{@thang.type}" else @thang.id)
|
if @thang.id is 'Hero Placeholder'
|
||||||
|
name = {knight: 'Tharin', captain: 'Anya'}[@thang.type] ? 'Hero'
|
||||||
|
else
|
||||||
|
name = if @thang.type then "#{@thang.id} - #{@thang.type}" else @thang.id
|
||||||
|
props.find('.thang-name').text name
|
||||||
propNames = _.without @thang.hudProperties ? [], 'action'
|
propNames = _.without @thang.hudProperties ? [], 'action'
|
||||||
nColumns = Math.ceil propNames.length / 5
|
nColumns = Math.ceil propNames.length / 5
|
||||||
columns = ($('<div class="thang-props-column"></div>').appendTo(props) for i in [0 ... nColumns])
|
columns = ($('<div class="thang-props-column"></div>').appendTo(props) for i in [0 ... nColumns])
|
||||||
|
|
|
@ -430,7 +430,7 @@ module.exports = class PlayLevelView extends RootView
|
||||||
onDonePressed: -> @showVictory()
|
onDonePressed: -> @showVictory()
|
||||||
|
|
||||||
onShowVictory: (e) ->
|
onShowVictory: (e) ->
|
||||||
$('#level-done-button').show()
|
$('#level-done-button').show() unless @level.get('type', true) is 'hero'
|
||||||
@showVictory() if e.showModal
|
@showVictory() if e.showModal
|
||||||
setTimeout(@preloadNextLevel, 3000)
|
setTimeout(@preloadNextLevel, 3000)
|
||||||
return if @victorySeen
|
return if @victorySeen
|
||||||
|
@ -584,8 +584,12 @@ module.exports = class PlayLevelView extends RootView
|
||||||
@world.scripts = scripts
|
@world.scripts = scripts
|
||||||
thangTypes = @supermodel.getModels(ThangType)
|
thangTypes = @supermodel.getModels(ThangType)
|
||||||
startFrame = @lastWorldFramesLoaded ? 0
|
startFrame = @lastWorldFramesLoaded ? 0
|
||||||
if @world.frames.length is @world.totalFrames # Finished loading
|
finishedLoading = @world.frames.length is @world.totalFrames
|
||||||
|
if finishedLoading
|
||||||
@lastWorldFramesLoaded = 0
|
@lastWorldFramesLoaded = 0
|
||||||
|
if @waitingForSubmissionComplete
|
||||||
|
@onSubmissionComplete()
|
||||||
|
@waitingForSubmissionComplete = false
|
||||||
else
|
else
|
||||||
@lastWorldFramesLoaded = @world.frames.length
|
@lastWorldFramesLoaded = @world.frames.length
|
||||||
for [spriteName, message] in @world.thangDialogueSounds startFrame
|
for [spriteName, message] in @world.thangDialogueSounds startFrame
|
||||||
|
@ -605,15 +609,23 @@ module.exports = class PlayLevelView extends RootView
|
||||||
onRealTimePlaybackEnded: (e) ->
|
onRealTimePlaybackEnded: (e) ->
|
||||||
@$el.removeClass 'real-time'
|
@$el.removeClass 'real-time'
|
||||||
@onWindowResize()
|
@onWindowResize()
|
||||||
|
if @world.frames.length is @world.totalFrames
|
||||||
|
_.delay @onSubmissionComplete, 750 # Wait for transition to end.
|
||||||
|
else
|
||||||
|
@waitingForSubmissionComplete = true
|
||||||
@onRealTimeMultiplayerPlaybackEnded()
|
@onRealTimeMultiplayerPlaybackEnded()
|
||||||
|
|
||||||
|
onSubmissionComplete: =>
|
||||||
|
return if @destroyed
|
||||||
|
@showVictory() if @goalManager.checkOverallStatus() is 'success'
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
@levelLoader?.destroy()
|
@levelLoader?.destroy()
|
||||||
@surface?.destroy()
|
@surface?.destroy()
|
||||||
@god?.destroy()
|
@god?.destroy()
|
||||||
@goalManager?.destroy()
|
@goalManager?.destroy()
|
||||||
@scriptManager?.destroy()
|
@scriptManager?.destroy()
|
||||||
@ambientSound.stop()
|
@ambientSound?.stop()
|
||||||
$(window).off 'resize', @onWindowResize
|
$(window).off 'resize', @onWindowResize
|
||||||
delete window.world # not sure where this is set, but this is one way to clean it up
|
delete window.world # not sure where this is set, but this is one way to clean it up
|
||||||
clearInterval(@pointerInterval)
|
clearInterval(@pointerInterval)
|
||||||
|
|
|
@ -8,15 +8,15 @@ module.exports = class CastButtonView extends CocoView
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click .cast-button': 'onCastButtonClick'
|
'click .cast-button': 'onCastButtonClick'
|
||||||
'click .cast-real-time-button': 'onCastRealTimeButtonClick'
|
'click .submit-button': 'onCastRealTimeButtonClick'
|
||||||
|
|
||||||
subscriptions:
|
subscriptions:
|
||||||
'tome:spell-changed': 'onSpellChanged'
|
'tome:spell-changed': 'onSpellChanged'
|
||||||
'tome:cast-spells': 'onCastSpells'
|
'tome:cast-spells': 'onCastSpells'
|
||||||
'god:world-load-progress-changed': 'onWorldLoadProgressChanged'
|
|
||||||
'god:new-world-created': 'onNewWorld'
|
'god:new-world-created': 'onNewWorld'
|
||||||
'real-time-multiplayer:joined-game': 'onJoinedRealTimeMultiplayerGame'
|
'real-time-multiplayer:joined-game': 'onJoinedRealTimeMultiplayerGame'
|
||||||
'real-time-multiplayer:left-game': 'onLeftRealTimeMultiplayerGame'
|
'real-time-multiplayer:left-game': 'onLeftRealTimeMultiplayerGame'
|
||||||
|
'goal-manager:new-goal-states': 'onNewGoalStates'
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
super options
|
super options
|
||||||
|
@ -37,11 +37,11 @@ module.exports = class CastButtonView extends CocoView
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
super()
|
super()
|
||||||
@castButton = $('.cast-button', @$el)
|
@castButton = $('.cast-button', @$el)
|
||||||
@castButtonGroup = $('.cast-button-group', @$el)
|
|
||||||
@castOptions = $('.autocast-delays', @$el)
|
@castOptions = $('.autocast-delays', @$el)
|
||||||
#delay = me.get('autocastDelay') # No more autocast
|
#delay = me.get('autocastDelay') # No more autocast
|
||||||
delay = 90019001
|
delay = 90019001
|
||||||
@setAutocastDelay delay
|
@setAutocastDelay delay
|
||||||
|
@$el.find('.submit-button').hide() if @options.levelID is 'dungeons-of-kithgard'
|
||||||
|
|
||||||
attachTo: (spellView) ->
|
attachTo: (spellView) ->
|
||||||
@$el.detach().prependTo(spellView.toolbarView.$el).show()
|
@$el.detach().prependTo(spellView.toolbarView.$el).show()
|
||||||
|
@ -71,12 +71,6 @@ module.exports = class CastButtonView extends CocoView
|
||||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'cast', volume: 0.5
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'cast', volume: 0.5
|
||||||
@hasStartedCastingOnce = true
|
@hasStartedCastingOnce = true
|
||||||
@updateCastButton()
|
@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) ->
|
onNewWorld: (e) ->
|
||||||
@casting = false
|
@casting = false
|
||||||
|
@ -85,6 +79,12 @@ module.exports = class CastButtonView extends CocoView
|
||||||
@hasCastOnce = true
|
@hasCastOnce = true
|
||||||
@updateCastButton()
|
@updateCastButton()
|
||||||
|
|
||||||
|
onNewGoalStates: (e) ->
|
||||||
|
@winnable = e.overallStatus is 'success'
|
||||||
|
@$el.toggleClass 'winnable', @winnable
|
||||||
|
if @winnable
|
||||||
|
@$el.find('.submit-button').show() # In case we hid it, like on the first level.
|
||||||
|
|
||||||
updateCastButton: ->
|
updateCastButton: ->
|
||||||
return if _.some @spells, (spell) => not spell.loaded
|
return if _.some @spells, (spell) => not spell.loaded
|
||||||
|
|
||||||
|
@ -92,13 +92,13 @@ module.exports = class CastButtonView extends CocoView
|
||||||
spell.hasChangedSignificantly spell.getSource(), null, callback
|
spell.hasChangedSignificantly spell.getSource(), null, callback
|
||||||
, (castable) =>
|
, (castable) =>
|
||||||
Backbone.Mediator.publish 'tome:spell-has-changed-significantly-calculation', hasChangedSignificantly: castable
|
Backbone.Mediator.publish 'tome:spell-has-changed-significantly-calculation', hasChangedSignificantly: castable
|
||||||
@castButtonGroup.toggleClass('castable', castable).toggleClass('casting', @casting)
|
@castButton.toggleClass('castable', castable).toggleClass('casting', @casting)
|
||||||
if @casting
|
if @casting
|
||||||
s = $.i18n.t('play_level.tome_cast_button_casting', defaultValue: 'Casting')
|
s = $.i18n.t('play_level.tome_cast_button_running')
|
||||||
else if castable
|
else if castable
|
||||||
s = $.i18n.t('play_level.tome_cast_button_castable', defaultValue: 'Cast Spell') + ' ' + @castShortcut
|
s = $.i18n.t('play_level.tome_cast_button_run') + ' ' + @castShortcut
|
||||||
else
|
else
|
||||||
s = $.i18n.t('play_level.tome_cast_button_cast', defaultValue: 'Spell Cast')
|
s = $.i18n.t('play_level.tome_cast_button_ran')
|
||||||
@castButton.text s
|
@castButton.text s
|
||||||
@castButton.prop 'disabled', not castable
|
@castButton.prop 'disabled', not castable
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue