2014-01-03 13:32:13 -05:00
CocoClass = require ' lib/CocoClass '
{ me } = require ' lib/auth '
2014-09-19 18:46:02 -04:00
LayerAdapter = require ' ./LayerAdapter '
2014-01-03 13:32:13 -05:00
IndieSprite = require ' lib/surface/IndieSprite '
WizardSprite = require ' lib/surface/WizardSprite '
2014-08-24 19:09:06 -04:00
FlagSprite = require ' lib/surface/FlagSprite '
2014-01-03 13:32:13 -05:00
CocoSprite = require ' lib/surface/CocoSprite '
Mark = require ' ./Mark '
Grid = require ' lib/world/Grid '
module.exports = class SpriteBoss extends CocoClass
subscriptions:
' bus:player-joined ' : ' onPlayerJoined '
' bus:player-left ' : ' onPlayerLeft '
2014-08-27 15:24:03 -04:00
' level:set-debug ' : ' onSetDebug '
' sprite:highlight-sprites ' : ' onHighlightSprites '
2014-01-03 13:32:13 -05:00
' surface:stage-mouse-down ' : ' onStageMouseDown '
2014-08-27 15:24:03 -04:00
' level:select-sprite ' : ' onSelectSprite '
' level:suppress-selection-sounds ' : ' onSuppressSelectionSounds '
' level:lock-select ' : ' onSetLockSelect '
2014-01-03 13:32:13 -05:00
' level:restarted ' : ' onLevelRestarted '
2014-02-06 17:00:27 -05:00
' god:new-world-created ' : ' onNewWorld '
2014-08-21 19:27:52 -04:00
' god:streaming-world-updated ' : ' onNewWorld '
2014-02-24 22:49:05 -05:00
' camera:dragged ' : ' onCameraDragged '
2014-03-12 13:08:57 -04:00
' sprite:loaded ' : -> @ update ( true )
2014-08-24 19:09:06 -04:00
' level:flag-color-selected ' : ' onFlagColorSelected '
' level:flag-updated ' : ' onFlagUpdated '
' surface:flag-appeared ' : ' onFlagAppeared '
' surface:remove-selected-flag ' : ' onRemoveSelectedFlag '
2014-01-03 13:32:13 -05:00
constructor: (@options) ->
super ( )
2014-02-26 21:42:39 -05:00
@dragged = 0
2014-01-03 13:32:13 -05:00
@ options ? = { }
@camera = @ options . camera
@surfaceLayer = @ options . surfaceLayer
@surfaceTextLayer = @ options . surfaceTextLayer
@world = options . world
@ options . thangTypes ? = [ ]
@sprites = { }
2014-04-28 19:31:51 -04:00
@spriteArray = [ ] # Mirror @sprites, but faster for when we just need to iterate
2014-01-03 13:32:13 -05:00
@selfWizardSprite = null
@ createLayers ( )
2014-08-24 19:09:06 -04:00
@pendingFlags = [ ]
2014-01-03 13:32:13 -05:00
destroy: ->
2014-04-28 20:06:43 -04:00
@ removeSprite sprite for thangID , sprite of @ sprites
2014-01-03 13:32:13 -05:00
@ targetMark ? . destroy ( )
@ selectionMark ? . destroy ( )
2014-02-14 13:57:47 -05:00
super ( )
2014-01-03 13:32:13 -05:00
2014-04-28 19:31:51 -04:00
toString: -> " <SpriteBoss: #{ @ spriteArray . length } sprites> "
2014-01-03 13:32:13 -05:00
thangTypeFor: (type) ->
2014-05-16 20:18:56 -04:00
_ . find @ options . thangTypes , (m) -> m . get ( ' original ' ) is type or m . get ( ' name ' ) is type
2014-01-03 13:32:13 -05:00
createLayers: ->
@spriteLayers = { }
for [ name , priority ] in [
2014-06-30 22:16:26 -04:00
[ ' Land ' , - 40 ]
[ ' Ground ' , - 30 ]
[ ' Obstacle ' , - 20 ]
[ ' Path ' , - 10 ]
[ ' Default ' , 0 ]
[ ' Floating ' , 10 ]
2014-01-03 13:32:13 -05:00
]
2014-09-19 18:46:02 -04:00
@ spriteLayers [ name ] = new LayerAdapter name: name , webGL: true , layerPriority: priority , transform: LayerAdapter . TRANSFORM_CHILD , camera: @ camera
@ surfaceLayer . addChild ( spriteLayer . container for spriteLayer in _ . values ( @ spriteLayers ) ) . . .
2014-01-03 13:32:13 -05:00
layerForChild: (child, sprite) ->
unless child . layerPriority ?
2014-08-19 22:21:36 -04:00
if thang = sprite ? . thang
child.layerPriority = thang . layerPriority
child . layerPriority ? = 0 if thang . isSelectable
child . layerPriority ? = - 40 if thang . isLand
2014-08-20 21:57:26 -04:00
child . layerPriority ? = 0
2014-06-30 22:16:26 -04:00
return @ spriteLayers [ ' Default ' ] unless child . layerPriority
2014-01-03 13:32:13 -05:00
layer = _ . findLast @ spriteLayers , (layer, name) ->
2014-09-19 18:46:02 -04:00
layer . layerPriority <= child . layerPriority
2014-08-19 22:21:36 -04:00
layer ? = @ spriteLayers [ ' Land ' ] if child . layerPriority < - 40
2014-06-30 22:16:26 -04:00
layer ? @ spriteLayers [ ' Default ' ]
2014-01-03 13:32:13 -05:00
addSprite: (sprite, id=null, layer=null) ->
id ? = sprite . thang . id
2014-06-30 22:16:26 -04:00
console . error ' Sprite collision! Already have: ' , id if @ sprites [ id ]
2014-01-03 13:32:13 -05:00
@ sprites [ id ] = sprite
2014-04-28 19:31:51 -04:00
@ spriteArray . push sprite
2014-06-30 22:16:26 -04:00
layer ? = @ spriteLayers [ ' Obstacle ' ] if sprite . thang ? . spriteName . search ( /(dungeon|indoor).wall/i ) isnt - 1
2014-05-14 18:59:56 -04:00
layer ? = @ layerForChild sprite . imageObject , sprite
2014-09-17 18:47:25 -04:00
layer . addCocoSprite sprite
2014-09-19 18:46:02 -04:00
layer . updateLayerOrder ( )
2014-01-03 13:32:13 -05:00
sprite
createMarks: ->
2014-09-17 18:47:25 -04:00
return # TODO: get these marks working again
2014-06-30 22:16:26 -04:00
@targetMark = new Mark name: ' target ' , camera: @ camera , layer: @ spriteLayers [ ' Ground ' ] , thangType: ' target '
@selectionMark = new Mark name: ' selection ' , camera: @ camera , layer: @ spriteLayers [ ' Ground ' ] , thangType: ' selection '
2014-01-03 13:32:13 -05:00
createSpriteOptions: (options) ->
2014-09-24 15:08:55 -04:00
_ . extend options , camera: @ camera , resolutionFactor: SPRITE_RESOLUTION_FACTOR , groundLayer: @ spriteLayers [ ' Ground ' ] , textLayer: @ surfaceTextLayer , floatingLayer: @ spriteLayers [ ' Floating ' ] , showInvisible: @ options . showInvisible
2014-01-03 13:32:13 -05:00
createIndieSprites: (indieSprites, withWizards) ->
unless @ indieSprites
2014-01-06 20:11:57 -05:00
@indieSprites = [ ]
@indieSprites = ( @ createIndieSprite indieSprite for indieSprite in indieSprites ) if indieSprites
2014-05-01 17:36:26 -04:00
if withWizards and not @ selfWizardSprite
2014-06-30 22:16:26 -04:00
@selfWizardSprite = @ createWizardSprite thangID: ' My Wizard ' , isSelf: true , sprites: @ sprites
2014-01-03 13:32:13 -05:00
createIndieSprite: (indieSprite) ->
unless thangType = @ thangTypeFor indieSprite . thangType
console . warn " Need to convert #{ indieSprite . id } ' s ThangType #{ indieSprite . thangType } to a ThangType reference. Until then, #{ indieSprite . id } won ' t show up. "
return
2014-08-26 15:39:30 -04:00
sprite = new IndieSprite thangType , @ createSpriteOptions { thangID: indieSprite . id , pos: indieSprite . pos , sprites: @ sprites , team: indieSprite . team , teamColors: @ world . getTeamColors ( ) }
2014-01-03 13:32:13 -05:00
@ addSprite sprite , sprite . thang . id
2014-02-22 15:01:05 -05:00
createOpponentWizard: (opponent) ->
# TODO: colorize name and cloud by team, colorize wizard by user's color config, level-specific wizard spawn points
2014-07-13 23:19:51 -04:00
sprite = @ createWizardSprite thangID: opponent . id , name: opponent . name , codeLanguage: opponent . codeLanguage
2014-06-30 22:16:26 -04:00
if not opponent . levelSlug or opponent . levelSlug is ' brawlwood '
2014-03-14 19:14:35 -04:00
sprite.targetPos = if opponent . team is ' ogres ' then { x: 52 , y: 52 } else { x: 28 , y: 28 }
2014-08-24 15:33:46 -04:00
else if opponent . levelSlug in [ ' dungeon-arena ' , ' sky-span ' ]
2014-06-30 22:16:26 -04:00
sprite.targetPos = if opponent . team is ' ogres ' then { x: 72 , y: 39 } else { x: 9 , y: 39 }
2014-07-08 21:51:10 -04:00
else if opponent . levelSlug is ' criss-cross '
sprite.targetPos = if opponent . team is ' ogres ' then { x: 50 , y: 12 } else { x: 0 , y: 40 }
2014-03-14 19:14:35 -04:00
else
2014-06-30 22:16:26 -04:00
sprite.targetPos = if opponent . team is ' ogres ' then { x: 52 , y: 28 } else { x: 20 , y: 28 }
2014-03-14 20:15:07 -04:00
2014-01-03 13:32:13 -05:00
createWizardSprite: (options) ->
2014-06-30 22:16:26 -04:00
sprite = new WizardSprite @ thangTypeFor ( ' Wizard ' ) , @ createSpriteOptions ( options )
@ addSprite sprite , sprite . thang . id , @ spriteLayers [ ' Floating ' ]
2014-01-03 13:32:13 -05:00
onPlayerJoined: (e) ->
# Create another WizardSprite, unless this player is just me
pid = e . player . id
return if pid is me . id
wiz = @ createWizardSprite thangID: pid , sprites: @ sprites
wiz . animateIn ( )
state = e . player . wizard or { }
wiz . setInitialState ( state . targetPos , @ sprites [ state . targetSprite ] )
onPlayerLeft: (e) ->
pid = e . player . id
@ sprites [ pid ] ? . animateOut => @ removeSprite @ sprites [ pid ]
onSetDebug: (e) ->
return if e . debug is @ debug
@debug = e . debug
2014-04-28 19:31:51 -04:00
sprite . setDebug @ debug for sprite in @ spriteArray
2014-01-03 13:32:13 -05:00
onHighlightSprites: (e) ->
highlightedIDs = e . thangIDs or [ ]
for thangID , sprite of @ sprites
sprite . setHighlight ? thangID in highlightedIDs , e . delay
addThangToSprites: (thang, layer=null) ->
return console . warn ' Tried to add Thang to the surface it already has: ' , thang . id if @ sprites [ thang . id ]
2014-05-02 20:03:30 -04:00
thangType = _ . find @ options . thangTypes , (m) ->
return false unless m . get ( ' actions ' ) or m . get ( ' raster ' )
return m . get ( ' name ' ) is thang . spriteName
thangType ? = _ . find @ options . thangTypes , (m) -> return m . get ( ' name ' ) is thang . spriteName
2014-08-11 01:09:13 -04:00
return console . error " Couldn ' t find ThangType for " , thang unless thangType
2014-05-09 15:56:58 -04:00
2014-02-17 20:38:49 -05:00
options = @ createSpriteOptions thang: thang
2014-05-15 20:07:53 -04:00
options.resolutionFactor = if thangType . get ( ' kind ' ) is ' Floor ' then 2 else SPRITE_RESOLUTION_FACTOR
2014-02-17 20:38:49 -05:00
sprite = new CocoSprite thangType , options
2014-05-16 18:33:49 -04:00
@ listenTo sprite , ' sprite:mouse-up ' , @ onSpriteMouseUp
2014-01-03 13:32:13 -05:00
@ addSprite sprite , null , layer
sprite . setDebug @ debug
sprite
removeSprite: (sprite) ->
2014-09-18 13:03:13 -04:00
sprite . layer . removeCocoSprite ( sprite )
2014-03-13 18:35:28 -04:00
thang = sprite . thang
2014-01-03 13:32:13 -05:00
delete @ sprites [ sprite . thang . id ]
2014-04-28 19:31:51 -04:00
@ spriteArray . splice @ spriteArray . indexOf ( sprite ) , 1
2014-05-22 15:05:30 -04:00
@ stopListening sprite
2014-02-14 16:31:26 -05:00
sprite . destroy ( )
2014-03-13 18:35:28 -04:00
sprite.thang = thang # Keep around so that we know which thang the destroyed thang was for
2014-01-03 13:32:13 -05:00
updateSounds: ->
2014-04-28 19:31:51 -04:00
sprite . playSounds ( ) for sprite in @ spriteArray # hmm; doesn't work for sprites which we didn't add yet in adjustSpriteExistence
2014-01-03 13:32:13 -05:00
update: (frameChanged) ->
@ adjustSpriteExistence ( ) if frameChanged
2014-04-28 19:31:51 -04:00
sprite . update frameChanged for sprite in @ spriteArray
2014-01-03 13:32:13 -05:00
@ updateSelection ( )
2014-09-19 18:46:02 -04:00
@ spriteLayers [ ' Default ' ] . updateLayerOrder ( )
2014-01-03 13:32:13 -05:00
adjustSpriteExistence: ->
# Add anything new, remove anything old, update everything current
2014-09-16 20:31:00 -04:00
updatedObstacles = [ ]
2014-08-06 10:43:56 -04:00
itemsJustEquipped = [ ]
2014-08-11 14:04:38 -04:00
for thang in @ world . thangs when thang . exists and thang . pos
2014-08-11 19:15:46 -04:00
itemsJustEquipped = itemsJustEquipped . concat @ equipNewItems thang
2014-01-03 13:32:13 -05:00
if sprite = @ sprites [ thang . id ]
sprite . setThang thang # make sure Sprite has latest Thang
else
2014-01-29 13:14:12 -05:00
sprite = @ addThangToSprites ( thang )
2014-08-27 15:24:03 -04:00
Backbone . Mediator . publish ' surface:new-thang-added ' , thang: thang , sprite: sprite
2014-09-16 20:31:00 -04:00
updatedObstacles . push sprite if sprite . imageObject . parent is @ spriteLayers [ ' Obstacle ' ]
2014-01-03 13:32:13 -05:00
sprite . playSounds ( )
2014-08-06 10:43:56 -04:00
item . modifyStats ( ) for item in itemsJustEquipped
2014-01-03 13:32:13 -05:00
for thangID , sprite of @ sprites
missing = not ( sprite . notOfThisWorld or @ world . thangMap [ thangID ] ? . exists )
2014-06-30 22:16:26 -04:00
isObstacle = sprite . imageObject . parent is @ spriteLayers [ ' Obstacle ' ]
2014-09-16 20:31:00 -04:00
updatedObstacles . push sprite if isObstacle and ( missing or sprite . hasMoved )
2014-01-03 13:32:13 -05:00
sprite.hasMoved = false
@ removeSprite sprite if missing
2014-03-12 12:10:36 -04:00
2014-02-25 14:59:23 -05:00
# mainly for handling selecting thangs from session when the thang is not always in existence
if @ willSelectThang and @ sprites [ @ willSelectThang [ 0 ] ]
@ selectThang @ willSelectThang . . .
2014-01-03 13:32:13 -05:00
2014-08-11 19:15:46 -04:00
equipNewItems: (thang) ->
itemsJustEquipped = [ ]
if thang . equip and not thang . equipped
thang . equip ( ) # Pretty hacky, but needed since initialize may not be called if we're not running Systems.
itemsJustEquipped . push thang
if thang . inventoryIDs
# Even hackier: these items were only created/equipped during simulation, so we reequip here.
for slot , itemID of thang . inventoryIDs
item = @ world . getThangByID itemID
unless item . equipped
2014-08-27 21:05:18 -04:00
console . log thang . id , ' equipping ' , item , ' in ' , thang . slot , ' Surface-side, but it cannot equip? ' unless item . equip
2014-08-11 19:15:46 -04:00
item . equip ( )
itemsJustEquipped . push item
return itemsJustEquipped
2014-01-03 13:32:13 -05:00
spriteFor: (thangID) -> @ sprites [ thangID ]
2014-02-06 17:00:27 -05:00
onNewWorld: (e) ->
@world = @options.world = e . world
2014-03-12 12:10:36 -04:00
2014-02-25 20:14:39 -05:00
play: ->
2014-05-06 14:02:53 -04:00
sprite . play ( ) for sprite in @ spriteArray
2014-02-24 17:40:28 -05:00
@ selectionMark ? . play ( )
@ targetMark ? . play ( )
2014-03-12 12:10:36 -04:00
2014-02-25 20:14:39 -05:00
stop: ->
2014-05-06 14:02:53 -04:00
sprite . stop ( ) for sprite in @ spriteArray
2014-02-24 17:40:28 -05:00
@ selectionMark ? . stop ( )
@ targetMark ? . stop ( )
2014-02-06 17:00:27 -05:00
2014-01-03 13:32:13 -05:00
# Selection
onSuppressSelectionSounds: (e) -> @suppressSelectionSounds = e . suppress
onSetLockSelect: (e) -> @selectLocked = e . lock
onLevelRestarted: (e) ->
@selectLocked = false
@ selectSprite e , null
onSelectSprite: (e) ->
@ selectThang e . thangID , e . spellName
2014-02-24 22:49:05 -05:00
onCameraDragged: ->
2014-02-26 21:42:39 -05:00
@ dragged += 1
2014-02-24 22:49:05 -05:00
onSpriteMouseUp: (e) ->
2014-03-12 20:50:59 -04:00
return if key . shift #and @options.choosing
2014-02-26 21:42:39 -05:00
return @dragged = 0 if @ dragged > 3
@dragged = 0
2014-01-03 13:32:13 -05:00
sprite = if e . sprite ? . thang ? . isSelectable then e . sprite else null
2014-08-25 17:02:23 -04:00
return if @ flagCursorSprite and sprite ? . thangType . get ( ' name ' ) is ' Flag '
2014-01-03 13:32:13 -05:00
@ selectSprite e , sprite
onStageMouseDown: (e) ->
2014-03-12 20:50:59 -04:00
return if key . shift #and @options.choosing
2014-01-03 13:32:13 -05:00
@ selectSprite e if e . onBackground
2014-03-14 16:27:29 -04:00
selectThang: (thangID, spellName=null, treemaThangSelected = null) ->
2014-02-25 14:59:23 -05:00
return @willSelectThang = [ thangID , spellName ] unless @ sprites [ thangID ]
2014-03-14 16:27:29 -04:00
@ selectSprite null , @ sprites [ thangID ] , spellName , treemaThangSelected
2014-01-03 13:32:13 -05:00
2014-03-14 16:27:29 -04:00
selectSprite: (e, sprite=null, spellName=null, treemaThangSelected = null) ->
2014-01-03 13:32:13 -05:00
return if e and ( @ disabled or @ selectLocked ) # Ignore clicks for selection/panning/wizard movement while disabled or select is locked
worldPos = sprite ? . thang ? . pos
2014-08-28 12:27:42 -04:00
worldPos ? = @ camera . screenToWorld { x: e . originalEvent . rawX , y: e . originalEvent . rawY } if e ? . originalEvent
2014-06-10 18:09:56 -04:00
if worldPos and ( @ options . navigateToSelection or not sprite or treemaThangSelected ) and e ? . originalEvent ? . nativeEvent ? . which isnt 3
2014-05-14 18:59:56 -04:00
@ camera . zoomTo ( sprite ? . imageObject or @ camera . worldToSurface ( worldPos ) , @ camera . zoom , 1000 , true )
2014-01-03 13:32:13 -05:00
sprite = null if @ options . choosing # Don't select sprites while choosing
if sprite isnt @ selectedSprite
@ selectedSprite ? . selected = false
sprite ? . selected = true
@selectedSprite = sprite
2014-05-16 13:03:45 -04:00
alive = sprite and not ( sprite . thang . health < 0 )
2014-01-09 14:04:22 -05:00
2014-01-21 00:19:54 -05:00
Backbone . Mediator . publish ' surface:sprite-selected ' ,
2014-01-03 13:32:13 -05:00
thang: if sprite then sprite . thang else null
sprite: sprite
spellName: spellName ? e ? . spellName
originalEvent: e
worldPos: worldPos
2014-03-13 18:35:28 -04:00
@willSelectThang = null if sprite # Now that we've done a real selection, don't reselect some other Thang later.
2014-01-09 14:04:22 -05:00
if alive and not @ suppressSelectionSounds
instance = sprite . playSound ' selected '
2014-01-09 17:04:46 -05:00
if instance ? . playState is ' playSucceeded '
2014-08-27 15:24:03 -04:00
Backbone . Mediator . publish ' sprite:thang-began-talking ' , thang: sprite ? . thang
2014-01-09 14:04:22 -05:00
instance . addEventListener ' complete ' , ->
2014-08-27 15:24:03 -04:00
Backbone . Mediator . publish ' sprite:thang-finished-talking ' , thang: sprite ? . thang
2014-01-09 14:04:22 -05:00
2014-08-24 19:09:06 -04:00
onFlagColorSelected: (e) ->
@ removeSprite @ flagCursorSprite if @ flagCursorSprite
@flagCursorSprite = null
2014-08-25 17:02:23 -04:00
for flagSprite in @ spriteArray when flagSprite . thangType . get ( ' name ' ) is ' Flag '
flagSprite.imageObject.cursor = if e . color then ' crosshair ' else ' pointer '
2014-08-24 19:09:06 -04:00
return unless e . color
@flagCursorSprite = new FlagSprite @ thangTypeFor ( ' Flag ' ) , @ createSpriteOptions ( thangID: ' Flag Cursor ' , color: e . color , team: me . team , isCursor: true , pos: e . pos )
@ addSprite @ flagCursorSprite , @ flagCursorSprite . thang . id , @ spriteLayers [ ' Floating ' ]
onFlagUpdated: (e) ->
return unless e . active
2014-09-04 23:10:04 -04:00
pendingFlag = new FlagSprite @ thangTypeFor ( ' Flag ' ) , @ createSpriteOptions ( thangID: ' Pending Flag ' + Math . random ( ) , color: e . color , team: e . team , isCursor: false , pos: e . pos )
2014-08-24 19:09:06 -04:00
@ addSprite pendingFlag , pendingFlag . thang . id , @ spriteLayers [ ' Floating ' ]
@ pendingFlags . push pendingFlag
onFlagAppeared: (e) ->
# Remove the pending flag that matches this one's color/team/position, and any color/team matches placed earlier.
t1 = e . sprite . thang
pending = ( @ pendingFlags ? [ ] ) . slice ( )
foundExactMatch = false
for i in [ pending . length - 1 . . 0 ] by - 1
pendingFlag = pending [ i ]
t2 = pendingFlag . thang
matchedType = t1 . color is t2 . color and t1 . team is t2 . team
matched = matchedType and ( foundExactMatch or Math . abs ( t1 . pos . x - t2 . pos . x ) < 0.00001 and Math . abs ( t1 . pos . y - t2 . pos . y ) < 0.00001 )
if matched
foundExactMatch = true
@ pendingFlags . splice ( i , 1 )
@ removeSprite pendingFlag
2014-08-25 17:02:23 -04:00
e.sprite.imageObject.cursor = if @ flagCursorSprite then ' crosshair ' else ' pointer '
2014-08-24 19:09:06 -04:00
null
onRemoveSelectedFlag: (e) ->
2014-08-25 17:02:23 -04:00
# Remove the selected sprite if it's a flag, or any flag of the given color if a color is given.
flagSprite = _ . find [ @ selectedSprite ] . concat ( @ spriteArray ) , (sprite) ->
sprite and sprite . thangType . get ( ' name ' ) is ' Flag ' and sprite . thang . team is me . team and ( sprite . thang . color is e . color or not e . color ) and not sprite . notOfThisWorld
return unless flagSprite
Backbone . Mediator . publish ' surface:remove-flag ' , color: flagSprite . thang . color
2014-08-24 19:09:06 -04:00
2014-01-03 13:32:13 -05:00
# Marks
updateSelection: ->
2014-02-14 18:35:54 -05:00
if @ selectedSprite ? . thang and ( not @ selectedSprite . thang . exists or not @ world . getThangByID @ selectedSprite . thang . id )
2014-03-13 18:35:28 -04:00
thangID = @ selectedSprite . thang . id
@selectedSprite = null # Don't actually trigger deselection, but remove the selected sprite.
2014-02-16 21:29:24 -05:00
@ selectionMark ? . toggle false
2014-03-13 18:35:28 -04:00
@willSelectThang = [ thangID , null ]
2014-01-03 13:32:13 -05:00
@ updateTarget ( )
return unless @ selectionMark
2014-03-14 20:15:07 -04:00
@selectedSprite = null if @ selectedSprite and ( @ selectedSprite . destroyed or not @ selectedSprite . thang )
2014-08-28 17:25:37 -04:00
# The selection mark should be on the ground layer, unless we're not a normal sprite (like a wall), in which case we'll place it higher so we can see it.
if @ selectedSprite and @ selectedSprite . imageObject . parent isnt @ spriteLayers . Default
@ selectionMark . setLayer @ spriteLayers . Default
else if @ selectedSprite
@ selectionMark . setLayer @ spriteLayers . Ground
2014-01-03 13:32:13 -05:00
@ selectionMark . toggle @ selectedSprite ?
@ selectionMark . setSprite @ selectedSprite
@ selectionMark . update ( )
updateTarget: ->
return unless @ targetMark
thang = @ selectedSprite ? . thang
target = thang ? . target
targetPos = thang ? . targetPos
targetPos = null if targetPos ? . isZero ? ( ) # Null targetPos get serialized as (0, 0, 0)
@ targetMark . setSprite if target then @ sprites [ target . id ] else null
2014-01-21 12:03:04 -05:00
@ targetMark . toggle @ targetMark . sprite or targetPos
2014-01-03 13:32:13 -05:00
@ targetMark . update if targetPos then @ camera . worldToSurface targetPos else null