2014-11-28 20:49:41 -05:00
ModalView = require ' views/core/ModalView '
2014-09-17 21:56:08 -04:00
template = require ' templates/play/modal/play-items-modal '
2014-11-24 13:51:20 -05:00
buyGemsPromptTemplate = require ' templates/play/modal/buy-gems-prompt '
2014-11-10 18:24:05 -05:00
ItemDetailsView = require ' ./ItemDetailsView '
2014-11-24 13:51:20 -05:00
BuyGemsModal = require ' views/play/modal/BuyGemsModal '
2014-11-01 17:15:57 -04:00
2014-09-17 21:56:08 -04:00
CocoCollection = require ' collections/CocoCollection '
ThangType = require ' models/ThangType '
2014-11-01 17:15:57 -04:00
LevelComponent = require ' models/LevelComponent '
Purchase = require ' models/Purchase '
2014-11-28 20:49:41 -05:00
utils = require ' core/utils '
2014-11-01 17:15:57 -04:00
PAGE_SIZE = 200
slotToCategory = {
' right-hand ' : ' primary '
' left-hand ' : ' secondary '
' head ' : ' armor '
' torso ' : ' armor '
' gloves ' : ' armor '
' feet ' : ' armor '
' eyes ' : ' accessories '
' neck ' : ' accessories '
' wrists ' : ' accessories '
' left-ring ' : ' accessories '
' right-ring ' : ' accessories '
' waist ' : ' accessories '
' pet ' : ' misc '
' minion ' : ' misc '
' flag ' : ' misc '
' misc-0 ' : ' misc '
' misc-1 ' : ' misc '
' programming-book ' : ' books '
}
2014-09-17 21:56:08 -04:00
module.exports = class PlayItemsModal extends ModalView
className: ' modal fade play-modal '
template: template
id: ' play-items-modal '
2014-11-01 17:15:57 -04:00
events:
' click .item ' : ' onItemClicked '
' shown.bs.tab ' : ' onTabClicked '
' click .unlock-button ' : ' onUnlockButtonClicked '
2014-11-24 13:51:20 -05:00
' click .buy-gems-prompt-button ' : ' onBuyGemsPromptButtonClicked '
2014-11-01 17:15:57 -04:00
' click # close-modal ' : ' hide '
2014-11-24 13:51:20 -05:00
' click ' : ' onClickedSomewhere '
2014-12-01 20:33:37 -05:00
' update .tab-pane .nano ' : ' onScrollItemPane '
2014-09-17 21:56:08 -04:00
constructor: (options) ->
2014-12-01 20:33:37 -05:00
@onScrollItemPane = _ . throttle ( _ . bind ( @ onScrollItemPane , @ ) , 200 )
2014-09-17 21:56:08 -04:00
super options
2014-11-01 17:15:57 -04:00
@items = new Backbone . Collection ( )
@itemCategoryCollections = { }
2014-11-04 10:19:30 -05:00
2014-11-01 17:15:57 -04:00
project = [
' name '
' components.config '
' components.original '
' slug '
' original '
' rasterIcon '
' gems '
2014-11-11 01:07:55 -05:00
' tier '
2014-11-25 13:28:31 -05:00
' description '
2014-11-01 17:15:57 -04:00
' i18n '
2014-11-04 10:19:30 -05:00
' heroClass '
2014-11-01 17:15:57 -04:00
]
2014-11-04 10:19:30 -05:00
2014-11-01 17:15:57 -04:00
itemFetcher = new CocoCollection ( [ ] , { url: ' /db/thang.type?view=items ' , project: project , model: ThangType } )
itemFetcher.skip = 0
itemFetcher . fetch ( { data: { skip: 0 , limit: PAGE_SIZE } } )
@ listenTo itemFetcher , ' sync ' , @ onItemsFetched
@ supermodel . loadCollection ( itemFetcher , ' items ' )
@idToItem = { }
onItemsFetched: (itemFetcher) ->
gemsOwned = me . gems ( )
needMore = itemFetcher . models . length is PAGE_SIZE
for model in itemFetcher . models
2014-11-11 01:07:55 -05:00
model.owned = me . ownsItem model . get ( ' original ' )
continue unless ( cost = model . get ( ' gems ' ) ) or model . owned
2014-11-01 17:15:57 -04:00
category = slotToCategory [ model . getAllowedSlots ( ) [ 0 ] ] or ' misc '
@ itemCategoryCollections [ category ] ? = new Backbone . Collection ( )
collection = @ itemCategoryCollections [ category ]
2014-11-26 12:22:30 -05:00
collection.comparator = (m) -> m . get ( ' tier ' ) ? m . get ( ' gems ' )
2014-11-01 17:15:57 -04:00
collection . add ( model )
model.name = utils . i18n model . attributes , ' name '
model.affordable = cost <= gemsOwned
2014-11-11 01:07:55 -05:00
model.silhouetted = not model . owned and model . isSilhouettedItem ( )
model.level = model . levelRequiredForItem ( ) if model . get ( ' tier ' ) ?
2014-11-24 13:51:20 -05:00
model.unequippable = not _ . intersection ( me . getHeroClasses ( ) , model . getAllowedHeroClasses ( ) ) . length
2014-11-21 19:23:26 -05:00
model.comingSoon = not model . getFrontFacingStats ( ) . props . length and not _ . size ( model . getFrontFacingStats ( ) . stats ) and not model . owned # Temp: while there are placeholder items
2014-11-01 17:15:57 -04:00
@ idToItem [ model . id ] = model
2014-09-17 21:56:08 -04:00
2014-11-01 17:15:57 -04:00
if needMore
itemFetcher . skip += PAGE_SIZE
itemFetcher . fetch ( { data: { skip: itemFetcher . skip , limit: PAGE_SIZE } } )
2014-11-04 10:19:30 -05:00
2014-09-17 21:56:08 -04:00
getRenderData: (context={}) ->
context = super ( context )
2014-11-01 17:15:57 -04:00
context.itemCategoryCollections = @ itemCategoryCollections
context.itemCategories = _ . keys @ itemCategoryCollections
context.itemCategoryNames = ( $ . i18n . t " items. #{ category } " for category in context . itemCategories )
context.gems = me . gems ( )
2014-09-17 21:56:08 -04:00
context
afterRender: ->
super ( )
return unless @ supermodel . finished ( )
Backbone . Mediator . publish ' audio-player:play-sound ' , trigger: ' game-menu-open ' , volume: 1
2014-11-01 17:15:57 -04:00
@ $el . find ( ' .nano:visible ' ) . nanoScroller ( { alwaysVisible: true } )
@itemDetailsView = new ItemDetailsView ( )
@ insertSubView ( @ itemDetailsView )
2014-11-21 19:23:26 -05:00
@ $el . find ( " a[href= ' # item-category-armor ' ] " ) . click ( ) # Start on armor tab, if it's there.
2014-09-17 21:56:08 -04:00
onHidden: ->
super ( )
Backbone . Mediator . publish ' audio-player:play-sound ' , trigger: ' game-menu-close ' , volume: 1
2014-11-04 10:19:30 -05:00
2014-11-01 17:15:57 -04:00
#- Click events
2014-11-04 10:19:30 -05:00
2014-11-01 17:15:57 -04:00
onItemClicked: (e) ->
return if $ ( e . target ) . closest ( ' .unlock-button ' ) . length
2014-11-26 09:58:23 -05:00
@ playSound ' menu-button-click '
2014-11-01 17:15:57 -04:00
itemEl = $ ( e . target ) . closest ( ' .item ' )
wasSelected = itemEl . hasClass ( ' selected ' )
@ $el . find ( ' .item.selected ' ) . removeClass ( ' selected ' )
if wasSelected
item = null
else
item = @ idToItem [ itemEl . data ( ' item-id ' ) ]
2014-11-11 01:07:55 -05:00
if item . silhouetted and not item . owned
2014-11-01 17:15:57 -04:00
item = null
else
itemEl . addClass ( ' selected ' ) unless wasSelected
@ itemDetailsView . setItem ( item )
2014-11-04 10:19:30 -05:00
2014-11-01 17:15:57 -04:00
onTabClicked: (e) ->
2014-11-26 09:58:23 -05:00
@ playSound ' game-menu-tab-switch '
2014-12-01 20:33:37 -05:00
nano = $ ( $ ( e . target ) . attr ( ' href ' ) ) . find ( ' .nano ' )
nano . nanoScroller ( { alwaysVisible: true } )
@paneNanoContent = nano . find ( ' .nano-content ' )
@ onScrollItemPane ( )
onScrollItemPane: ->
# dynamically load visible items when the user scrolls enough to see them
items = @ paneNanoContent . find ( ' .item:not(.loaded) ' )
threshold = @ paneNanoContent . height ( ) + 100
for itemEl in items
itemEl = $ ( itemEl )
if itemEl . position ( ) . top < threshold
$ ( itemEl ) . addClass ( ' loaded ' )
item = @ idToItem [ itemEl . data ( ' item-id ' ) ]
itemEl . find ( ' .item-silhouette, .item-img ' ) . attr ( ' src ' , item . getPortraitURL ( ) )
2014-11-01 17:15:57 -04:00
onUnlockButtonClicked: (e) ->
2014-11-24 13:51:20 -05:00
e . stopPropagation ( )
2014-11-10 18:24:05 -05:00
button = $ ( e . target ) . closest ( ' button ' )
2014-11-24 13:51:20 -05:00
item = @ idToItem [ button . data ( ' item-id ' ) ]
affordable = item . affordable
if not affordable
2014-11-26 09:58:23 -05:00
@ playSound ' menu-button-click '
2014-11-24 13:51:20 -05:00
@ askToBuyGems button
else if button . hasClass ( ' confirm ' )
2014-11-26 09:58:23 -05:00
@ playSound ' menu-button-unlock-end '
2014-11-01 17:15:57 -04:00
purchase = Purchase . makeFor ( item )
purchase . save ( )
2014-11-04 10:19:30 -05:00
2014-11-01 17:15:57 -04:00
#- set local changes to mimic what should happen on the server...
purchased = me . get ( ' purchased ' ) ? { }
purchased . items ? = [ ]
purchased . items . push ( item . get ( ' original ' ) )
item.owned = true
me . set ( ' purchased ' , purchased )
me . set ( ' spent ' , ( me . get ( ' spent ' ) ? 0 ) + item . get ( ' gems ' ) )
2014-11-04 10:19:30 -05:00
2014-11-01 17:15:57 -04:00
#- ...then rerender key bits
@ renderSelectors ( " .item[data-item-id= ' #{ item . id } ' ] " , " # gems-count " )
@ itemDetailsView . render ( )
2014-11-21 19:23:26 -05:00
Backbone . Mediator . publish ' store:item-purchased ' , item: item , itemSlug: item . get ( ' slug ' )
2014-11-01 17:15:57 -04:00
else
2014-11-26 09:58:23 -05:00
@ playSound ' menu-button-unlock-start '
2014-11-01 17:15:57 -04:00
button . addClass ( ' confirm ' ) . text ( $ . i18n . t ( ' play.confirm ' ) )
@ $el . one ' click ' , (e) ->
button . removeClass ( ' confirm ' ) . text ( $ . i18n . t ( ' play.unlock ' ) ) if e . target isnt button [ 0 ]
2014-11-24 13:51:20 -05:00
askToBuyGems: (unlockButton) ->
if me . getGemPromptGroup ( ) is ' no-prompt '
return @ openModalView new BuyGemsModal ( )
@ $el . find ( ' .unlock-button ' ) . popover ' destroy '
popoverTemplate = buyGemsPromptTemplate { }
unlockButton . popover (
animation: true
trigger: ' manual '
content: ' ' # template has it
container: @ $el
template: popoverTemplate
) . popover ' show '
popover = unlockButton . data ( ' bs.popover ' )
popover ? . $tip ? . i18n ( )
onBuyGemsPromptButtonClicked: (e) ->
2014-11-26 09:58:23 -05:00
@ playSound ' menu-button-click '
2014-11-24 13:51:20 -05:00
@ openModalView new BuyGemsModal ( )
onClickedSomewhere: (e) ->
return if @ destroyed
@ $el . find ( ' .unlock-button ' ) . popover ' destroy '
destroy: ->
@ $el . find ( ' .unlock-button ' ) . popover ' destroy '
super ( )