Merge branch 'master' of https://github.com/codecombat/codecombat
This commit is contained in:
commit
98245d0fb9
10 changed files with 102 additions and 94 deletions
app
lib
models
styles/play/level
templates/play/level
views
server
|
@ -82,6 +82,7 @@ module.exports = class SpriteParser
|
||||||
shortKey = @shapeLongKeys[longKey]
|
shortKey = @shapeLongKeys[longKey]
|
||||||
unless shortKey?
|
unless shortKey?
|
||||||
shortKey = '' + _.size @thangType.shapes
|
shortKey = '' + _.size @thangType.shapes
|
||||||
|
shortKey += '+' while @thangType.shapes[shortKey]
|
||||||
@thangType.shapes[shortKey] = shape
|
@thangType.shapes[shortKey] = shape
|
||||||
@shapeLongKeys[longKey] = shortKey
|
@shapeLongKeys[longKey] = shortKey
|
||||||
return shortKey
|
return shortKey
|
||||||
|
|
|
@ -129,7 +129,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
reg = @getOffset 'registration'
|
reg = @getOffset 'registration'
|
||||||
@imageObject.regX = -reg.x
|
@imageObject.regX = -reg.x
|
||||||
@imageObject.regY = -reg.y
|
@imageObject.regY = -reg.y
|
||||||
if @currentRootAction.name is 'move'
|
if @currentRootAction.name is 'move' and action.frames
|
||||||
start = Math.floor(Math.random() * action.frames.length)
|
start = Math.floor(Math.random() * action.frames.length)
|
||||||
@imageObject.currentAnimationFrame = start
|
@imageObject.currentAnimationFrame = start
|
||||||
|
|
||||||
|
@ -375,6 +375,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
e = _.clone(e)
|
e = _.clone(e)
|
||||||
e.sprite = @
|
e.sprite = @
|
||||||
e.blurb ?= '...'
|
e.blurb ?= '...'
|
||||||
|
e.thang = @thang
|
||||||
Backbone.Mediator.publish 'sprite:speech-updated', e
|
Backbone.Mediator.publish 'sprite:speech-updated', e
|
||||||
|
|
||||||
isTalking: ->
|
isTalking: ->
|
||||||
|
@ -427,5 +428,5 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
delay = if withDelay and sound.delay then 1000 * sound.delay / createjs.Ticker.getFPS() else 0
|
delay = if withDelay and sound.delay then 1000 * sound.delay / createjs.Ticker.getFPS() else 0
|
||||||
name = AudioPlayer.nameForSoundReference sound
|
name = AudioPlayer.nameForSoundReference sound
|
||||||
instance = createjs.Sound.play name, "none", delay, 0, 0, volume
|
instance = createjs.Sound.play name, "none", delay, 0, 0, volume
|
||||||
#console.log @thang?.id, "played sound", name, "with delay", delay, "volume", volume, "and got sound instance", instance
|
# console.log @thang?.id, "played sound", name, "with delay", delay, "volume", volume, "and got sound instance", instance
|
||||||
instance
|
instance
|
|
@ -233,7 +233,7 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
sprite?.selected = true
|
sprite?.selected = true
|
||||||
@selectedSprite = sprite
|
@selectedSprite = sprite
|
||||||
alive = sprite?.thang.health > 0
|
alive = sprite?.thang.health > 0
|
||||||
sprite.playSound 'selected' if alive and not @suppressSelectionSounds
|
|
||||||
Backbone.Mediator.publish "surface:sprite-selected",
|
Backbone.Mediator.publish "surface:sprite-selected",
|
||||||
thang: if sprite then sprite.thang else null
|
thang: if sprite then sprite.thang else null
|
||||||
sprite: sprite
|
sprite: sprite
|
||||||
|
@ -241,6 +241,14 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
originalEvent: e
|
originalEvent: e
|
||||||
worldPos: worldPos
|
worldPos: worldPos
|
||||||
|
|
||||||
|
if alive and not @suppressSelectionSounds
|
||||||
|
instance = sprite.playSound 'selected'
|
||||||
|
if instance.playState is 'playSucceeded'
|
||||||
|
Backbone.Mediator.publish 'thang-began-talking', thang: sprite?.thang
|
||||||
|
instance.addEventListener 'complete', ->
|
||||||
|
Backbone.Mediator.publish 'thang-finished-talking', thang: sprite?.thang
|
||||||
|
console.log 'select...', instance.playState
|
||||||
|
|
||||||
# Marks
|
# Marks
|
||||||
|
|
||||||
updateSelection: ->
|
updateSelection: ->
|
||||||
|
|
|
@ -179,7 +179,7 @@ module.exports.Trailmaster = class Trailmaster
|
||||||
animation = sprite.getActionDirection(animation) ? animation # no idea if this ever works
|
animation = sprite.getActionDirection(animation) ? animation # no idea if this ever works
|
||||||
clone.gotoAndStop animation.name
|
clone.gotoAndStop animation.name
|
||||||
# TODO: use action-specific framerate here?
|
# TODO: use action-specific framerate here?
|
||||||
clone.currentAnimationFrame = Math.min(@clock % (animation.frames.length * 3), animation.frames.length - 1)
|
# clone.currentAnimationFrame = Math.min(@clock % (animation.frames.length * 3), animation.frames.length - 1)
|
||||||
sprites.push(clone)
|
sprites.push(clone)
|
||||||
lastPos = x: thang.pos.x, y: thang.pos.y
|
lastPos = x: thang.pos.x, y: thang.pos.y
|
||||||
lastAction = action.name
|
lastAction = action.name
|
||||||
|
|
|
@ -18,19 +18,6 @@ module.exports = class ThangType extends CocoModel
|
||||||
resetRawData: ->
|
resetRawData: ->
|
||||||
@set('raw', {shapes:{}, containers:{}, animations:{}})
|
@set('raw', {shapes:{}, containers:{}, animations:{}})
|
||||||
|
|
||||||
requiredRawAnimations: ->
|
|
||||||
required = []
|
|
||||||
for name, action of @get('actions')
|
|
||||||
continue if name is 'portrait'
|
|
||||||
allActions = [action].concat(_.values (action.relatedActions ? {}))
|
|
||||||
for a in allActions when a.animation
|
|
||||||
scale = if name is 'portrait' then a.scale or 1 else a.scale or @get('scale') or 1
|
|
||||||
animation = {animation: a.animation, scale: scale}
|
|
||||||
animation.portrait = name is 'portrait'
|
|
||||||
unless _.find(required, (r) -> _.isEqual r, animation)
|
|
||||||
required.push animation
|
|
||||||
required
|
|
||||||
|
|
||||||
resetSpriteSheetCache: ->
|
resetSpriteSheetCache: ->
|
||||||
@buildActions()
|
@buildActions()
|
||||||
@spriteSheets = {}
|
@spriteSheets = {}
|
||||||
|
@ -87,8 +74,7 @@ module.exports = class ThangType extends CocoModel
|
||||||
mc.nominalBounds = mc.frameBounds = null # override what the movie clip says on bounding
|
mc.nominalBounds = mc.frameBounds = null # override what the movie clip says on bounding
|
||||||
@builder.addMovieClip(mc, rect, scale)
|
@builder.addMovieClip(mc, rect, scale)
|
||||||
frames = @builder._animations[portrait.animation].frames
|
frames = @builder._animations[portrait.animation].frames
|
||||||
frames = @normalizeFrames(portrait.frames, frames[0]) if portrait.frames?
|
frames = @mapFrames(portrait.frames, frames[0]) if portrait.frames?
|
||||||
portrait.frames = frames
|
|
||||||
@builder.addAnimation 'portrait', frames, true
|
@builder.addAnimation 'portrait', frames, true
|
||||||
else if portrait.container
|
else if portrait.container
|
||||||
s = @vectorParser.buildContainerFromStore(portrait.container)
|
s = @vectorParser.buildContainerFromStore(portrait.container)
|
||||||
|
@ -108,7 +94,6 @@ module.exports = class ThangType extends CocoModel
|
||||||
scale = action.scale ? @get('scale') ? 1
|
scale = action.scale ? @get('scale') ? 1
|
||||||
frames = framesMap[scale + "_" + action.animation]
|
frames = framesMap[scale + "_" + action.animation]
|
||||||
frames = @mapFrames(action.frames, frames[0]) if action.frames?
|
frames = @mapFrames(action.frames, frames[0]) if action.frames?
|
||||||
action.frames = frames # Keep generated frame numbers around
|
|
||||||
next = true
|
next = true
|
||||||
next = action.goesTo if action.goesTo
|
next = action.goesTo if action.goesTo
|
||||||
next = false if action.loops is false
|
next = false if action.loops is false
|
||||||
|
@ -120,7 +105,20 @@ module.exports = class ThangType extends CocoModel
|
||||||
s = @vectorParser.buildContainerFromStore(action.container)
|
s = @vectorParser.buildContainerFromStore(action.container)
|
||||||
frame = @builder.addFrame(s, s.bounds, scale)
|
frame = @builder.addFrame(s, s.bounds, scale)
|
||||||
@builder.addAnimation name, [frame], false
|
@builder.addAnimation name, [frame], false
|
||||||
|
|
||||||
|
requiredRawAnimations: ->
|
||||||
|
required = []
|
||||||
|
for name, action of @get('actions')
|
||||||
|
continue if name is 'portrait'
|
||||||
|
allActions = [action].concat(_.values (action.relatedActions ? {}))
|
||||||
|
for a in allActions when a.animation
|
||||||
|
scale = if name is 'portrait' then a.scale or 1 else a.scale or @get('scale') or 1
|
||||||
|
animation = {animation: a.animation, scale: scale}
|
||||||
|
animation.portrait = name is 'portrait'
|
||||||
|
unless _.find(required, (r) -> _.isEqual r, animation)
|
||||||
|
required.push animation
|
||||||
|
required
|
||||||
|
|
||||||
mapFrames: (frames, frameOffset) ->
|
mapFrames: (frames, frameOffset) ->
|
||||||
return frames unless _.isString(frames) # don't accidentally do this again
|
return frames unless _.isString(frames) # don't accidentally do this again
|
||||||
(parseInt(f, 10) + frameOffset for f in frames.split(','))
|
(parseInt(f, 10) + frameOffset for f in frames.split(','))
|
||||||
|
@ -148,11 +146,16 @@ module.exports = class ThangType extends CocoModel
|
||||||
|
|
||||||
getPortraitImage: (spriteOptionsOrKey, size=100) ->
|
getPortraitImage: (spriteOptionsOrKey, size=100) ->
|
||||||
src = @getPortraitSource(spriteOptionsOrKey, size)
|
src = @getPortraitSource(spriteOptionsOrKey, size)
|
||||||
|
return null unless src
|
||||||
$('<img />').attr('src', src)
|
$('<img />').attr('src', src)
|
||||||
|
|
||||||
getPortraitSource: (spriteOptionsOrKey, size=100) ->
|
getPortraitSource: (spriteOptionsOrKey, size=100) ->
|
||||||
|
stage = @getPortraitStage(spriteOptionsOrKey, size)
|
||||||
|
stage?.toDataURL()
|
||||||
|
|
||||||
|
getPortraitStage: (spriteOptionsOrKey, size=100) ->
|
||||||
key = spriteOptionsOrKey
|
key = spriteOptionsOrKey
|
||||||
key = if _.isObject(key) then @spriteSheetKey(key) else key
|
key = if _.isString(key) then key else @spriteSheetKey(@fillOptions(key))
|
||||||
spriteSheet = @spriteSheets[key]
|
spriteSheet = @spriteSheets[key]
|
||||||
spriteSheet ?= @buildSpriteSheet({portraitOnly:true})
|
spriteSheet ?= @buildSpriteSheet({portraitOnly:true})
|
||||||
return unless spriteSheet
|
return unless spriteSheet
|
||||||
|
@ -165,11 +168,21 @@ module.exports = class ThangType extends CocoModel
|
||||||
sprite.gotoAndStop 'portrait'
|
sprite.gotoAndStop 'portrait'
|
||||||
stage.addChild(sprite)
|
stage.addChild(sprite)
|
||||||
stage.update()
|
stage.update()
|
||||||
stage.toDataURL()
|
stage.startTalking = ->
|
||||||
|
sprite.gotoAndPlay 'portrait'
|
||||||
|
return if @tick
|
||||||
|
@tick = => @update()
|
||||||
|
createjs.Ticker.addEventListener 'tick', @tick
|
||||||
|
stage.stopTalking = ->
|
||||||
|
sprite.gotoAndStop 'portrait'
|
||||||
|
@update()
|
||||||
|
createjs.Ticker.removeEventListener 'tick', @tick
|
||||||
|
@tick = null
|
||||||
|
stage
|
||||||
|
|
||||||
uploadGenericPortrait: (callback) ->
|
uploadGenericPortrait: (callback) ->
|
||||||
src = @getPortraitSource()
|
src = @getPortraitSource()
|
||||||
return unless src
|
return callback?() unless src
|
||||||
src = src.replace('data:image/png;base64,', '').replace(/\ /g, '+')
|
src = src.replace('data:image/png;base64,', '').replace(/\ /g, '+')
|
||||||
body =
|
body =
|
||||||
filename: 'portrait.png'
|
filename: 'portrait.png'
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
.no-selection-message
|
.no-selection-message
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
.thang-image-wrapper, .speaker-image-wrapper
|
.thang-canvas-wrapper, .speaker-image-wrapper
|
||||||
width: 100px
|
width: 100px
|
||||||
height: 100px
|
height: 100px
|
||||||
border: 1px solid darkred
|
border: 1px solid darkred
|
||||||
|
@ -71,9 +71,11 @@
|
||||||
|
|
||||||
&.team-humans
|
&.team-humans
|
||||||
border-color: darkred
|
border-color: darkred
|
||||||
|
background-color: rgba(255,100,100,0.5)
|
||||||
|
|
||||||
&.team-ogres
|
&.team-ogres
|
||||||
border-color: darkblue
|
border-color: darkblue
|
||||||
|
background-color: rgba(100,100,255,0.5)
|
||||||
|
|
||||||
.thang-props
|
.thang-props
|
||||||
width: 144px
|
width: 144px
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
.center
|
.center
|
||||||
|
|
||||||
.thang-image-wrapper.thang-elem
|
.thang-canvas-wrapper.thang-elem
|
||||||
img.thang-image
|
canvas.thang-canvas
|
||||||
|
|
||||||
.thang-props.thang-elem
|
.thang-props.thang-elem
|
||||||
.thang-name
|
.thang-name
|
||||||
|
@ -17,9 +17,6 @@
|
||||||
tbody
|
tbody
|
||||||
|
|
||||||
.dialogue-area
|
.dialogue-area
|
||||||
.speaker-image-wrapper
|
|
||||||
canvas.thang-canvas(width=100, height=100)
|
|
||||||
img.speaker-image
|
|
||||||
p.bubble.dialogue-bubble
|
p.bubble.dialogue-bubble
|
||||||
|
|
||||||
.no-selection-message
|
.no-selection-message
|
||||||
|
|
|
@ -166,7 +166,7 @@ module.exports = class ThangTypeEditView extends View
|
||||||
@file = e.target.files[0]
|
@file = e.target.files[0]
|
||||||
return unless @file
|
return unless @file
|
||||||
return unless @file.type is 'text/javascript'
|
return unless @file.type is 'text/javascript'
|
||||||
@$el.find('#upload-button').prop('disabled', true)
|
# @$el.find('#upload-button').prop('disabled', true)
|
||||||
@reader = new FileReader()
|
@reader = new FileReader()
|
||||||
@reader.onload = @onFileLoad
|
@reader.onload = @onFileLoad
|
||||||
@reader.readAsText(@file)
|
@reader.readAsText(@file)
|
||||||
|
@ -301,7 +301,7 @@ module.exports = class ThangTypeEditView extends View
|
||||||
|
|
||||||
res.success =>
|
res.success =>
|
||||||
url = "/editor/thang/#{newThangType.get('slug') or newThangType.id}"
|
url = "/editor/thang/#{newThangType.get('slug') or newThangType.id}"
|
||||||
newThangType.uploadGenericPortrait =>
|
newThangType.uploadGenericPortrait ->
|
||||||
document.location.href = url
|
document.location.href = url
|
||||||
|
|
||||||
clearRawData: ->
|
clearRawData: ->
|
||||||
|
|
|
@ -10,26 +10,26 @@ module.exports = class HUDView extends View
|
||||||
template: template
|
template: template
|
||||||
dialogueMode: false
|
dialogueMode: false
|
||||||
|
|
||||||
constructor: (options) ->
|
|
||||||
@thangIDMap = {}
|
|
||||||
super options
|
|
||||||
|
|
||||||
subscriptions:
|
subscriptions:
|
||||||
'surface:frame-changed': 'onFrameChanged'
|
'surface:frame-changed': 'onFrameChanged'
|
||||||
|
'level-disable-controls': 'onDisableControls'
|
||||||
|
'level-enable-controls': 'onEnableControls'
|
||||||
'surface:sprite-selected': 'onSpriteSelected'
|
'surface:sprite-selected': 'onSpriteSelected'
|
||||||
'sprite:speech-updated': 'onSpriteDialogue'
|
'sprite:speech-updated': 'onSpriteDialogue'
|
||||||
'level-sprite-clear-dialogue': 'onSpriteClearDialogue'
|
'level-sprite-clear-dialogue': 'onSpriteClearDialogue'
|
||||||
'level-disable-controls': 'onDisableControls'
|
|
||||||
'level-enable-controls': 'onEnableControls'
|
|
||||||
'level:shift-space-pressed': 'onShiftSpacePressed'
|
'level:shift-space-pressed': 'onShiftSpacePressed'
|
||||||
'level:escape-pressed': 'onEscapePressed'
|
'level:escape-pressed': 'onEscapePressed'
|
||||||
'god:new-world-created': 'onNewWorldCreated'
|
|
||||||
'surface:ticked': 'onTick'
|
|
||||||
'dialogue-sound-completed': 'onDialogueSoundCompleted'
|
'dialogue-sound-completed': 'onDialogueSoundCompleted'
|
||||||
|
'thang-began-talking': 'onThangBeganTalking'
|
||||||
|
'thang-finished-talking': 'onThangFinishedTalking'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click': -> Backbone.Mediator.publish 'focus-editor'
|
'click': -> Backbone.Mediator.publish 'focus-editor'
|
||||||
|
|
||||||
|
afterRender: =>
|
||||||
|
super()
|
||||||
|
@$el.addClass 'no-selection'
|
||||||
|
|
||||||
onFrameChanged: (e) ->
|
onFrameChanged: (e) ->
|
||||||
@timeProgress = e.progress
|
@timeProgress = e.progress
|
||||||
@update()
|
@update()
|
||||||
|
@ -42,100 +42,83 @@ module.exports = class HUDView extends View
|
||||||
return if e.controls and not ('hud' in e.controls)
|
return if e.controls and not ('hud' in e.controls)
|
||||||
@disabled = false
|
@disabled = false
|
||||||
|
|
||||||
onNewWorldCreated: (e) ->
|
|
||||||
@thangIDMap = {}
|
|
||||||
for thang in e.world.thangs
|
|
||||||
if @thang?.id is thang.id
|
|
||||||
#console.log('HUD updated thang for', thang.id)
|
|
||||||
@thang = thang
|
|
||||||
@createActions()
|
|
||||||
@thangIDMap[thang.id] = thang.spriteName
|
|
||||||
|
|
||||||
onSpriteSelected: (e) ->
|
onSpriteSelected: (e) ->
|
||||||
# TODO: this allows the surface and HUD selection to get out of sync if we select another unit while in dialogue mode
|
# TODO: this allows the surface and HUD selection to get out of sync if we select another unit while in dialogue mode
|
||||||
return if @disabled or @dialogueMode
|
return if @disabled or @dialogueMode
|
||||||
@switchToThangElements()
|
@switchToThangElements()
|
||||||
@setThang e.thang
|
@setThang e.thang, e.sprite?.thangType
|
||||||
|
|
||||||
onSpriteDialogue: (e) ->
|
onSpriteDialogue: (e) ->
|
||||||
return unless e.message
|
return unless e.message
|
||||||
spriteID = e.sprite.thang.id
|
spriteID = e.sprite.thang.id
|
||||||
spriteName = e.sprite.thangType?.get('name') or e.sprite.thang.spriteName
|
@setSpeaker e.sprite
|
||||||
@setSpeaker spriteID, spriteName
|
@stage?.startTalking()
|
||||||
@startAnimation spriteID
|
|
||||||
@setMessage(e.message, e.mood, e.responses)
|
@setMessage(e.message, e.mood, e.responses)
|
||||||
window.tracker?.trackEvent 'Heard Sprite', {speaker: spriteID, message: e.message, label: e.message}, ['Google Analytics']
|
window.tracker?.trackEvent 'Heard Sprite', {speaker: spriteID, message: e.message, label: e.message}, ['Google Analytics']
|
||||||
|
|
||||||
startAnimation: (spriteID) =>
|
|
||||||
@speakerStage.removeAllChildren()
|
|
||||||
|
|
||||||
#spriteData = spriteMap.dataForThang(spriteID)
|
|
||||||
spriteData = null # we deleted SpriteMap, but haven't refactored to use vector animated portraits yet
|
|
||||||
|
|
||||||
canvas = $('canvas', @$el)
|
|
||||||
image = $('.speaker-image', @$el)
|
|
||||||
if spriteData?.sprite_data?.animations.portrait
|
|
||||||
image.hide()
|
|
||||||
canvas.show()
|
|
||||||
else
|
|
||||||
image.show()
|
|
||||||
canvas.hide()
|
|
||||||
return
|
|
||||||
|
|
||||||
onDialogueSoundCompleted: ->
|
onDialogueSoundCompleted: ->
|
||||||
return unless @portraitSprite
|
@stage?.stopTalking()
|
||||||
@portraitSprite.gotoAndPlay('portrait_idle')
|
|
||||||
|
|
||||||
onTick: ->
|
|
||||||
@speakerStage.update()
|
|
||||||
|
|
||||||
onSpriteClearDialogue: ->
|
onSpriteClearDialogue: ->
|
||||||
@clearSpeaker()
|
@clearSpeaker()
|
||||||
|
|
||||||
afterRender: =>
|
setThang: (thang, thangType) ->
|
||||||
super()
|
|
||||||
@$el.addClass 'no-selection'
|
|
||||||
@speakerStage = new createjs.Stage($('canvas', @$el)[0])
|
|
||||||
|
|
||||||
setThang: (thang) ->
|
|
||||||
unless @speaker
|
unless @speaker
|
||||||
if not thang? and not @thang? then return
|
if not thang? and not @thang? then return
|
||||||
if thang? and @thang? and thang.id is @thang.id then return
|
if thang? and @thang? and thang.id is @thang.id then return
|
||||||
|
|
||||||
@thang = thang
|
@thang = thang
|
||||||
|
@thangType = thangType
|
||||||
@$el.toggleClass 'no-selection', not @thang?
|
@$el.toggleClass 'no-selection', not @thang?
|
||||||
clearTimeout @hintNextSelectionTimeout
|
clearTimeout @hintNextSelectionTimeout
|
||||||
@$el.find('.no-selection-message').hide()
|
@$el.find('.no-selection-message').hide()
|
||||||
if not @thang
|
if not @thang
|
||||||
@hintNextSelectionTimeout = _.delay((=> @$el.find('.no-selection-message').slideDown('slow')), 10000)
|
@hintNextSelectionTimeout = _.delay((=> @$el.find('.no-selection-message').slideDown('slow')), 10000)
|
||||||
return
|
return
|
||||||
@createAvatar @thang.id, @sprite
|
@createAvatar thangType
|
||||||
@createProperties()
|
@createProperties()
|
||||||
@createActions()
|
@createActions()
|
||||||
@update()
|
@update()
|
||||||
@speaker = null
|
@speaker = null
|
||||||
|
|
||||||
setSpeaker: (speaker, speakerType) ->
|
setSpeaker: (speakerSprite) ->
|
||||||
return if speaker is @speaker
|
return if speakerSprite is @speakerSprite
|
||||||
image = @$el.find '.speaker-image'
|
@speakerSprite = speakerSprite
|
||||||
spriteUtils.createAvatar @thangIDMap[speakerType] or speakerType, image
|
@speaker = @speakerSprite.thang.id
|
||||||
@speaker = speaker
|
@createAvatar @speakerSprite.thangType
|
||||||
@$el.removeClass 'no-selection'
|
@$el.removeClass 'no-selection'
|
||||||
@switchToDialogueElements()
|
@switchToDialogueElements()
|
||||||
|
|
||||||
clearSpeaker: ->
|
clearSpeaker: ->
|
||||||
if not @thang
|
if not @thang
|
||||||
@$el.addClass 'no-selection'
|
@$el.addClass 'no-selection'
|
||||||
#console.log "clearSpeaker and have thang", @thang
|
|
||||||
@setThang @thang
|
@setThang @thang
|
||||||
@switchToThangElements()
|
@switchToThangElements()
|
||||||
@speaker = null
|
@speaker = null
|
||||||
|
@speakerSprite = null
|
||||||
@bubble = null
|
@bubble = null
|
||||||
@update()
|
@update()
|
||||||
|
|
||||||
createAvatar: (id) ->
|
createAvatar: (thangType) ->
|
||||||
image = @$el.find '.thang-image'
|
stage = thangType.getPortraitStage()
|
||||||
spriteUtils.createAvatar @thangIDMap[id] or id, image
|
wrapper = @$el.find '.thang-canvas-wrapper'
|
||||||
image.attr('title', id).parent().removeClass('team-ogres').removeClass('team-humans').addClass('team-' + @thang.team)
|
newCanvas = $(stage.canvas).addClass('thang-canvas')
|
||||||
|
wrapper.empty().append(newCanvas)
|
||||||
|
team = @thang?.team or @speakerSprite?.thang?.team
|
||||||
|
newCanvas.parent().removeClass('team-ogres').removeClass('team-humans').addClass("team-#{team}")
|
||||||
|
stage.update()
|
||||||
|
@stage?.stopTalking()
|
||||||
|
@stage = stage
|
||||||
|
f = => console.log 'new canvas style timeout', newCanvas.attr 'style'
|
||||||
|
setTimeout f, 1000
|
||||||
|
|
||||||
|
onThangBeganTalking: (e) ->
|
||||||
|
return unless @stage and @thang is e.thang
|
||||||
|
@stage?.startTalking()
|
||||||
|
|
||||||
|
onThangFinishedTalking: (e) ->
|
||||||
|
return unless @stage and @thang is e.thang
|
||||||
|
@stage?.stopTalking()
|
||||||
|
|
||||||
createProperties: ->
|
createProperties: ->
|
||||||
props = @$el.find('.thang-props')
|
props = @$el.find('.thang-props')
|
||||||
|
@ -219,6 +202,7 @@ module.exports = class HUDView extends View
|
||||||
switchToDialogueElements: ->
|
switchToDialogueElements: ->
|
||||||
@dialogueMode = true
|
@dialogueMode = true
|
||||||
$('.thang-elem', @$el).addClass('hide')
|
$('.thang-elem', @$el).addClass('hide')
|
||||||
|
@$el.find('.thang-canvas-wrapper').removeClass('hide')
|
||||||
$('.dialogue-area', @$el)
|
$('.dialogue-area', @$el)
|
||||||
.removeClass('hide')
|
.removeClass('hide')
|
||||||
.animate({opacity:1.0}, 200)
|
.animate({opacity:1.0}, 200)
|
||||||
|
@ -235,11 +219,8 @@ module.exports = class HUDView extends View
|
||||||
|
|
||||||
update: ->
|
update: ->
|
||||||
return unless @thang and not @speaker
|
return unless @thang and not @speaker
|
||||||
# Update avatar?
|
|
||||||
|
|
||||||
# Update properties
|
# Update properties
|
||||||
@updatePropElement(prop, @thang[prop]) for prop in @thang.hudProperties ? []
|
@updatePropElement(prop, @thang[prop]) for prop in @thang.hudProperties ? []
|
||||||
|
|
||||||
# Update action timeline
|
# Update action timeline
|
||||||
@updateActions()
|
@updateActions()
|
||||||
|
|
||||||
|
@ -343,3 +324,7 @@ module.exports = class HUDView extends View
|
||||||
timeline.append bar
|
timeline.append bar
|
||||||
|
|
||||||
ael
|
ael
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
super()
|
||||||
|
@stage?.stopTalking()
|
||||||
|
|
|
@ -119,6 +119,7 @@ checkExistence = (options, res, force, done) ->
|
||||||
returnConflict(res)
|
returnConflict(res)
|
||||||
done(true)
|
done(true)
|
||||||
else if files.length
|
else if files.length
|
||||||
|
q = { _id: files[0]._id }
|
||||||
q.root = 'media'
|
q.root = 'media'
|
||||||
Grid.gfs.remove q, (err) ->
|
Grid.gfs.remove q, (err) ->
|
||||||
return returnServerError(res) if err
|
return returnServerError(res) if err
|
||||||
|
|
Reference in a new issue