diff --git a/app/styles/game-menu/inventory-view.sass b/app/styles/game-menu/inventory-view.sass index 98bb645e1..ea41db65a 100644 --- a/app/styles/game-menu/inventory-view.sass +++ b/app/styles/game-menu/inventory-view.sass @@ -68,6 +68,10 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin border-color: #28f @include box-shadow(0 0 10px #28f) + &.should-equip + background-color: #8fa + outline: 2px solid #8af + &.droppable outline: 2px solid blue @@ -189,6 +193,14 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin .item-info:after content: ' (available)' + &.should-equip + background-color: #8fa + outline: 2px solid #8af + + .item-info:after + content: ' (drag to equip)' + font-weight: bold + &.equipped background-color: #ff5 diff --git a/app/views/game-menu/InventoryView.coffee b/app/views/game-menu/InventoryView.coffee index f8914877e..a797fad23 100644 --- a/app/views/game-menu/InventoryView.coffee +++ b/app/views/game-menu/InventoryView.coffee @@ -29,7 +29,6 @@ module.exports = class InventoryView extends CocoView @items = new CocoCollection([], {model: ThangType}) @equipment = options.equipment or @options.session?.get('heroConfig')?.inventory or me.get('heroConfig')?.inventory or {} @equipment = $.extend true, {}, @equipment - @assignLevelEquipment() @items.url = '/db/thang.type?view=items&project=name,components,original,rasterIcon' @supermodel.loadCollection(@items, 'items') @@ -103,26 +102,44 @@ module.exports = class InventoryView extends CocoView for itemSlot in @$el.find '.item-slot' slot = $(itemSlot).data 'slot' - #$(itemSlot).find('.placeholder').css('background-image', "url(/images/pages/game-menu/slot-#{slot}.png)") - do (slot) => + do (slot, itemSlot) => $(itemSlot).droppable drop: (e, ui) => @onAvailableItemDoubleClick() accept: (el) -> $(el).parent().hasClass slot activeClass: 'droppable' hoverClass: 'droppable-hover' tolerance: 'touch' + @makeEquippedSlotDraggable $(itemSlot) @$el.find('#selected-items').hide() # Hide until one is selected @delegateEvents() if @selectedHero and not @startedLoadingFirstHero @loadHero() + @requireLevelEquipment() afterInsert: -> super() @canvasWidth = @$el.find('canvas').innerWidth() @canvasHeight = @$el.find('canvas').innerHeight() + makeEquippedSlotDraggable: (slot) -> + unequip = => @unequipItemFromSlot slot + shouldStayEquippedWhenDropped = (isValidDrop) -> + pos = $(@).position() + revert = Math.abs(pos.left) < $(@).outerWidth() and Math.abs(pos.top) < $(@).outerHeight() + unequip() if not revert + revert + # TODO: figure out how to make this actually above the available items list (the .ui-draggable-helper img is still inside .item-view and so underlaps...) + $(slot).find('img').draggable + revert: shouldStayEquippedWhenDropped + appendTo: @$el + cursorAt: {left: 35.5, top: 35.5} + revertDuration: 200 + distance: 10 + scroll: false + zIndex: 100 + clearSelection: -> @$el.find('.item-slot.selected').removeClass 'selected' @$el.find('.list-group-item').removeClass('active') @@ -197,7 +214,10 @@ module.exports = class InventoryView extends CocoView for el in @$el.find('#available-equipment .list-group-item') itemID = $(el).find('.item-view').data('item-id') if itemID is itemIDToUnequip - return $(el).removeClass('equipped') + unequipped = $(el).removeClass('equipped') + break + @requireLevelEquipment() if unequipped + return unequipped equipSelectedItemToSlot: (slot) -> selectedItemContainer = @getSelectedAvailableItemContainer() @@ -207,6 +227,8 @@ module.exports = class InventoryView extends CocoView slotContainer.html(newItemHTML) slotContainer.find('.item-view').data('item-id', selectedItemContainer.find('.item-view').data('item-id')) @$el.find('.list-group-item').removeClass('active') + @makeEquippedSlotDraggable slot + @requireLevelEquipment() onSelectionChanged: -> @$el.find('.item-slot').show() @@ -290,7 +312,7 @@ module.exports = class InventoryView extends CocoView config[slotName] = item.get('original') config - assignLevelEquipment: -> + requireLevelEquipment: -> # This is temporary, until we have a more general way of awarding items and configuring needed/locked items per level. gear = 'simple-boots': '53e237bf53457600003e3f05' @@ -306,17 +328,35 @@ module.exports = class InventoryView extends CocoView 'shadow-guard': {feet: 'simple-boots'} 'true-names': {feet: 'simple-boots', 'right-hand': 'longsword'} 'the-raised-sword': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic'} - 'the-first-kithmaze': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i'} - 'the-second-kithmaze': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i'} - 'new-sight': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i'} - 'lowly-kithmen': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'} - 'a-bolt-in-the-dark': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'} + 'the-first-kithmaze': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'} + 'the-second-kithmaze': {feet: 'simple-boots', 'programming-book': 'programmaticon-i'} + 'new-sight': {'right-hand': 'longsword', 'programming-book': 'programmaticon-i'} + 'lowly-kithmen': {feet: 'simple-boots', 'right-hand': 'longsword', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'} + 'a-bolt-in-the-dark': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', eyes: 'crude-glasses'} 'the-final-kithmaze': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'} - 'kithgard-gates': {feet: 'simple-boots', 'right-hand': 'builders-hammer', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'} - 'defence-of-plainswood': {feet: 'simple-boots', 'right-hand': 'builders-hammer', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'} + 'kithgard-gates': {feet: 'simple-boots', 'right-hand': 'builders-hammer'} + 'defence-of-plainswood': {feet: 'simple-boots', 'right-hand': 'builders-hammer'} + # TODO: figure out leather boots for plainswood (or next one?) return unless necessaryGear = gearByLevel[@options.levelID] - for slot, item of necessaryGear ? {} - @equipment[slot] ?= gear[item] + if @supermodel.finished() + equipment = @getCurrentEquipmentConfig() # Make sure @equipment is updated + else + equipment = @equipment + hadRequired = @remainingRequiredEquipment?.length + @remainingRequiredEquipment = [] + @$el.find('.should-equip').removeClass('should-equip') + for slot, item of necessaryGear + continue if item is 'leather-tunic' and $('#world-map-view') # Don't tell them they need it until they need it in the level + continue if equipment[slot] and not (item is 'builders-hammer' and @equipment[slot] is gear.longsword) + availableSlotSelector = "#available-equipment li[data-item-id='#{gear[item]}']" + @highlightElement availableSlotSelector, delay: 500, sides: ['right'], rotation: Math.PI / 2 + @$el.find(availableSlotSelector).addClass 'should-equip' + @$el.find("#equipped div[data-slot='#{slot}']").addClass 'should-equip' + @remainingRequiredEquipment.push slot: slot, item: gear[item] + if hadRequired and not @remainingRequiredEquipment.length + @endHighlight() + @highlightElement '#play-level-button', duration: 5000 + $('#play-level-button').prop('disabled', @remainingRequiredEquipment.length > 0) # Restrict available items to those that would be available by this item. @allowedItems = [] @@ -370,7 +410,9 @@ module.exports = class InventoryView extends CocoView onShown: -> # Called when we switch tabs to this within the modal + @requireLevelEquipment() @loadHero() onHidden: -> # Called when the modal itself is dismissed + @endHighlight() diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee index 3068f8015..524dd13d2 100644 --- a/app/views/kinds/CocoView.coffee +++ b/app/views/kinds/CocoView.coffee @@ -60,6 +60,7 @@ module.exports = class CocoView extends Backbone.View view.destroy() for id, view of @subviews $('#modal-wrapper .modal').off 'hidden.bs.modal', @modalClosed @endHighlight() + @getPointer(false).remove() @[key] = undefined for key, value of @ @destroyed = true @off = doNothing @@ -354,16 +355,17 @@ module.exports = class CocoView extends Backbone.View setTimeout (=> $pointer.css transition: 'all 0.4s ease-in', transform: "rotate(#{@pointerRotation}rad) translate(-3px, #{@pointerRadialDistance}px)"), 800 endHighlight: -> - @getPointer().css('opacity', 0.0) + @getPointer(false).css('opacity', 0.0) clearInterval @pointerInterval clearTimeout @pointerDelayTimeout clearTimeout @pointerDurationTimeout @pointerInterval = @pointerDelayTimeout = @pointerDurationTimeout = null - getPointer: -> - return $pointer if ($pointer = @$el.find('.highlight-pointer')) and $pointer.length - $pointer = $('<img src="/images/level/pointer.png" class="highlight-pointer">') - @$el.append($pointer) + getPointer: (add=true) -> + return $pointer if ($pointer = $(".highlight-pointer[data-cid='#{@cid}']")) and ($pointer.length or not add) + $pointer = $("<img src='/images/level/pointer.png' class='highlight-pointer' data-cid='#{@cid}'>") + $pointer.css('z-index', 1040) if @$el.parents('#modal-wrapper').length + $('body').append($pointer) $pointer # Utilities diff --git a/app/views/play/modal/PlayLevelModal.coffee b/app/views/play/modal/PlayLevelModal.coffee index a1eafc8d5..ea11de1df 100644 --- a/app/views/play/modal/PlayLevelModal.coffee +++ b/app/views/play/modal/PlayLevelModal.coffee @@ -64,7 +64,7 @@ module.exports = class PlayLevelModal extends ModalView updateConfig: (callback, skipSessionSave) -> sessionHeroConfig = @options.session.get('heroConfig') ? {} lastHeroConfig = me.get('heroConfig') ? {} - thangType = @subviews.choose_hero_view.selectedHero.get 'original' + thangType = @subviews.choose_hero_view.selectedHero?.get('original') ? sessionHeroConfig.thangType ? lastHeroConfig.thangType inventory = @subviews.inventory_view.getCurrentEquipmentConfig() patchSession = patchMe = false props = thangType: thangType, inventory: inventory @@ -101,6 +101,7 @@ module.exports = class PlayLevelModal extends ModalView @chooseHeroView.onShown() onClickPlayLevel: (e) -> + return if @$el.find('#play-level-button').prop 'disabled' @showLoading() @updateConfig => @navigatingToPlay = true