diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index 319449141..0a5e64478 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -248,6 +248,8 @@ module.exports = class SpriteBoss extends CocoClass # Marks updateSelection: -> + if @selectedSprite and (not @selectedSprite.thang.exists or not @world.getThangByID @selectedSprite.thang.id) + @selectSprite null, null, null @updateTarget() return unless @selectionMark @selectionMark.toggle @selectedSprite? diff --git a/app/styles/play/level/hud.sass b/app/styles/play/level/hud.sass index 63f8b1a94..a775375ef 100644 --- a/app/styles/play/level/hud.sass +++ b/app/styles/play/level/hud.sass @@ -223,7 +223,10 @@ .hud-hint font-weight: normal - color: #888888 + color: #aaa + position: absolute + top: 0 + right: 4px .enter position: absolute diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee index e70714eda..41dba1118 100644 --- a/app/views/play/level/hud_view.coffee +++ b/app/views/play/level/hud_view.coffee @@ -163,7 +163,7 @@ module.exports = class HUDView extends View else s = $.i18n.t('play_level.hud_continue', defaultValue: "Continue (press shift-space)") if @shiftSpacePressed > 4 and not @escapePressed - group.append('<span class="hud-hint">Press esc to skip dialog</span>') + @bubble.append('<span class="hud-hint">skip: esc</span>') group.append($('<button class="btn btn-small banner with-dot">' + s + ' <div class="dot"></div></button>')) @lastResponses = null @bubble.append($("<h3>#{@speaker ? 'Captain Anya'}</h3>")) diff --git a/app/views/play/level/tome/spell.coffee b/app/views/play/level/tome/spell.coffee index 17cc4d748..6a3b409ac 100644 --- a/app/views/play/level/tome/spell.coffee +++ b/app/views/play/level/tome/spell.coffee @@ -30,6 +30,9 @@ module.exports = class Spell addThang: (thang) -> @thangs[thang.id] ?= {thang: thang, aether: @createAether(thang), castAether: null} + removeThangID: (thangID) -> + delete @thangs[thangID] + canRead: (team) -> (team ? me.team) in @permissions.read or (team ? me.team) in @permissions.readwrite diff --git a/app/views/play/level/tome/spell_list_view.coffee b/app/views/play/level/tome/spell_list_view.coffee index 6b5862d38..2fabeffd6 100644 --- a/app/views/play/level/tome/spell_list_view.coffee +++ b/app/views/play/level/tome/spell_list_view.coffee @@ -79,3 +79,11 @@ module.exports = class SpellListView extends View 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() diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee index cd4235f34..ed3619c79 100644 --- a/app/views/play/level/tome/spell_view.coffee +++ b/app/views/play/level/tome/spell_view.coffee @@ -377,11 +377,12 @@ module.exports = class SpellView extends View @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 - aether = e.world.userCodeMap[thangID][@spell.name] - #console.log thangID, "got new castAether with raw", aether.raw, "problems", aether.problems + 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 e.world.getThangByID(thangID) + 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 @spell.transpile() @updateAether false, false diff --git a/app/views/play/level/tome/thang_list_entry_view.coffee b/app/views/play/level/tome/thang_list_entry_view.coffee index fb143ddaa..1db0f3741 100644 --- a/app/views/play/level/tome/thang_list_entry_view.coffee +++ b/app/views/play/level/tome/thang_list_entry_view.coffee @@ -46,6 +46,7 @@ module.exports = class ThangListEntryView extends View @$el.append @avatar.el # Before rendering, so render can use parent for popover @avatar.render() @avatar.setSharedThangs @spells.length # A bit weird to call it sharedThangs; could refactor if we like this + @$el.toggle Boolean(@thang.exists) @$el.popover( animation: false html: true diff --git a/app/views/play/level/tome/thang_list_view.coffee b/app/views/play/level/tome/thang_list_view.coffee index 405acde5b..a2f5f8939 100644 --- a/app/views/play/level/tome/thang_list_view.coffee +++ b/app/views/play/level/tome/thang_list_view.coffee @@ -72,7 +72,11 @@ module.exports = class ThangListView extends View return entry.spells[0] null - addThang: (thang) -> - @thangs.push thang + adjustThangs: (spells, thangs, toRemove, toAdd) -> + for entry in @entries when _.find toRemove, {id: entry.thang.id} + entry.$el.remove() + entry.destroy() + @spells = @options.spells = spells + @thangs = @options.thangs = _.filter thangs, 'isSelectable' @sortThangs() - @addThangListEntries [thang] + @addThangListEntries toAdd diff --git a/app/views/play/level/tome/tome_view.coffee b/app/views/play/level/tome/tome_view.coffee index 3e5b85d3d..a030b70d7 100644 --- a/app/views/play/level/tome/tome_view.coffee +++ b/app/views/play/level/tome/tome_view.coffee @@ -47,7 +47,7 @@ module.exports = class TomeView extends View 'tome:cast-spell': "onCastSpell" 'tome:toggle-spell-list': 'onToggleSpellList' 'surface:sprite-selected': 'onSpriteSelected' - 'surface:new-thang-added': 'onNewThangAdded' + 'god:new-world-created': 'onNewWorld' events: 'click #spell-view': 'onSpellViewClick' @@ -58,7 +58,7 @@ module.exports = class TomeView extends View programmableThangs = _.filter @options.thangs, 'isProgrammable' if programmableThangs.length - @createSpells programmableThangs # Do before spellList, thangList, and castButton + @createSpells programmableThangs, programmableThangs[0].world # Do before spellList, thangList, and castButton @spellList = @insertSubView new SpellListView spells: @spells, supermodel: @supermodel @thangList = @insertSubView new ThangListView spells: @spells, thangs: @options.thangs, supermodel: @supermodel @castButton = @insertSubView new CastButtonView spells: @spells @@ -66,20 +66,20 @@ module.exports = class TomeView extends View @cast() console.log "Warning: There are no Programmable Thangs in this level, which makes it unplayable." - onNewThangAdded: (e) -> - return unless e.thang.isProgrammable and not _.find @thangList.thangs, id: e.thang.id - @createSpells [e.thang] - @spellList.addThang e.thang - @thangList.addThang e.thang + onNewWorld: (e) -> + oldThangs = @thangList.thangs + newThangs = e.world.thangs + toRemove = (thang for thang in oldThangs when not e.world.getThangByID thang.id) + toAdd = (thang for thang in newThangs when not _.find oldThangs, id: thang.id) + @createSpells toAdd, e.world + @thangList.adjustThangs @spells, newThangs, toRemove, toAdd + @spellList.adjustSpells @spells - createSpells: (programmableThangs) -> - # If needed, we could make this able to update when programmableThangs changes. - # We haven't done that yet, so call it just once on init. + createSpells: (programmableThangs, world) -> pathPrefixComponents = ['play', 'level', @options.levelID, @options.session.id, 'code'] @spells ?= {} @thangSpells ?= {} for thang in programmableThangs - world = thang.world continue if @thangSpells[thang.id]? @thangSpells[thang.id] = [] for methodName, method of thang.programmableMethods @@ -92,8 +92,12 @@ module.exports = class TomeView extends View unless method.cloneOf spell = @spells[spellKey] = new Spell programmableMethod: method, spellKey: spellKey, pathComponents: pathPrefixComponents.concat(pathComponents), session: @options.session, supermodel: @supermodel, skipFlow: @getQueryVariable("skip_flow") is "true", skipProtectAPI: @getQueryVariable("skip_protect_api") is "true" for thangID, spellKeys of @thangSpells - thang = world.getThangByID(thangID) - @spells[spellKey].addThang thang for spellKey in spellKeys + thang = world.getThangByID thangID + if thang + @spells[spellKey].addThang thang for spellKey in spellKeys + else + delete @thangSpells[thangID] + @spells[spellKey].removeThangID thangID for spellKey in spellKeys null onSpellLoaded: (e) ->