This commit is contained in:
Scott Erickson 2014-02-28 13:59:33 -08:00
commit 4de425bd58
6 changed files with 62 additions and 35 deletions

View file

@ -19,3 +19,9 @@ Whether you're novice or pro, the CodeCombat team is ready to help you implement
### [License](https://github.com/codecombat/codecombat/blob/master/LICENSE)
[MIT](https://github.com/codecombat/codecombat/blob/master/LICENSE) for the code, and [CC-BY](http://codecombat.com/legal) for the art and music. Please also [sign the CodeCombat contributor license agreement](http://codecombat.com/cla) so we can accept your pull requests. It is easy.
----------
[![](https://dl.dropboxusercontent.com/u/138899/GitHub%20Wikis/challengepost.png)](http://codecombat.challengepost.com/?utm_source-github&utm_medium-oswidget&utm_campaign-codecombat)
[![](http://1-ps.googleusercontent.com/x/s.google-melange.appspot.com/www.google-melange.com/soc/content/2-1-20140225/images/gsoc/logo/920x156xbanner-gsoc2014.png.pagespeed.ic.gdr4t3Igca.png)](http://www.google-melange.com/gsoc/homepage/google/gsoc2014)

View file

@ -100,7 +100,7 @@ module.exports = Surface = class Surface extends CocoClass
@stage.removeAllEventListeners()
@stage.enableDOMEvents false
@stage.enableMouseOver 0
@playScrubbedSounds = null
@onFramesScrubbed = null
@onMouseMove = null
@onMouseDown = null
@tick = null
@ -202,32 +202,33 @@ module.exports = Surface = class Surface extends CocoClass
.get(@)
.to({currentFrame:@scrubbingTo}, scrubDuration, createjs.Ease.sineInOut)
.call(onTweenEnd)
t.addEventListener('change', @playScrubbedSounds)
t.addEventListener('change', @onFramesScrubbed)
else
@currentFrame = @scrubbingTo
@playScrubbedSounds()
@onFramesScrubbed() # For performance, don't play these for instant transitions.
onTweenEnd()
@updateState true
@onFrameChanged()
playScrubbedSounds: (e) =>
# gotta play all the sounds, even when scrubbing!
rising = @currentFrame > @lastFrame
actualCurrentFrame = @currentFrame
tempFrame = if rising then Math.ceil(@lastFrame) else Math.floor(@lastFrame)
while true # temporary fix to stop cacophony
break if rising and tempFrame > actualCurrentFrame
break if (not rising) and tempFrame < actualCurrentFrame
@currentFrame = tempFrame
frame = @world.getFrame(@getCurrentFrame())
frame.restoreState()
for thangID, sprite of @spriteBoss.sprites
sprite.playSounds false, Math.max(0.05, Math.min(1, 1 / @scrubbingPlaybackSpeed))
tempFrame += if rising then 1 else -1
@currentFrame = actualCurrentFrame
onFramesScrubbed: (e) =>
if e
# Gotta play all the sounds when scrubbing (but not when doing an immediate transition).
rising = @currentFrame > @lastFrame
actualCurrentFrame = @currentFrame
tempFrame = if rising then Math.ceil(@lastFrame) else Math.floor(@lastFrame)
while true # temporary fix to stop cacophony
break if rising and tempFrame > actualCurrentFrame
break if (not rising) and tempFrame < actualCurrentFrame
@currentFrame = tempFrame
frame = @world.getFrame(@getCurrentFrame())
frame.restoreState()
for thangID, sprite of @spriteBoss.sprites
sprite.playSounds false, Math.max(0.05, Math.min(1, 1 / @scrubbingPlaybackSpeed))
tempFrame += if rising then 1 else -1
@currentFrame = actualCurrentFrame
# TODO: are these needed, or perhaps do they duplicate things?
@restoreWorldState()
@spriteBoss.update true
@onFrameChanged()
@ -325,7 +326,7 @@ module.exports = Surface = class Surface extends CocoClass
onNewWorld: (event) ->
return unless event.world.name is @world.name
@casting = false
# This has a tendency to break scripts that are waiting for playback to change when the level is loaded
# so only run it after the first world is created.
Backbone.Mediator.publish 'level-set-playing', { playing: @wasPlayingWhenCastingBegan } unless event.firstWorld
@ -493,14 +494,23 @@ module.exports = Surface = class Surface extends CocoClass
tick: (e) =>
# seems to be a bug where only one object can register with the Ticker...
oldFrame = @currentFrame
oldWorldFrame = Math.floor oldFrame
while true
Dropper.tick()
@trailmaster.tick() if @trailmaster
# Skip some frame updates unless we're playing and not at end (or we haven't drawn much yet)
frameAdvanced = (@playing and @currentFrame < @world.totalFrames) or @totalFramesDrawn < 2
@currentFrame += @world.frameRate / @frameRate if frameAdvanced
@updateSpriteSounds() if frameAdvanced
newWorldFrame = Math.floor @currentFrame
worldFrameAdvanced = newWorldFrame isnt oldWorldFrame
if worldFrameAdvanced
# Only restore world state when it will correspond to an integer WorldFrame, not interpolated frame.
@restoreWorldState()
oldWorldFrame = newWorldFrame
break unless Dropper.drop()
if frameAdvanced and not worldFrameAdvanced
# We didn't end the above loop on an integer frame, so do the world state update.
@restoreWorldState()
# these are skipped for dropped frames
@updateState @currentFrame isnt oldFrame
@ -513,7 +523,7 @@ module.exports = Surface = class Surface extends CocoClass
Backbone.Mediator.publish('surface:mouse-' + (if mib then "over" else "out"), {})
@mouseInBounds = mib
updateSpriteSounds: ->
restoreWorldState: ->
@world.getFrame(@getCurrentFrame()).restoreState()
current = Math.max(0, Math.min(@currentFrame, @world.totalFrames - 1))
if current - Math.floor(current) > 0.01
@ -523,7 +533,7 @@ module.exports = Surface = class Surface extends CocoClass
@spriteBoss.updateSounds()
updateState: (frameChanged) ->
# world state must have been restored in @updateSpriteSounds
# world state must have been restored in @restoreWorldState
@camera.updateZoom()
@spriteBoss.update frameChanged unless @casting
@dimmer?.setSprites @spriteBoss.sprites

View file

@ -24,6 +24,7 @@ module.exports = class ThangTypeHomeView extends View
'click button.new-model-submit': 'makeNewModel'
'submit form': 'makeNewModel'
'shown.bs.modal #new-model-modal': 'focusOnName'
'hidden.bs.modal #new-model-modal': 'onModalHidden'
getRenderData: ->
c = super()
@ -85,16 +86,21 @@ module.exports = class ThangTypeHomeView extends View
res = model.save()
return unless res
modal = @$el.find('.modal')
modal = @$el.find('#new-model-modal')
forms.clearFormAlerts(modal)
@showLoading(modal.find('.modal-body'))
res.error =>
@hideLoading()
forms.applyErrorsToForm(modal, JSON.parse(res.responseText))
that = @
res.success ->
modal.modal('hide')
base = document.location.pathname[1..] + '/'
app.router.navigate(base + (model.get('slug') or model.id), {trigger:true})
that.model = model
modal.modal('hide')
onModalHidden: ->
# Can only redirect after the modal hidden event has triggered
base = document.location.pathname[1..] + '/'
app.router.navigate(base + (@model.get('slug') or @model.id), {trigger:true})
focusOnName: ->
@$el.find('#name').focus()

View file

@ -145,7 +145,9 @@ module.exports = class HUDView extends View
createActions: ->
actions = @$el.find('.thang-actions tbody').empty()
return unless @thang.world and not _.isEmpty @thang.actions
showActions = @thang.world and not _.isEmpty(@thang.actions) and 'action' in @thang.hudProperties ? []
@$el.find('.thang-actions').toggle showActions
return unless showActions
@buildActionTimespans()
for actionName, action of @thang.actions
actions.append @createActionElement(actionName)

View file

@ -44,15 +44,16 @@ module.exports = class SpellPaletteView extends View
allDocs = {}
for lc in lcs
for doc in (lc.get('propertyDocumentation') ? [])
allDocs[doc.name] ?= []
allDocs[doc.name].push doc
allDocs['__' + doc.name] ?= []
allDocs['__' + doc.name].push doc
if doc.type is 'snippet' then doc.owner = 'snippets'
#allDocs[doc.name] = doc for doc in (lc.get('propertyDocumentation') ? []) for lc in lcs
propStorage =
'this': 'programmableProperties'
more: 'moreProgrammableProperties'
Math: 'programmableMathProperties'
Array: 'programmableArrayProperties'
String: 'programmableStringProperties'
Vector: 'programmableVectorProperties'
snippets: 'programmableSnippets'
count = 0
@ -66,10 +67,10 @@ module.exports = class SpellPaletteView extends View
@entries = []
for owner, props of propGroups
for prop in props
doc = _.find (allDocs[prop] ? []), (doc) ->
doc = _.find (allDocs['__' + prop] ? []), (doc) ->
return true if doc.owner is owner
return (owner is 'this' or owner is 'more') and (not doc.owner? or doc.owner is 'this')
console.log 'could not find doc for', prop, 'from', allDocs[prop], 'for', owner, 'of', propGroups unless doc
console.log 'could not find doc for', prop, 'from', allDocs['__' + prop], 'for', owner, 'of', propGroups unless doc
doc ?= prop
@entries.push @addEntry(doc, shortenize, tabbify, owner is 'snippets')
groupForEntry = (entry) ->

View file

@ -181,7 +181,8 @@ findNearestBetterSessionID = (sessionTotalScore, opponentSessionTotalScore, oppo
$gt:opponentSessionTotalScore + 0.5
_id:
$ne: opponentSessionID
levelID: "project-dota"
"level.original": "52d97ecd32362bc86e004e87"
"level.majorVersion": 0
submitted: true
submittedCode:
$exists: true
@ -280,7 +281,8 @@ updateSessionToSubmit = (sessionToUpdate, callback) ->
fetchInitialSessionsToRankAgainst = (opposingTeam, callback) ->
console.log "Fetching sessions to rank against for opposing team #{opposingTeam}"
findParameters =
levelID: "project-dota"
"level.original": "52d97ecd32362bc86e004e87"
"level.majorVersion": 0
submitted: true
submittedCode:
$exists: true