mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-14 07:00:01 -04:00
Remove code for multiple spells; rename SpellListTabEntryView to SpellTopBarView; remove hero avatar from SpellTopBarView
This commit is contained in:
parent
220db3106c
commit
e3670165e7
20 changed files with 78 additions and 593 deletions
|
@ -115,9 +115,7 @@ module.exports = class God extends CocoClass
|
|||
getUserCodeMap: (spells) ->
|
||||
userCodeMap = {}
|
||||
for spellKey, spell of spells
|
||||
for thangID, spellThang of spell.thangs
|
||||
continue if spellThang.thang?.programmableMethods[spell.name].cloneOf
|
||||
(userCodeMap[thangID] ?= {})[spell.name] = spellThang.aether.serialize()
|
||||
(userCodeMap[spell.thang.thang.id] ?= {})[spell.name] = spell.thang.aether.serialize()
|
||||
userCodeMap
|
||||
|
||||
|
||||
|
|
|
@ -481,9 +481,7 @@
|
|||
tome_cast_button_ran: "Ran"
|
||||
tome_submit_button: "Submit"
|
||||
tome_reload_method: "Reload original code for this method" # Title text for individual method reload button.
|
||||
tome_select_method: "Select a Method"
|
||||
tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methods).
|
||||
tome_select_a_thang: "Select Someone for "
|
||||
tome_available_spells: "Available Spells"
|
||||
tome_your_skills: "Your Skills"
|
||||
tome_current_method: "Current Method"
|
||||
|
|
|
@ -39,8 +39,6 @@ module.exports =
|
|||
variableChain: c.array {}, {type: 'string'}
|
||||
frame: {type: 'integer', minimum: 0}
|
||||
|
||||
'tome:toggle-spell-list': c.object {title: 'Toggle Spell List', description: 'Published when you toggle the dropdown for a thang\'s spells'}
|
||||
|
||||
'tome:reload-code': c.object {title: 'Reload Code', description: 'Published when you reset a spell to its original source', required: []},
|
||||
spell: {type: 'object'}
|
||||
|
||||
|
@ -91,10 +89,6 @@ module.exports =
|
|||
problems: {type: 'array'}
|
||||
isCast: {type: 'boolean'}
|
||||
|
||||
'tome:spell-shown': c.object {title: 'Spell Shown', description: 'Published when we show a spell', required: ['thang', 'spell']},
|
||||
thang: {type: 'object'}
|
||||
spell: {type: 'object'}
|
||||
|
||||
'tome:change-language': c.object {title: 'Tome Change Language', description: 'Published when the Tome should update its programming language', required: ['language']},
|
||||
language: {type: 'string'}
|
||||
reload: {type: 'boolean', description: 'Whether player code should reload to the default when the language changes.'}
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
@import "app/styles/mixins"
|
||||
@import "app/styles/bootstrap/variables"
|
||||
|
||||
.spell-list-entry-view
|
||||
.method-signature
|
||||
background-color: transparent
|
||||
border: 0
|
||||
font-size: 1.1em
|
||||
display: inline-block
|
||||
padding: 4px
|
||||
|
||||
.spell-list-entry-view.spell-tab
|
||||
#spell-top-bar-view
|
||||
$height: 87px
|
||||
$paddingTop: 10px
|
||||
$paddingBottom: 25px
|
||||
|
@ -46,12 +38,6 @@
|
|||
> *:not(.spell-tool-buttons)
|
||||
@include opacity(0.5)
|
||||
|
||||
.thang-avatar-view
|
||||
width: $childSize - 10px
|
||||
margin: 5px 0.4vw
|
||||
display: inline-block
|
||||
float: left
|
||||
|
||||
.btn.btn-small
|
||||
margin-top: 15px
|
||||
margin-right: 1.3vw
|
||||
|
@ -97,46 +83,8 @@
|
|||
.thang-avatar-wrapper
|
||||
border-width: 0
|
||||
|
||||
.spell-list-entry-view:not(.spell-tab)
|
||||
cursor: pointer
|
||||
@include opacity(0.90)
|
||||
clear: both
|
||||
padding: 5px
|
||||
position: relative
|
||||
|
||||
&:hover
|
||||
@include opacity(1)
|
||||
background-color: hsla(240, 40, 80, 0.25)
|
||||
|
||||
&.shows-top-divider:not(:first-child)
|
||||
border-top: 1px dashed #ccc
|
||||
|
||||
.method-signature
|
||||
margin-top: 5px
|
||||
|
||||
.thang-names
|
||||
float: right
|
||||
margin: 8px
|
||||
font-variant: small-caps
|
||||
color: darken(#ca8, 50%)
|
||||
white-space: nowrap
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
font-size: 13px
|
||||
max-width: 35%
|
||||
text-align: right
|
||||
|
||||
.thang-avatar-view
|
||||
width: 40px
|
||||
float: right
|
||||
|
||||
.thang-avatar-wrapper
|
||||
margin: 0 5px 0 0
|
||||
//margin: 2px 10px 2px 5px
|
||||
|
||||
|
||||
//html.no-borderimage
|
||||
// .spell-list-entry-view.spell-tab
|
||||
// .spell-top-bar-view
|
||||
// border-width: 0
|
||||
// border-image: none
|
||||
// background: transparent url(/images/level/code_editor_tab_background.png) no-repeat
|
|
@ -1,20 +0,0 @@
|
|||
@import "app/styles/mixins"
|
||||
@import "app/styles/bootstrap/variables"
|
||||
|
||||
#spell-list-view
|
||||
display: none
|
||||
position: absolute
|
||||
z-index: 10
|
||||
top: 50px
|
||||
left: 0%
|
||||
right: 10%
|
||||
padding: 4%
|
||||
border-style: solid
|
||||
border-image: url(/images/level/popover_border_background.png) 16 12 fill round
|
||||
border-width: 16px 12px
|
||||
|
||||
html.no-borderimage
|
||||
#spell-list-view
|
||||
background: transparent url(/images/level/popover_background.png)
|
||||
background-size: 100% 100%
|
||||
border: 0
|
|
@ -1,30 +0,0 @@
|
|||
@import "app/styles/mixins"
|
||||
@import "app/styles/bootstrap/variables"
|
||||
|
||||
.spell-list-entry-view
|
||||
.spell-list-entry-thangs-view
|
||||
position: absolute
|
||||
z-index: 11
|
||||
top: 50px
|
||||
right: -10%
|
||||
max-width: 70%
|
||||
max-height: 500px
|
||||
overflow: scroll
|
||||
padding: 4%
|
||||
border-style: solid
|
||||
border-image: url(/images/level/popover_border_background.png) 16 12 fill round
|
||||
border-width: 16px 12px
|
||||
|
||||
.thang-avatar-view
|
||||
cursor: pointer
|
||||
max-width: 100px
|
||||
width: 20%
|
||||
display: inline-block
|
||||
|
||||
|
||||
html.no-borderimage
|
||||
.spell-list-entry-view
|
||||
.spell-list-entry-thangs-view
|
||||
background: transparent url(/images/level/popover_background.png)
|
||||
background-size: 100% 100%
|
||||
border: 0
|
|
@ -3,12 +3,6 @@
|
|||
.hinge.hinge-2
|
||||
.hinge.hinge-3
|
||||
|
||||
if includeSpellList
|
||||
.btn.btn-small.btn-illustrated.spell-list-button(data-i18n="[title]play_level.tome_see_all_methods", title="See all methods you can edit")
|
||||
.glyphicon.glyphicon-chevron-down
|
||||
|
||||
.thang-avatar-placeholder
|
||||
|
||||
.spell-tool-buttons
|
||||
.btn.btn-small.btn-illustrated.btn-warning.reload-code(data-i18n="[title]play_level.tome_reload_method", title="Reload original code for this method")
|
||||
.glyphicon.glyphicon-repeat
|
|
@ -1 +0,0 @@
|
|||
h5(data-i18n="play_level.tome_select_method") Select a Method
|
|
@ -1,7 +0,0 @@
|
|||
if showTopDivider
|
||||
// Don't repeat Thang names when not changed from previous entry
|
||||
.thang-names(title=thangNames)= thangNames
|
||||
|
||||
code #{spell.name}(#{parameters})
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
h4
|
||||
span(data-i18n="play_level.tome_select_a_thang") Select Someone for
|
||||
code #{view.spell.name}(#{(view.spell.parameters || []).join(", ")})
|
|
@ -1,11 +1,7 @@
|
|||
#spell-list-tab-entry-view
|
||||
|
||||
#spell-list-view
|
||||
#spell-top-bar-view
|
||||
|
||||
#cast-button-view
|
||||
|
||||
#spell-view
|
||||
|
||||
#spell-palette-view
|
||||
|
||||
|
||||
|
|
|
@ -57,12 +57,9 @@ module.exports = class ThangAvatarView extends CocoView
|
|||
@$el.toggleClass 'selected', Boolean(selected)
|
||||
|
||||
onProblemsUpdated: (e) ->
|
||||
return unless @thang?.id of e.spell.thangs
|
||||
myProblems = []
|
||||
for thangID, spellThang of e.spell.thangs when thangID is @thang.id
|
||||
#aether = if e.isCast and spellThang.castAether then spellThang.castAether else spellThang.aether
|
||||
aether = spellThang.castAether # try only paying attention to the actually cast ones
|
||||
myProblems = myProblems.concat aether.getAllProblems() if aether
|
||||
return unless @thang?.id is e.spell.thang?.thang.id
|
||||
aether = e.spell.thang.castAether
|
||||
myProblems = aether?.getAllProblems() ? []
|
||||
worstLevel = null
|
||||
for level in ['error', 'warning', 'info'] when _.some myProblems, {level: level}
|
||||
worstLevel = level
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
SpellView = require './SpellView'
|
||||
SpellListTabEntryView = require './SpellListTabEntryView'
|
||||
SpellTopBarView = require './SpellTopBarView'
|
||||
{me} = require 'core/auth'
|
||||
{createAetherOptions} = require 'lib/aether_utils'
|
||||
utils = require 'core/utils'
|
||||
|
@ -7,7 +7,7 @@ utils = require 'core/utils'
|
|||
module.exports = class Spell
|
||||
loaded: false
|
||||
view: null
|
||||
entryView: null
|
||||
topBarView: null
|
||||
|
||||
constructor: (options) ->
|
||||
@spellKey = options.spellKey
|
||||
|
@ -45,23 +45,22 @@ module.exports = class Spell
|
|||
if p.aiSource and not @otherSession and not @canWrite()
|
||||
@source = @originalSource = p.aiSource
|
||||
@isAISource = true
|
||||
@thangs = {}
|
||||
if @canRead() # We can avoid creating these views if we'll never use them.
|
||||
@view = new SpellView {spell: @, level: options.level, session: @session, otherSession: @otherSession, worker: @worker, god: options.god, @supermodel, levelID: options.levelID}
|
||||
@view.render() # Get it ready and code loaded in advance
|
||||
@tabView = new SpellListTabEntryView
|
||||
@topBarView = new SpellTopBarView
|
||||
hintsState: options.hintsState
|
||||
spell: @
|
||||
supermodel: @supermodel
|
||||
codeLanguage: @language
|
||||
level: options.level
|
||||
@tabView.render()
|
||||
@topBarView.render()
|
||||
Backbone.Mediator.publish 'tome:spell-created', spell: @
|
||||
|
||||
destroy: ->
|
||||
@view?.destroy()
|
||||
@tabView?.destroy()
|
||||
@thangs = null
|
||||
@topBarView?.destroy()
|
||||
@thang = null
|
||||
@worker = null
|
||||
|
||||
setLanguage: (@language) ->
|
||||
|
@ -115,13 +114,13 @@ module.exports = class Spell
|
|||
("// #{line}" for line in description.split('\n')).join('\n') + '\n' + @originalSource
|
||||
|
||||
addThang: (thang) ->
|
||||
if @thangs[thang.id]
|
||||
@thangs[thang.id].thang = thang
|
||||
if @thang?.thang.id is thang.id
|
||||
@thang.thang = thang
|
||||
else
|
||||
@thangs[thang.id] = {thang: thang, aether: @createAether(thang), castAether: null}
|
||||
@thang = {thang: thang, aether: @createAether(thang), castAether: null}
|
||||
|
||||
removeThangID: (thangID) ->
|
||||
delete @thangs[thangID]
|
||||
@thang = null if @thang?.thang.id is thangID
|
||||
|
||||
canRead: (team) ->
|
||||
(team ? me.team) in @permissions.read or (team ? me.team) in @permissions.readwrite
|
||||
|
@ -137,30 +136,16 @@ module.exports = class Spell
|
|||
@source = source
|
||||
else
|
||||
source = @getSource()
|
||||
[pure, problems] = [null, null]
|
||||
if @language is 'html'
|
||||
[pure, problems] = [source, []] # TODO: problems? Actually do something when transpiling
|
||||
for thangID, spellThang of @thangs
|
||||
unless pure
|
||||
pure = spellThang.aether.transpile source
|
||||
problems = spellThang.aether.problems
|
||||
#console.log 'aether transpiled', source.length, 'to', spellThang.aether.pure.length, 'for', thangID, @spellKey
|
||||
else
|
||||
spellThang.aether.raw = source
|
||||
spellThang.aether.pure = pure
|
||||
spellThang.aether.problems = problems
|
||||
#console.log 'aether reused transpilation for', thangID, @spellKey
|
||||
unless @language is 'html'
|
||||
@thang?.aether.transpile source
|
||||
null
|
||||
|
||||
hasChanged: (newSource=null, currentSource=null) ->
|
||||
(newSource ? @originalSource) isnt (currentSource ? @source)
|
||||
|
||||
hasChangedSignificantly: (newSource=null, currentSource=null, cb) ->
|
||||
for thangID, spellThang of @thangs
|
||||
aether = spellThang.aether
|
||||
break
|
||||
unless aether
|
||||
console.error @toString(), 'couldn\'t find a spellThang with aether of', @thangs
|
||||
unless aether = @thang?.aether
|
||||
console.error @toString(), 'couldn\'t find a spellThang with aether', @thang
|
||||
cb false
|
||||
if @worker
|
||||
workerMessage =
|
||||
|
@ -202,10 +187,9 @@ module.exports = class Spell
|
|||
aether
|
||||
|
||||
updateLanguageAether: (@language) ->
|
||||
for thangId, spellThang of @thangs
|
||||
spellThang.aether?.setLanguage @language
|
||||
spellThang.castAether = null
|
||||
Backbone.Mediator.publish 'tome:spell-changed-language', spell: @, language: @language
|
||||
@thang?.aether?.setLanguage @language
|
||||
@thang?.castAether = null
|
||||
Backbone.Mediator.publish 'tome:spell-changed-language', spell: @, language: @language
|
||||
if @worker
|
||||
workerMessage =
|
||||
function: 'updateLanguageAether'
|
||||
|
|
|
@ -17,7 +17,6 @@ module.exports = class SpellDebugView extends CocoView
|
|||
'god:new-world-created': 'onNewWorld'
|
||||
'god:debug-value-return': 'handleDebugValue'
|
||||
'god:debug-world-load-progress-changed': 'handleWorldLoadProgressChanged'
|
||||
'tome:spell-shown': 'changeCurrentThangAndSpell'
|
||||
'tome:cast-spells': 'onTomeCast'
|
||||
'surface:frame-changed': 'onFrameChanged'
|
||||
'tome:spell-has-changed-significantly-calculation': 'onSpellChangedCalculation'
|
||||
|
@ -98,10 +97,6 @@ module.exports = class SpellDebugView extends CocoView
|
|||
currentObject = currentObject[key]
|
||||
currentObject[keys[keys.length - 1]] = value
|
||||
|
||||
changeCurrentThangAndSpell: (thangAndSpellObject) ->
|
||||
@thang = thangAndSpellObject.thang
|
||||
@spell = thangAndSpellObject.spell
|
||||
|
||||
handleDebugValue: (e) ->
|
||||
{key, value} = e
|
||||
@workerIsSimulating = false
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
CocoView = require 'views/core/CocoView'
|
||||
ThangAvatarView = require 'views/play/level/ThangAvatarView'
|
||||
template = require 'templates/play/level/tome/spell_list_entry_thangs'
|
||||
|
||||
module.exports = class SpellListEntryThangsView extends CocoView
|
||||
className: 'spell-list-entry-thangs-view'
|
||||
template: template
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@thangs = options.thangs
|
||||
@thang = options.thang
|
||||
@spell = options.spell
|
||||
@avatars = []
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
avatar.destroy() for avatar in @avatars if @avatars
|
||||
@avatars = []
|
||||
spellName = @spell.name
|
||||
for thang in @thangs
|
||||
avatar = new ThangAvatarView thang: thang, includeName: true, supermodel: @supermodel, creator: @
|
||||
@$el.append avatar.el
|
||||
avatar.render()
|
||||
avatar.setSelected thang is @thang
|
||||
avatar.$el.data('thang-id', thang.id).click (e) ->
|
||||
Backbone.Mediator.publish 'level:select-sprite', thangID: $(@).data('thang-id'), spellName: spellName
|
||||
avatar.onProblemsUpdated spell: @spell
|
||||
@avatars.push avatar
|
||||
|
||||
destroy: ->
|
||||
avatar.destroy() for avatar in @avatars
|
||||
super()
|
|
@ -1,115 +0,0 @@
|
|||
# TODO: This still needs a way to send problem states to its Thang
|
||||
|
||||
CocoView = require 'views/core/CocoView'
|
||||
ThangAvatarView = require 'views/play/level/ThangAvatarView'
|
||||
SpellListEntryThangsView = require 'views/play/level/tome/SpellListEntryThangsView'
|
||||
template = require 'templates/play/level/tome/spell_list_entry'
|
||||
|
||||
module.exports = class SpellListEntryView extends CocoView
|
||||
tagName: 'div' #'li'
|
||||
className: 'spell-list-entry-view'
|
||||
template: template
|
||||
controlsEnabled: true
|
||||
|
||||
subscriptions:
|
||||
'tome:problems-updated': 'onProblemsUpdated'
|
||||
'tome:spell-changed-language': 'onSpellChangedLanguage'
|
||||
'level:disable-controls': 'onDisableControls'
|
||||
'level:enable-controls': 'onEnableControls'
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
|
||||
events:
|
||||
'click': 'onClick'
|
||||
'mouseenter .thang-avatar-view': 'onMouseEnterAvatar'
|
||||
'mouseleave .thang-avatar-view': 'onMouseLeaveAvatar'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@spell = options.spell
|
||||
@showTopDivider = options.showTopDivider
|
||||
|
||||
getRenderData: (context={}) ->
|
||||
context = super context
|
||||
context.spell = @spell
|
||||
context.thangNames = (thangID for thangID, spellThang of @spell.thangs when spellThang.thang.exists).join(', ') # + ', Marcus, Robert, Phoebe, Will Smith, Zap Brannigan, You, Gandaaaaalf'
|
||||
context.showTopDivider = @showTopDivider
|
||||
context
|
||||
|
||||
getPrimarySpellThang: ->
|
||||
if @lastSelectedThang
|
||||
spellThang = _.find @spell.thangs, (spellThang) => spellThang.thang.id is @lastSelectedThang.id
|
||||
return spellThang if spellThang
|
||||
for thangID, spellThang of @spell.thangs
|
||||
continue unless spellThang.thang.exists
|
||||
return spellThang # Just do the first one else
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
return unless @options.showTopDivider # Don't repeat Thang avatars when not changed from previous entry
|
||||
return @$el.hide() unless spellThang = @getPrimarySpellThang()
|
||||
@$el.show()
|
||||
@avatar?.destroy()
|
||||
@avatar = new ThangAvatarView thang: spellThang.thang, includeName: false, supermodel: @supermodel
|
||||
@$el.prepend @avatar.el # Before rendering, so render can use parent for popover
|
||||
@avatar.render()
|
||||
@avatar.setSharedThangs _.size @spell.thangs
|
||||
@$el.addClass 'shows-top-divider' if @options.showTopDivider
|
||||
|
||||
setSelected: (selected, @lastSelectedThang) ->
|
||||
@avatar?.setSelected selected
|
||||
|
||||
onClick: (e) ->
|
||||
spellThang = @getPrimarySpellThang()
|
||||
Backbone.Mediator.publish 'level:select-sprite', thangID: spellThang.thang.id, spellName: @spell.name
|
||||
|
||||
onMouseEnterAvatar: (e) ->
|
||||
return unless @controlsEnabled and _.size(@spell.thangs) > 1
|
||||
@showThangs()
|
||||
|
||||
onMouseLeaveAvatar: (e) ->
|
||||
return unless @controlsEnabled and _.size(@spell.thangs) > 1
|
||||
@hideThangsTimeout = _.delay @hideThangs, 100
|
||||
|
||||
showThangs: ->
|
||||
clearTimeout @hideThangsTimeout if @hideThangsTimeout
|
||||
return if @thangsView
|
||||
spellThang = @getPrimarySpellThang()
|
||||
return unless spellThang
|
||||
@thangsView = new SpellListEntryThangsView thangs: (spellThang.thang for thangID, spellThang of @spell.thangs), thang: spellThang.thang, spell: @spell, supermodel: @supermodel
|
||||
@thangsView.render()
|
||||
@$el.append @thangsView.el
|
||||
@thangsView.$el.mouseenter (e) => @onMouseEnterAvatar()
|
||||
@thangsView.$el.mouseleave (e) => @onMouseLeaveAvatar()
|
||||
|
||||
hideThangs: =>
|
||||
return unless @thangsView
|
||||
@thangsView.off 'mouseenter mouseleave'
|
||||
@thangsView.$el.remove()
|
||||
@thangsView.destroy()
|
||||
@thangsView = null
|
||||
|
||||
onProblemsUpdated: (e) ->
|
||||
return unless e.spell is @spell
|
||||
@$el.toggleClass 'user-code-problem', e.problems.length
|
||||
|
||||
onSpellChangedLanguage: (e) ->
|
||||
return unless e.spell is @spell
|
||||
@render() # So that we can update parameters if needed
|
||||
|
||||
onDisableControls: (e) -> @toggleControls e, false
|
||||
onEnableControls: (e) -> @toggleControls e, true
|
||||
toggleControls: (e, enabled) ->
|
||||
return if e.controls and not ('editor' in e.controls)
|
||||
return if enabled is @controlsEnabled
|
||||
@controlsEnabled = enabled
|
||||
disabled = not enabled
|
||||
# Should refactor the disabling list so we can target the spell list separately?
|
||||
# Should not call it 'editor' any more?
|
||||
@$el.toggleClass('disabled', disabled).find('*').prop('disabled', disabled)
|
||||
|
||||
onNewWorld: (e) ->
|
||||
@lastSelectedThang = e.world.thangMap[@lastSelectedThang.id] if @lastSelectedThang
|
||||
|
||||
destroy: ->
|
||||
@avatar?.destroy()
|
||||
super()
|
|
@ -1,96 +0,0 @@
|
|||
# The SpellListView has SpellListEntryViews, which have ThangAvatarViews.
|
||||
# The SpellListView serves as a dropdown triggered from a SpellListTabEntryView, which actually isn't in a list, just had a lot of similar parts.
|
||||
# There is only one SpellListView, and it belongs to the TomeView.
|
||||
|
||||
# TODO: showTopDivider should change when we reorder
|
||||
|
||||
CocoView = require 'views/core/CocoView'
|
||||
template = require 'templates/play/level/tome/spell_list'
|
||||
{me} = require 'core/auth'
|
||||
SpellListEntryView = require './SpellListEntryView'
|
||||
|
||||
module.exports = class SpellListView extends CocoView
|
||||
className: 'spell-list-view'
|
||||
id: 'spell-list-view'
|
||||
template: template
|
||||
|
||||
subscriptions:
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@entries = []
|
||||
@sortSpells()
|
||||
|
||||
sortSpells: ->
|
||||
# Keep only spells for which we have permissions
|
||||
spells = _.filter @options.spells, (s) -> s.canRead()
|
||||
@spells = _.sortBy spells, @sortScoreForSpell
|
||||
#console.log 'Kept sorted spells', @spells
|
||||
|
||||
sortScoreForSpell: (s) =>
|
||||
# Sort by most spells per fewest Thangs
|
||||
# Lower comes first
|
||||
score = 0
|
||||
# Selected spell at the top
|
||||
score -= 9001900190019001 if s is @spell
|
||||
# Spells for selected thang at the top
|
||||
score -= 900190019001 if @thang and @thang.id of s.thangs
|
||||
# Read-only spells at the bottom
|
||||
score += 90019001 unless s.canWrite()
|
||||
# The more Thangs sharing a spell, the lower
|
||||
score += 9001 * _.size(s.thangs)
|
||||
# The more spells per Thang, the higher
|
||||
score -= _.filter(@spells, (s2) -> thangID of s2.thangs).length for thangID of s.thangs
|
||||
score
|
||||
|
||||
sortEntries: ->
|
||||
# Call sortSpells before this
|
||||
@entries = _.sortBy @entries, (entry) => _.indexOf @spells, entry.spell
|
||||
@$el.append entry.$el for entry in @entries
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
@addSpellListEntries()
|
||||
|
||||
addSpellListEntries: ->
|
||||
newEntries = []
|
||||
lastThangs = null
|
||||
for spell, index in @spells
|
||||
continue if _.find @entries, spell: spell
|
||||
theseThangs = _.keys(spell.thangs)
|
||||
changedThangs = not lastThangs or not _.isEqual theseThangs, lastThangs
|
||||
lastThangs = theseThangs
|
||||
newEntries.push entry = new SpellListEntryView spell: spell, showTopDivider: changedThangs, supermodel: @supermodel, level: @options.level
|
||||
@entries.push entry
|
||||
for entry in newEntries
|
||||
@$el.append entry.el
|
||||
entry.render() # Render after appending so that we can access parent container for popover
|
||||
|
||||
rerenderEntries: ->
|
||||
entry.render() for entry in @entries
|
||||
|
||||
onNewWorld: (e) ->
|
||||
@thang = e.world.thangMap[@thang.id] if @thang
|
||||
|
||||
setThangAndSpell: (@thang, @spell) ->
|
||||
@entries[0]?.setSelected false
|
||||
@sortSpells()
|
||||
@sortEntries()
|
||||
@entries[0].setSelected true, @thang
|
||||
|
||||
addThang: (thang) ->
|
||||
@sortSpells()
|
||||
@addSpellListEntries()
|
||||
|
||||
adjustSpells: (spells) ->
|
||||
for entry in @entries when _.isEmpty entry.spell.thangs
|
||||
entry.$el.remove()
|
||||
entry.destroy()
|
||||
@spells = @options.spells = spells
|
||||
@sortSpells()
|
||||
@addSpellListEntries()
|
||||
|
||||
destroy: ->
|
||||
entry.destroy() for entry in @entries
|
||||
super()
|
|
@ -1,25 +1,21 @@
|
|||
SpellListEntryView = require './SpellListEntryView'
|
||||
ThangAvatarView = require 'views/play/level/ThangAvatarView'
|
||||
template = require 'templates/play/level/tome/spell_list_tab_entry'
|
||||
LevelComponent = require 'models/LevelComponent'
|
||||
DocFormatter = require './DocFormatter'
|
||||
template = require 'templates/play/level/tome/spell-top-bar-view'
|
||||
ReloadLevelModal = require 'views/play/level/modal/ReloadLevelModal'
|
||||
CocoView = require 'views/core/CocoView'
|
||||
|
||||
module.exports = class SpellListTabEntryView extends SpellListEntryView
|
||||
module.exports = class SpellTopBarView extends CocoView
|
||||
template: template
|
||||
id: 'spell-list-tab-entry-view'
|
||||
id: 'spell-top-bar-view'
|
||||
controlsEnabled: true
|
||||
|
||||
subscriptions:
|
||||
'level:disable-controls': 'onDisableControls'
|
||||
'level:enable-controls': 'onEnableControls'
|
||||
'tome:spell-loaded': 'onSpellLoaded'
|
||||
'tome:spell-changed': 'onSpellChanged'
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
'tome:spell-changed-language': 'onSpellChangedLanguage'
|
||||
'tome:toggle-maximize': 'onToggleMaximize'
|
||||
|
||||
events:
|
||||
'click .spell-list-button': 'onDropdownClick'
|
||||
'click .reload-code': 'onCodeReload'
|
||||
'click .beautify-code': 'onBeautifyClick'
|
||||
'click .fullscreen-code': 'onToggleMaximize'
|
||||
|
@ -27,6 +23,7 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
|
|||
|
||||
constructor: (options) ->
|
||||
@hintsState = options.hintsState
|
||||
@spell = options.spell
|
||||
super(options)
|
||||
|
||||
getRenderData: (context={}) ->
|
||||
|
@ -35,7 +32,6 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
|
|||
shift = $.i18n.t 'keyboard_shortcuts.shift'
|
||||
context.beautifyShortcutVerbose = "#{ctrl}+#{shift}+B: #{$.i18n.t 'keyboard_shortcuts.beautify'}"
|
||||
context.maximizeShortcutVerbose = "#{ctrl}+#{shift}+M: #{$.i18n.t 'keyboard_shortcuts.maximize_editor'}"
|
||||
context.includeSpellList = @options.level.get('slug') in ['break-the-prison', 'zone-of-danger', 'k-means-cluster-wars', 'brawlwood', 'dungeon-arena', 'sky-span', 'minimax-tic-tac-toe']
|
||||
context.codeLanguage = @options.codeLanguage
|
||||
context
|
||||
|
||||
|
@ -44,52 +40,6 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
|
|||
@$el.addClass 'spell-tab'
|
||||
@attachTransitionEventListener()
|
||||
|
||||
onNewWorld: (e) ->
|
||||
@thang = e.world.thangMap[@thang.id] if @thang
|
||||
|
||||
setThang: (thang) ->
|
||||
return if thang.id is @thang?.id
|
||||
@thang = thang
|
||||
@spellThang = @spell.thangs[@thang.id]
|
||||
@buildAvatar()
|
||||
@buildDocs() unless @docsBuilt
|
||||
|
||||
buildAvatar: ->
|
||||
return unless @thang.world
|
||||
avatar = new ThangAvatarView thang: @thang, includeName: false, supermodel: @supermodel
|
||||
if @avatar
|
||||
@avatar.$el.replaceWith avatar.$el
|
||||
@avatar.destroy()
|
||||
else
|
||||
@$el.find('.thang-avatar-placeholder').replaceWith avatar.$el
|
||||
@avatar = avatar
|
||||
@avatar.render()
|
||||
|
||||
buildDocs: ->
|
||||
return if @spell.name is 'plan' # Too confusing for beginners
|
||||
@docsBuilt = true
|
||||
lcs = @supermodel.getModels LevelComponent
|
||||
found = false
|
||||
for lc in lcs when not found
|
||||
for doc in lc.get('propertyDocumentation') ? []
|
||||
if doc.name is @spell.name
|
||||
found = true
|
||||
break
|
||||
return unless found
|
||||
docFormatter = new DocFormatter doc: doc, thang: @thang, language: @options.codeLanguage, selectedMethod: true
|
||||
@$el.find('.method-signature').popover(
|
||||
animation: true
|
||||
html: true
|
||||
placement: 'bottom'
|
||||
trigger: 'hover'
|
||||
content: docFormatter.formatPopover()
|
||||
container: @$el.parent()
|
||||
).on 'show.bs.popover', =>
|
||||
@playSound 'spell-tab-entry-open', 0.75
|
||||
|
||||
onMouseEnterAvatar: (e) -> # Don't call super
|
||||
onMouseLeaveAvatar: (e) -> # Don't call super
|
||||
onClick: (e) -> # Don't call super
|
||||
onDisableControls: (e) -> @toggleControls e, false
|
||||
onEnableControls: (e) -> @toggleControls e, true
|
||||
|
||||
|
@ -98,15 +48,8 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
|
|||
@hintsState.set('hidden', not @hintsState.get('hidden'))
|
||||
window.tracker?.trackEvent 'Hints Clicked', category: 'Students', levelSlug: @options.level.get('slug'), hintCount: @hintsState.get('hints')?.length ? 0, ['Mixpanel']
|
||||
|
||||
onDropdownClick: (e) ->
|
||||
return unless @controlsEnabled
|
||||
Backbone.Mediator.publish 'tome:toggle-spell-list', {}
|
||||
@playSound 'spell-list-open'
|
||||
|
||||
onCodeReload: (e) ->
|
||||
#return unless @controlsEnabled
|
||||
#Backbone.Mediator.publish 'tome:reload-code', spell: @spell # Old: just reload the current code
|
||||
@openModalView new ReloadLevelModal() # New: prompt them to restart the level
|
||||
@openModalView new ReloadLevelModal()
|
||||
|
||||
onBeautifyClick: (e) ->
|
||||
return unless @controlsEnabled
|
||||
|
@ -134,14 +77,10 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
|
|||
onSpellChangedLanguage: (e) ->
|
||||
return unless e.spell is @spell
|
||||
@options.codeLanguage = e.language
|
||||
@$el.find('.method-signature').popover 'destroy'
|
||||
@render()
|
||||
@docsBuilt = false
|
||||
@buildDocs() if @thang
|
||||
@updateReloadButton()
|
||||
|
||||
toggleControls: (e, enabled) ->
|
||||
# Don't call super; do it differently
|
||||
return if e.controls and not ('editor' in e.controls)
|
||||
return if enabled is @controlsEnabled
|
||||
@controlsEnabled = enabled
|
||||
|
@ -163,8 +102,5 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
|
|||
$codearea.on transitionListener, =>
|
||||
$codearea.css 'z-index', 2 unless $('html').hasClass 'fullscreen-editor'
|
||||
|
||||
|
||||
destroy: ->
|
||||
@avatar?.destroy()
|
||||
@$el.find('.method-signature').popover 'destroy'
|
||||
super()
|
|
@ -569,7 +569,7 @@ module.exports = class SpellView extends CocoView
|
|||
@updateLines()
|
||||
return if thang.id is @thang?.id
|
||||
@thang = thang
|
||||
@spellThang = @spell.thangs[@thang.id]
|
||||
@spellThang = @spell.thang
|
||||
@createDebugView() unless @debugView
|
||||
@debugView?.thang = @thang
|
||||
@createTranslationView() unless @translationView
|
||||
|
@ -612,11 +612,11 @@ module.exports = class SpellView extends CocoView
|
|||
lineHeight = @ace.renderer.lineHeight or 20
|
||||
tomeHeight = $('#tome-view').innerHeight()
|
||||
spellPaletteView = $('#spell-palette-view')
|
||||
spellListTabEntryHeight = $('#spell-list-tab-entry-view').outerHeight()
|
||||
spellTopBarHeight = $('#spell-top-bar-view').outerHeight()
|
||||
spellToolbarHeight = $('.spell-toolbar-view').outerHeight()
|
||||
@spellPaletteHeight ?= spellPaletteView.outerHeight() # Remember this until resize, since we change it afterward
|
||||
spellPaletteAllowedHeight = Math.min @spellPaletteHeight, tomeHeight / 3
|
||||
maxHeight = tomeHeight - spellListTabEntryHeight - spellToolbarHeight - spellPaletteAllowedHeight
|
||||
maxHeight = tomeHeight - spellTopBarHeight - spellToolbarHeight - spellPaletteAllowedHeight
|
||||
linesAtMaxHeight = Math.floor(maxHeight / lineHeight)
|
||||
lines = Math.max 8, Math.min(screenLineCount + 2, linesAtMaxHeight)
|
||||
# 2 lines buffer is nice
|
||||
|
@ -903,15 +903,12 @@ module.exports = class SpellView extends CocoView
|
|||
return if @spellThang?.castAether?.metrics?.statementsExecuted > 2000 # Don't preload if they are running significant amounts of user code
|
||||
return if @options.level.isType('web-dev')
|
||||
oldSource = @spell.source
|
||||
oldSpellThangAethers = {}
|
||||
for thangID, spellThang of @spell.thangs
|
||||
oldSpellThangAethers[thangID] = spellThang.aether.serialize() # Get raw, pure, and problems
|
||||
oldSpellThangAether = @spell.thang?.aether.serialize()
|
||||
@spell.transpile @getSource()
|
||||
@cast true
|
||||
@spell.source = oldSource
|
||||
for thangID, spellThang of @spell.thangs
|
||||
for key, value of oldSpellThangAethers[thangID]
|
||||
spellThang.aether[key] = value
|
||||
for key, value of oldSpellThangAether
|
||||
@spell.thang.aether[key] = value
|
||||
|
||||
onSpellChanged: (e) ->
|
||||
@spellHasChanged = true
|
||||
|
@ -928,10 +925,10 @@ module.exports = class SpellView extends CocoView
|
|||
return unless e.god is @options.god
|
||||
return @onInfiniteLoop e if e.problem.id is 'runtime_InfiniteLoop'
|
||||
return unless e.problem.userInfo.methodName is @spell.name
|
||||
return unless spellThang = _.find @spell.thangs, (spellThang, thangID) -> thangID is e.problem.userInfo.thangID
|
||||
return unless @spell.thang?.thang.id is e.problem.userInfo.thangID
|
||||
@spell.hasChangedSignificantly @getSource(), null, (hasChanged) =>
|
||||
return if hasChanged
|
||||
spellThang.aether.addProblem e.problem
|
||||
@spell.thang.aether.addProblem e.problem
|
||||
@lastUpdatedAetherSpellThang = null # force a refresh without a re-transpile
|
||||
@updateAether false, false
|
||||
|
||||
|
@ -952,13 +949,14 @@ module.exports = class SpellView extends CocoView
|
|||
@updateAether false, false
|
||||
|
||||
onNewWorld: (e) ->
|
||||
@spell.removeThangID thangID for thangID of @spell.thangs when not e.world.getThangByID thangID
|
||||
for thangID, spellThang of @spell.thangs
|
||||
thang = e.world.getThangByID(thangID)
|
||||
aether = e.world.userCodeMap[thangID]?[@spell.name] # Might not be there if this is a new Programmable Thang.
|
||||
spellThang.castAether = aether
|
||||
spellThang.aether = @spell.createAether thang
|
||||
#console.log thangID, @spell.spellKey, 'ran', aether.metrics.callsExecuted, 'times over', aether.metrics.statementsExecuted, 'statements, with max recursion depth', aether.metrics.maxDepth, 'and full flow/metrics', aether.metrics, aether.flow
|
||||
if thang = e.world.getThangByID @spell.thang?.thang.id
|
||||
aether = e.world.userCodeMap[thang.id]?[@spell.name]
|
||||
@spell.thang.castAether = aether
|
||||
@spell.thang.aether = @spell.createAether thang
|
||||
#console.log thang.id, @spell.spellKey, 'ran', aether.metrics.callsExecuted, 'times over', aether.metrics.statementsExecuted, 'statements, with max recursion depth', aether.metrics.maxDepth, 'and full flow/metrics', aether.metrics, aether.flow
|
||||
else
|
||||
@spell.thang = null
|
||||
|
||||
@spell.transpile() # TODO: is there any way we can avoid doing this if it hasn't changed? Causes a slight hang.
|
||||
@updateAether false, false
|
||||
|
||||
|
@ -1149,7 +1147,7 @@ module.exports = class SpellView extends CocoView
|
|||
|
||||
toggleBackground: =>
|
||||
# TODO: make the background an actual background and do the CSS trick
|
||||
# used in spell_list_entry.sass for disabling
|
||||
# used in spell-top-bar-view.sass for disabling
|
||||
background = @$el.find('img.code-background')[0]
|
||||
if background.naturalWidth is 0 # not loaded yet
|
||||
return _.delay @toggleBackground, 100
|
||||
|
|
|
@ -2,36 +2,26 @@
|
|||
# - a CastButtonView, which has
|
||||
# - a cast button
|
||||
# - a submit/done button
|
||||
# - for each spell (programmableMethod):
|
||||
# - for each spell (programmableMethod) (which is now just always only 'plan')
|
||||
# - a Spell, which has
|
||||
# - a list of Thangs that share that Spell, with one aether per Thang per Spell
|
||||
# - a Thang that uses that Spell, with an aether and a castAether
|
||||
# - a SpellView, which has
|
||||
# - tons of stuff; the meat
|
||||
# - a SpellListView, which has
|
||||
# - for each spell:
|
||||
# - a SpellListEntryView, which has
|
||||
# - icons for each Thang
|
||||
# - the spell name
|
||||
# - a reload button
|
||||
# - documentation for that method (in a popover)
|
||||
# - a SpellTopBarView, which has some controls
|
||||
# - a SpellPaletteView, which has
|
||||
# - for each programmableProperty:
|
||||
# - a SpellPaletteEntryView
|
||||
#
|
||||
# The CastButtonView and SpellListView always show.
|
||||
# The CastButtonView always shows.
|
||||
# The SpellPaletteView shows the entries for the currently selected Programmable Thang.
|
||||
# The SpellView shows the code and runtime state for the currently selected Spell and, specifically, Thang.
|
||||
# The SpellView obscures most of the SpellListView when present. We might mess with this.
|
||||
# You can switch a SpellView to showing the runtime state of another Thang sharing that Spell.
|
||||
# SpellPaletteViews are destroyed and recreated whenever you switch Thangs.
|
||||
# The SpellListView shows spells to which your team has read or readwrite access.
|
||||
# It doubles as a Thang selector, since it's there when nothing is selected.
|
||||
|
||||
CocoView = require 'views/core/CocoView'
|
||||
template = require 'templates/play/level/tome/tome'
|
||||
{me} = require 'core/auth'
|
||||
Spell = require './Spell'
|
||||
SpellListView = require './SpellListView'
|
||||
SpellPaletteView = require './SpellPaletteView'
|
||||
CastButtonView = require './CastButtonView'
|
||||
|
||||
|
@ -44,7 +34,6 @@ module.exports = class TomeView extends CocoView
|
|||
subscriptions:
|
||||
'tome:spell-loaded': 'onSpellLoaded'
|
||||
'tome:cast-spell': 'onCastSpell'
|
||||
'tome:toggle-spell-list': 'onToggleSpellList'
|
||||
'tome:change-language': 'updateLanguageForAllSpells'
|
||||
'surface:sprite-selected': 'onSpriteSelected'
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
|
@ -52,7 +41,6 @@ module.exports = class TomeView extends CocoView
|
|||
'tome:select-primary-sprite': 'onSelectPrimarySprite'
|
||||
|
||||
events:
|
||||
'click #spell-view': 'onSpellViewClick'
|
||||
'click': 'onClick'
|
||||
|
||||
afterRender: ->
|
||||
|
@ -62,9 +50,7 @@ module.exports = class TomeView extends CocoView
|
|||
if @options.level.isType('web-dev')
|
||||
if @fakeProgrammableThang = @createFakeProgrammableThang()
|
||||
programmableThangs = [@fakeProgrammableThang]
|
||||
@createSpells programmableThangs, programmableThangs[0]?.world # Do before spellList, thangList, and castButton
|
||||
unless @options.level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev', 'web-dev')
|
||||
@spellList = @insertSubView new SpellListView spells: @spells, supermodel: @supermodel, level: @options.level
|
||||
@createSpells programmableThangs, programmableThangs[0]?.world # Do before castButton
|
||||
@castButton = @insertSubView new CastButtonView spells: @spells, level: @options.level, session: @options.session, god: @options.god
|
||||
@teamSpellMap = @generateTeamSpellMap(@spells)
|
||||
unless programmableThangs.length
|
||||
|
@ -75,10 +61,8 @@ module.exports = class TomeView extends CocoView
|
|||
delete @options.thangs
|
||||
|
||||
onNewWorld: (e) ->
|
||||
thangs = _.filter e.world.thangs, 'inThangList'
|
||||
programmableThangs = _.filter thangs, (t) -> t.isProgrammable and t.programmableMethods
|
||||
programmableThangs = _.filter e.thangs, (t) -> t.isProgrammable and t.programmableMethods and t.inThangList
|
||||
@createSpells programmableThangs, e.world
|
||||
@spellList?.adjustSpells @spells
|
||||
|
||||
onCommentMyCode: (e) ->
|
||||
for spellKey, spell of @spells when spell.canWrite()
|
||||
|
@ -117,30 +101,27 @@ module.exports = class TomeView extends CocoView
|
|||
@thangSpells[thang.id] = []
|
||||
for methodName, method of thang.programmableMethods
|
||||
pathComponents = [thang.id, methodName]
|
||||
if method.cloneOf
|
||||
pathComponents[0] = method.cloneOf # referencing another Thang's method
|
||||
pathComponents[0] = _.string.slugify pathComponents[0]
|
||||
spellKey = pathComponents.join '/'
|
||||
@thangSpells[thang.id].push spellKey
|
||||
unless method.cloneOf
|
||||
skipProtectAPI = @getQueryVariable 'skip_protect_api', (@options.levelID in ['gridmancer', 'minimax-tic-tac-toe'])
|
||||
spell = @spells[spellKey] = new Spell
|
||||
hintsState: @options.hintsState
|
||||
programmableMethod: method
|
||||
spellKey: spellKey
|
||||
pathComponents: pathPrefixComponents.concat(pathComponents)
|
||||
session: @options.session
|
||||
otherSession: @options.otherSession
|
||||
supermodel: @supermodel
|
||||
skipProtectAPI: skipProtectAPI
|
||||
worker: @worker
|
||||
language: language
|
||||
spectateView: @options.spectateView
|
||||
spectateOpponentCodeLanguage: @options.spectateOpponentCodeLanguage
|
||||
observing: @options.observing
|
||||
levelID: @options.levelID
|
||||
level: @options.level
|
||||
god: @options.god
|
||||
skipProtectAPI = @getQueryVariable 'skip_protect_api', false
|
||||
spell = @spells[spellKey] = new Spell
|
||||
hintsState: @options.hintsState
|
||||
programmableMethod: method
|
||||
spellKey: spellKey
|
||||
pathComponents: pathPrefixComponents.concat(pathComponents)
|
||||
session: @options.session
|
||||
otherSession: @options.otherSession
|
||||
supermodel: @supermodel
|
||||
skipProtectAPI: skipProtectAPI
|
||||
worker: @worker
|
||||
language: language
|
||||
spectateView: @options.spectateView
|
||||
spectateOpponentCodeLanguage: @options.spectateOpponentCodeLanguage
|
||||
observing: @options.observing
|
||||
levelID: @options.levelID
|
||||
level: @options.level
|
||||
god: @options.god
|
||||
|
||||
for thangID, spellKeys of @thangSpells
|
||||
thang = @fakeProgrammableThang ? world.getThangByID thangID
|
||||
|
@ -176,53 +157,24 @@ module.exports = class TomeView extends CocoView
|
|||
difficulty = Math.max 0, difficulty - 1 # Show the difficulty they won, not the next one.
|
||||
Backbone.Mediator.publish 'tome:cast-spells', spells: @spells, preload: preload, realTime: realTime, submissionCount: sessionState.submissionCount ? 0, flagHistory: sessionState.flagHistory ? [], difficulty: difficulty, god: @options.god, fixedSeed: @options.fixedSeed
|
||||
|
||||
onToggleSpellList: (e) ->
|
||||
@spellList?.rerenderEntries()
|
||||
@spellList?.$el.toggle()
|
||||
|
||||
onSpellViewClick: (e) ->
|
||||
@spellList?.$el.hide()
|
||||
|
||||
onClick: (e) ->
|
||||
Backbone.Mediator.publish 'tome:focus-editor', {} unless $(e.target).parents('.popover').length
|
||||
|
||||
clearSpellView: ->
|
||||
@spellView?.dismiss()
|
||||
@spellView?.$el.after('<div id="' + @spellView.id + '"></div>').detach()
|
||||
@spellView = null
|
||||
@spellTabView?.$el.after('<div id="' + @spellTabView.id + '"></div>').detach()
|
||||
@spellTabView = null
|
||||
@removeSubView @spellPaletteView if @spellPaletteView
|
||||
@spellPaletteView = null
|
||||
@$el.find('#spell-palette-view').hide()
|
||||
@castButton?.$el.hide()
|
||||
|
||||
onSpriteSelected: (e) ->
|
||||
return if @spellView and @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev', 'web-dev'] # Never deselect the hero in the Tome.
|
||||
thang = e.thang
|
||||
spellName = e.spellName
|
||||
@spellList?.$el.hide()
|
||||
return @clearSpellView() unless thang
|
||||
spell = @spellFor thang, spellName
|
||||
unless spell?.canRead()
|
||||
@clearSpellView()
|
||||
@updateSpellPalette thang, spell if spell
|
||||
return
|
||||
@setSpellView spell, thang
|
||||
spell = @spellFor e.thang, e.spellName
|
||||
if spell?.canRead()
|
||||
@setSpellView spell, e.thang
|
||||
|
||||
setSpellView: (spell, thang) ->
|
||||
unless spell.view is @spellView
|
||||
@clearSpellView()
|
||||
@spellView = spell.view
|
||||
@spellTabView = spell.tabView
|
||||
@spellTopBarView = spell.topBarView
|
||||
@$el.find('#' + @spellView.id).after(@spellView.el).remove()
|
||||
@$el.find('#' + @spellTabView.id).after(@spellTabView.el).remove()
|
||||
@$el.find('#' + @spellTopBarView.id).after(@spellTopBarView.el).remove()
|
||||
@castButton?.attachTo @spellView
|
||||
Backbone.Mediator.publish 'tome:spell-shown', thang: thang, spell: spell
|
||||
@updateSpellPalette thang, spell
|
||||
@spellList?.setThangAndSpell thang, spell
|
||||
@spellView?.setThang thang
|
||||
@spellTabView?.setThang thang
|
||||
|
||||
updateSpellPalette: (thang, spell) ->
|
||||
return unless thang and @spellPaletteView?.thang isnt thang and (thang.programmableProperties or thang.apiProperties or thang.programmableHTMLProperties)
|
||||
|
@ -256,7 +208,7 @@ module.exports = class TomeView extends CocoView
|
|||
if @options.level.isType('web-dev')
|
||||
@setSpellView @spells['hero-placeholder/plan'], @fakeProgrammableThang
|
||||
return
|
||||
# This is only fired by PlayLevelView for hero levels currently
|
||||
# This is fired by PlayLevelView
|
||||
# TODO: Don't hard code these hero names
|
||||
if @options.session.get('team') is 'ogres'
|
||||
Backbone.Mediator.publish 'level:select-sprite', thangID: 'Hero Placeholder 1'
|
||||
|
|
Loading…
Reference in a new issue