mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-23 19:32:03 -04:00
Set up the PlayHeroesModal, and hooked it into the world map.
This commit is contained in:
parent
c48b155413
commit
c660053dea
8 changed files with 570 additions and 24 deletions
BIN
app/assets/images/pages/play/modal/confirm-button.png
Normal file
BIN
app/assets/images/pages/play/modal/confirm-button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
BIN
app/assets/images/pages/play/modal/play-heroes-background.png
Normal file
BIN
app/assets/images/pages/play/modal/play-heroes-background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
|
@ -55,6 +55,7 @@
|
||||||
confirm: "Confirm"
|
confirm: "Confirm"
|
||||||
owned: "Owned" # For items you own
|
owned: "Owned" # For items you own
|
||||||
locked: "Locked"
|
locked: "Locked"
|
||||||
|
available: "Available"
|
||||||
skills_granted: "Skills Granted" # Property documentation details
|
skills_granted: "Skills Granted" # Property documentation details
|
||||||
heroes: "Heroes" # Tooltip on hero shop button from /play
|
heroes: "Heroes" # Tooltip on hero shop button from /play
|
||||||
achievements: "Achievements" # Tooltip on achievement list button from /play
|
achievements: "Achievements" # Tooltip on achievement list button from /play
|
||||||
|
@ -312,6 +313,9 @@
|
||||||
io_blurb: "Simple but obscure."
|
io_blurb: "Simple but obscure."
|
||||||
status: "Status"
|
status: "Status"
|
||||||
weapons: "Weapons"
|
weapons: "Weapons"
|
||||||
|
weapons_warrior: "Swords - Short Range, No Magic"
|
||||||
|
weapons_ranger: "Crossbows, Guns - Long Range, No Magic"
|
||||||
|
weapons_wizard: "Wands, Staffs - Long Range, Magic"
|
||||||
attack: "Damage" # Can also translate as "Attack"
|
attack: "Damage" # Can also translate as "Attack"
|
||||||
health: "Health"
|
health: "Health"
|
||||||
speed: "Speed"
|
speed: "Speed"
|
||||||
|
|
|
@ -1,4 +1,328 @@
|
||||||
|
@import "app/styles/mixins"
|
||||||
|
@import "app/styles/bootstrap/variables"
|
||||||
|
|
||||||
|
$heroCanvasHeight: 265px
|
||||||
|
|
||||||
#play-heroes-modal
|
#play-heroes-modal
|
||||||
.hero-view
|
|
||||||
color: black
|
|
||||||
|
|
||||||
|
//- Clear modal defaults
|
||||||
|
|
||||||
|
.modal-dialog
|
||||||
|
padding: 0
|
||||||
|
width: 820px
|
||||||
|
height: 658px
|
||||||
|
|
||||||
|
|
||||||
|
//- Background
|
||||||
|
|
||||||
|
#play-heroes-background
|
||||||
|
position: absolute
|
||||||
|
top: -59px
|
||||||
|
left: -20px
|
||||||
|
|
||||||
|
|
||||||
|
//- Header
|
||||||
|
|
||||||
|
h1
|
||||||
|
position: absolute
|
||||||
|
left: 154px
|
||||||
|
top: 25px
|
||||||
|
margin: 0
|
||||||
|
width: 450px
|
||||||
|
text-align: center
|
||||||
|
color: rgb(254,188,68)
|
||||||
|
font-size: 38px
|
||||||
|
text-shadow: black 4px 4px 0, black -4px -4px 0, black 4px -4px 0, black -4px 4px 0, black 4px 0px 0, black 0px -4px 0, black -4px 0px 0, black 0px 4px 0
|
||||||
|
|
||||||
|
|
||||||
|
//- Close modal button
|
||||||
|
|
||||||
|
#close-modal
|
||||||
|
position: absolute
|
||||||
|
left: 615px
|
||||||
|
top: 17px
|
||||||
|
width: 60px
|
||||||
|
height: 60px
|
||||||
|
color: white
|
||||||
|
text-align: center
|
||||||
|
font-size: 30px
|
||||||
|
padding-top: 15px
|
||||||
|
cursor: pointer
|
||||||
|
@include rotate(-3deg)
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color: yellow
|
||||||
|
|
||||||
|
|
||||||
|
//- Carousel character portraits
|
||||||
|
|
||||||
|
#hero-carousel
|
||||||
|
width: 750px
|
||||||
|
height: 386px
|
||||||
|
position: absolute
|
||||||
|
left: 34px
|
||||||
|
top: 117px
|
||||||
|
|
||||||
|
.carousel-indicator-container
|
||||||
|
position: relative
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
.carousel-indicators
|
||||||
|
position: static
|
||||||
|
width: 100%
|
||||||
|
margin-left: 0
|
||||||
|
|
||||||
|
.hero-indicator
|
||||||
|
width: 104px
|
||||||
|
height: 98px
|
||||||
|
margin: 0 -11px
|
||||||
|
position: relative
|
||||||
|
background: url(/images/pages/play/modal/hero_portrait_picker_inactive.png)
|
||||||
|
border: none
|
||||||
|
&.active
|
||||||
|
background: url(/images/pages/play/modal/hero_portrait_picker_active.png)
|
||||||
|
z-index: 5
|
||||||
|
|
||||||
|
.hero-avatar
|
||||||
|
width: 61px
|
||||||
|
height: 61px
|
||||||
|
background-size: contain
|
||||||
|
position: relative
|
||||||
|
left: 21px
|
||||||
|
top: 18px
|
||||||
|
|
||||||
|
&.locked
|
||||||
|
.hero-avatar
|
||||||
|
@include filter(contrast(50%) brightness(65%))
|
||||||
|
|
||||||
|
.lock-indicator
|
||||||
|
position: absolute
|
||||||
|
width: 40%
|
||||||
|
left: 30%
|
||||||
|
top: 30%
|
||||||
|
@include filter(invert(90%))
|
||||||
|
|
||||||
|
|
||||||
|
//- Small transformations to jumble the hero icons a little
|
||||||
|
|
||||||
|
.hero-index-0
|
||||||
|
transform: rotate(-5deg)
|
||||||
|
z-index: 2
|
||||||
|
|
||||||
|
.hero-index-1
|
||||||
|
top: -3px
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
.hero-index-2
|
||||||
|
top: -3px
|
||||||
|
transform: rotate(5deg)
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
.hero-index-3
|
||||||
|
transform: rotate(-1deg)
|
||||||
|
z-index: 0
|
||||||
|
|
||||||
|
.hero-index-4
|
||||||
|
transform: rotate(3deg)
|
||||||
|
|
||||||
|
.hero-index-5
|
||||||
|
z-index: 0
|
||||||
|
|
||||||
|
.hero-index-6
|
||||||
|
transform: rotate(6deg)
|
||||||
|
top: -8px
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
.hero-index-8
|
||||||
|
transform: rotate(4deg)
|
||||||
|
|
||||||
|
|
||||||
|
//- Carousel panel
|
||||||
|
|
||||||
|
#hero-carousel
|
||||||
|
.hero-item
|
||||||
|
|
||||||
|
&.locked
|
||||||
|
@include opacity(0.6)
|
||||||
|
|
||||||
|
canvas, .hero-feature-image
|
||||||
|
width: 334px
|
||||||
|
height: $heroCanvasHeight
|
||||||
|
float: left
|
||||||
|
|
||||||
|
.hero-stats
|
||||||
|
width: 384px
|
||||||
|
height: $heroCanvasHeight
|
||||||
|
float: left
|
||||||
|
|
||||||
|
.hero-feature-image
|
||||||
|
display: none
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
img
|
||||||
|
height: $heroCanvasHeight
|
||||||
|
|
||||||
|
.hero-stats
|
||||||
|
color: white
|
||||||
|
|
||||||
|
h2
|
||||||
|
margin-top: 0px
|
||||||
|
color: white
|
||||||
|
|
||||||
|
.hero-description
|
||||||
|
margin-bottom: 10px
|
||||||
|
|
||||||
|
.hero-stat-row
|
||||||
|
margin: 5px 0
|
||||||
|
|
||||||
|
.stat-label
|
||||||
|
float: left
|
||||||
|
width: 100px
|
||||||
|
color: rgb(203,170,148)
|
||||||
|
|
||||||
|
.stat-value
|
||||||
|
display: inline-block
|
||||||
|
width: 280px
|
||||||
|
color: rgb(244,189,68)
|
||||||
|
|
||||||
|
.stat-progress
|
||||||
|
background: rgb(32,27,22)
|
||||||
|
height: 15px
|
||||||
|
padding: 4px 5px
|
||||||
|
border-radius: 16px
|
||||||
|
position: relative
|
||||||
|
top: 2px
|
||||||
|
left: -3px
|
||||||
|
width: 70%
|
||||||
|
|
||||||
|
.stat-progress-bar
|
||||||
|
height: 7px
|
||||||
|
border-radius: 7px
|
||||||
|
|
||||||
|
|
||||||
|
&.attack .stat-progress-bar
|
||||||
|
background: purple
|
||||||
|
|
||||||
|
&.health .stat-progress-bar
|
||||||
|
background: red
|
||||||
|
|
||||||
|
&.speed .stat-progress-bar
|
||||||
|
background: green
|
||||||
|
|
||||||
|
|
||||||
|
//- Carousel switch buttons
|
||||||
|
|
||||||
|
a.left, a.right
|
||||||
|
color: rgb(74,61,51)
|
||||||
|
position: absolute
|
||||||
|
top: 195px
|
||||||
|
width: 40px
|
||||||
|
height: 84px
|
||||||
|
font-size: 24px
|
||||||
|
|
||||||
|
.glyphicon
|
||||||
|
position: relative
|
||||||
|
top: 27px
|
||||||
|
left: 8px
|
||||||
|
|
||||||
|
&:hover, &:active
|
||||||
|
color: rgb(126,105,88)
|
||||||
|
|
||||||
|
a.right
|
||||||
|
right: -49px
|
||||||
|
|
||||||
|
a.left
|
||||||
|
left: -46px
|
||||||
|
.glyphicon
|
||||||
|
@include scaleXY(-1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
//- Programming select box
|
||||||
|
|
||||||
|
.form
|
||||||
|
position: absolute
|
||||||
|
left: 32px
|
||||||
|
top: 527px
|
||||||
|
width: 541px
|
||||||
|
height: 102px
|
||||||
|
padding: 10px 40px
|
||||||
|
|
||||||
|
.help-block
|
||||||
|
color: rgb(51,51,51)
|
||||||
|
font-size: 14px
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
|
select
|
||||||
|
font-size: 18px
|
||||||
|
|
||||||
|
.fancy-select
|
||||||
|
display: inline-block
|
||||||
|
width: 100%
|
||||||
|
|
||||||
|
.options
|
||||||
|
text-transform: none
|
||||||
|
|
||||||
|
.trigger, .options
|
||||||
|
background-color: rgb(239,232,217)
|
||||||
|
width: 100%
|
||||||
|
color: black
|
||||||
|
|
||||||
|
.trigger
|
||||||
|
text-transform: uppercase
|
||||||
|
border: 3px solid black
|
||||||
|
font-size: 16px
|
||||||
|
padding: 5px 10px
|
||||||
|
|
||||||
|
//- the little triangle on the right side of the fancy select box
|
||||||
|
&:after
|
||||||
|
border: 8px solid transparent
|
||||||
|
border-top-color: black
|
||||||
|
top: 13px
|
||||||
|
right: 11px
|
||||||
|
|
||||||
|
.options
|
||||||
|
padding-left: 5px
|
||||||
|
|
||||||
|
.selected
|
||||||
|
color: black
|
||||||
|
|
||||||
|
.hover
|
||||||
|
color: black
|
||||||
|
background-color: #abc
|
||||||
|
|
||||||
|
.options
|
||||||
|
li
|
||||||
|
padding-left: 40px
|
||||||
|
background: transparent url(/images/common/code_languages/javascript_small.png) no-repeat left center
|
||||||
|
background-size: 32px 32px
|
||||||
|
|
||||||
|
&[data-value="python"]
|
||||||
|
background-image: url(/images/common/code_languages/python_small.png)
|
||||||
|
&[data-value="coffeescript"]
|
||||||
|
background-image: url(/images/common/code_languages/coffeescript_small.png)
|
||||||
|
&[data-value="clojure"]
|
||||||
|
background-image: url(/images/common/code_languages/clojure_small.png)
|
||||||
|
&[data-value="lua"]
|
||||||
|
background-image: url(/images/common/code_languages/lua_small.png)
|
||||||
|
&[data-value="io"]
|
||||||
|
background-image: url(/images/common/code_languages/io_small.png)
|
||||||
|
|
||||||
|
#confirm-button
|
||||||
|
background: url(/images/pages/play/modal/confirm-button.png)
|
||||||
|
width: 209px
|
||||||
|
height: 110px
|
||||||
|
position: absolute
|
||||||
|
left: 588px
|
||||||
|
top: 522px
|
||||||
|
padding: 36px 0
|
||||||
|
text-align: center
|
||||||
|
text-transform: uppercase
|
||||||
|
font-size: 26px
|
||||||
|
font-family: Open Sans Condensed
|
||||||
|
color: white
|
||||||
|
|
||||||
|
|
||||||
|
body.ipad #play-heroes-modal
|
||||||
|
// iPad is Python-only for now, and has its own reset button.
|
||||||
|
.form
|
||||||
|
display: none
|
||||||
|
|
|
@ -1,7 +1,63 @@
|
||||||
extends /templates/modal/modal_base
|
.modal-dialog
|
||||||
|
.modal-content
|
||||||
|
|
||||||
block modal-header-content
|
img(src="/images/pages/play/modal/play-heroes-background.png")#play-heroes-background
|
||||||
h3(data-i18n="play.heroes") Heroes
|
|
||||||
|
h1(data-i18n="choose_hero.choose_hero")
|
||||||
|
|
||||||
block modal-body-content
|
div#close-modal
|
||||||
p TODO: show all dem heroes
|
span.glyphicon.glyphicon-remove
|
||||||
|
|
||||||
|
#hero-carousel.carousel.slide(data-interval=0)
|
||||||
|
.carousel-indicator-container
|
||||||
|
ol.carousel-indicators
|
||||||
|
for hero, index in heroes
|
||||||
|
li(data-hero-id=hero.get('original'), title=hero.get('name'), data-slide-to=index, data-target="#hero-carousel", class="hero-indicator hero-index-" + index + (hero.locked ? " locked" : ""))
|
||||||
|
.hero-avatar
|
||||||
|
if hero.locked
|
||||||
|
img.lock-indicator(src="/images/pages/game-menu/lock.png")
|
||||||
|
.carousel-inner
|
||||||
|
for hero in heroes
|
||||||
|
div(class="item hero-item" + (hero.locked ? " locked" : ""), data-hero-id=hero.get('original'))
|
||||||
|
canvas.hero-canvas
|
||||||
|
.hero-feature-image
|
||||||
|
img
|
||||||
|
.hero-stats
|
||||||
|
h2= hero.name
|
||||||
|
.hero-description= hero.description
|
||||||
|
|
||||||
|
.hero-stat-row
|
||||||
|
.stat-label(data-i18n='choose_hero.status')
|
||||||
|
.stat-value(data-i18n=hero.locked ? 'play.locked' : 'play.available')
|
||||||
|
|
||||||
|
.hero-stat-row
|
||||||
|
.stat-label(data-i18n='choose_hero.weapons')
|
||||||
|
.stat-value(data-i18n='choose_hero.weapons_'+hero.class)
|
||||||
|
|
||||||
|
if hero.stats
|
||||||
|
if hero.stats.skills.length
|
||||||
|
.hero-stat-row
|
||||||
|
.stat-label(data-i18n='choose_hero.skills')
|
||||||
|
.stat-value= hero.stats.skills.join(', ')
|
||||||
|
for stat in ['attack', 'health', 'speed']
|
||||||
|
.hero-stat-row(class=stat)
|
||||||
|
.stat-label(data-i18n='choose_hero.'+stat)
|
||||||
|
.stat-value
|
||||||
|
.stat-progress
|
||||||
|
.stat-progress-bar(style="width: " + (parseInt(hero.stats[stat]*100)) + "%")
|
||||||
|
|
||||||
|
a.left(role="button", data-slide="prev", href="#hero-carousel")
|
||||||
|
span.glyphicon.glyphicon-play
|
||||||
|
a.right(role="button", data-slide="next", href="#hero-carousel")
|
||||||
|
span.glyphicon.glyphicon-play
|
||||||
|
|
||||||
|
|
||||||
|
.form
|
||||||
|
.form-group.select-group
|
||||||
|
span.help-block(data-i18n="choose_hero.programming_language_description") Which programming language do you want to use?
|
||||||
|
//label.control-label(for="option-code-language", data-i18n="choose_hero.programming_language") Programming Language
|
||||||
|
select#option-code-language(name="code-language")
|
||||||
|
for option in codeLanguages
|
||||||
|
option(value=option.id, selected=codeLanguage === option.id)= option.name
|
||||||
|
|
||||||
|
a#confirm-button(data-i18n=confirmButtonI18N)
|
||||||
|
|
|
@ -2,46 +2,208 @@ ModalView = require 'views/kinds/ModalView'
|
||||||
template = require 'templates/play/modal/play-heroes-modal'
|
template = require 'templates/play/modal/play-heroes-modal'
|
||||||
CocoCollection = require 'collections/CocoCollection'
|
CocoCollection = require 'collections/CocoCollection'
|
||||||
ThangType = require 'models/ThangType'
|
ThangType = require 'models/ThangType'
|
||||||
#HeroView = require 'views/game-menu/HeroView'
|
SpriteBuilder = require 'lib/sprites/SpriteBuilder'
|
||||||
|
AudioPlayer = require 'lib/AudioPlayer'
|
||||||
|
utils = require 'lib/utils'
|
||||||
|
|
||||||
module.exports = class PlayHeroesModal extends ModalView
|
module.exports = class PlayHeroesModal extends ModalView
|
||||||
className: 'modal fade play-modal'
|
className: 'modal fade play-modal'
|
||||||
template: template
|
template: template
|
||||||
modalWidthPercent: 90
|
|
||||||
id: 'play-heroes-modal'
|
id: 'play-heroes-modal'
|
||||||
#instant: true
|
|
||||||
|
|
||||||
#events:
|
events:
|
||||||
# 'change input.select': 'onSelectionChanged'
|
'slide.bs.carousel #hero-carousel': 'onHeroChanged'
|
||||||
|
'change #option-code-language': 'onCodeLanguageChanged'
|
||||||
|
'click #close-modal': 'hide'
|
||||||
|
'click #confirm-button': 'saveAndHide'
|
||||||
|
|
||||||
|
shortcuts:
|
||||||
|
'left': -> @$el.find('#hero-carousel').carousel('prev') if @heroes.models.length and not @$el.hasClass 'secret'
|
||||||
|
'right': -> @$el.find('#hero-carousel').carousel('next') if @heroes.models.length and not @$el.hasClass 'secret'
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
super options
|
super options
|
||||||
|
options ?= {}
|
||||||
|
@confirmButtonI18N = options.confirmButtonI18N ? "common.save"
|
||||||
@heroes = new CocoCollection([], {model: ThangType})
|
@heroes = new CocoCollection([], {model: ThangType})
|
||||||
@heroes.url = '/db/thang.type?view=heroes&project=name,description,components,original,rasterIcon'
|
@heroes.url = '/db/thang.type?view=heroes'
|
||||||
|
@heroes.setProjection ['original','name','slug','soundTriggers','featureImage','gems','heroClass','description']
|
||||||
|
@listenToOnce @heroes, 'sync', @onHeroesLoaded
|
||||||
@supermodel.loadCollection(@heroes, 'heroes')
|
@supermodel.loadCollection(@heroes, 'heroes')
|
||||||
|
@stages = {}
|
||||||
|
@session = options.session
|
||||||
|
|
||||||
|
onHeroesLoaded: ->
|
||||||
|
for hero in @heroes.models
|
||||||
|
hero.name = utils.i18n hero.attributes, 'extendedName' # or whatever the property name ends up being
|
||||||
|
hero.name ?= utils.i18n hero.attributes, 'name'
|
||||||
|
hero.description = utils.i18n hero.attributes, 'description'
|
||||||
|
original = hero.get('original')
|
||||||
|
hero.locked = original not in [ThangType.heroes.captain, ThangType.heroes.knight] and not me.ownsHero(original)
|
||||||
|
hero.class = (hero.get('heroClass') or 'warrior').toLowerCase()
|
||||||
|
hero.stats = hero.getHeroStats()
|
||||||
|
|
||||||
getRenderData: (context={}) ->
|
getRenderData: (context={}) ->
|
||||||
context = super(context)
|
context = super(context)
|
||||||
context.heroes = @heroes.models
|
context.heroes = @heroes.models
|
||||||
|
context.level = @options.level
|
||||||
|
context.codeLanguages = [
|
||||||
|
{id: 'python', name: 'Python (Default)'}
|
||||||
|
{id: 'javascript', name: 'JavaScript'}
|
||||||
|
{id: 'coffeescript', name: 'CoffeeScript'}
|
||||||
|
{id: 'clojure', name: 'Clojure (Experimental)'}
|
||||||
|
{id: 'lua', name: 'Lua (Experimental)'}
|
||||||
|
{id: 'io', name: 'Io (Experimental)'}
|
||||||
|
]
|
||||||
|
context.codeLanguage = @codeLanguage = @options?.session?.get('codeLanguage') ? me.get('aceConfig')?.language ? 'python'
|
||||||
|
context.confirmButtonI18N = @confirmButtonI18N
|
||||||
context
|
context
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
super()
|
super()
|
||||||
return unless @supermodel.finished()
|
return unless @supermodel.finished()
|
||||||
|
heroes = @heroes.models
|
||||||
|
@$el.find('.hero-indicator').each ->
|
||||||
|
heroID = $(@).data('hero-id')
|
||||||
|
hero = _.find heroes, (hero) -> hero.get('original') is heroID
|
||||||
|
$(@).find('.hero-avatar').css('background-image', "url(#{hero.getPortraitURL()})").tooltip()
|
||||||
|
@canvasWidth = 313 # @$el.find('canvas').width() # unreliable, whatever
|
||||||
|
@canvasHeight = @$el.find('canvas').height()
|
||||||
|
heroConfig = @options?.session?.get('heroConfig') ? me.get('heroConfig') ? {}
|
||||||
|
heroIndex = Math.max 0, _.findIndex(heroes, ((hero) -> hero.get('original') is heroConfig.thangType))
|
||||||
|
@$el.find(".hero-item:nth-child(#{heroIndex + 1}), .hero-indicator:nth-child(#{heroIndex + 1})").addClass('active')
|
||||||
|
@onHeroChanged direction: null, relatedTarget: @$el.find('.hero-item')[heroIndex]
|
||||||
|
@$el.find('.hero-stat').tooltip()
|
||||||
|
@buildCodeLanguages()
|
||||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
||||||
#@addHeroViews()
|
|
||||||
|
onHeroChanged: (e) ->
|
||||||
|
direction = e.direction # 'left' or 'right'
|
||||||
|
heroItem = $(e.relatedTarget)
|
||||||
|
hero = _.find @heroes.models, (hero) -> hero.get('original') is heroItem.data('hero-id')
|
||||||
|
return console.error "Couldn't find hero from heroItem:", heroItem unless hero
|
||||||
|
heroIndex = heroItem.index()
|
||||||
|
hero = @loadHero hero, heroIndex
|
||||||
|
@preloadHero heroIndex + 1
|
||||||
|
@preloadHero heroIndex - 1
|
||||||
|
@selectedHero = hero unless hero.locked
|
||||||
|
Backbone.Mediator.publish 'level:hero-selection-updated', hero: @selectedHero
|
||||||
|
$('#choose-inventory-button').prop 'disabled', hero.locked
|
||||||
|
|
||||||
|
getFullHero: (original) ->
|
||||||
|
url = "/db/thang.type/#{original}/version"
|
||||||
|
if fullHero = @supermodel.getModel url
|
||||||
|
return fullHero
|
||||||
|
fullHero = new ThangType()
|
||||||
|
fullHero.setURL url
|
||||||
|
fullHero = (@supermodel.loadModel fullHero, 'thang').model
|
||||||
|
fullHero
|
||||||
|
|
||||||
|
preloadHero: (heroIndex) ->
|
||||||
|
return unless hero = @heroes.models[heroIndex]
|
||||||
|
@loadHero hero, heroIndex, true
|
||||||
|
|
||||||
|
loadHero: (hero, heroIndex, preloading=false) ->
|
||||||
|
createjs.Ticker.removeEventListener 'tick', stage for stage in _.values @stages
|
||||||
|
if featureImage = hero.get 'featureImage'
|
||||||
|
$(".hero-item[data-hero-id='#{hero.get('original')}'] canvas").hide()
|
||||||
|
$(".hero-item[data-hero-id='#{hero.get('original')}'] .hero-feature-image").show().find('img').prop('src', '/file/' + featureImage)
|
||||||
|
@playSelectionSound hero unless preloading
|
||||||
|
return hero
|
||||||
|
createjs.Ticker.setFPS 30 # In case we paused it from being inactive somewhere else
|
||||||
|
if stage = @stages[heroIndex]
|
||||||
|
unless preloading
|
||||||
|
_.defer -> createjs.Ticker.addEventListener 'tick', stage # Deferred, otherwise it won't start updating for some reason.
|
||||||
|
@playSelectionSound hero
|
||||||
|
return hero
|
||||||
|
fullHero = @getFullHero hero.get 'original'
|
||||||
|
onLoaded = =>
|
||||||
|
return unless canvas = $(".hero-item[data-hero-id='#{fullHero.get('original')}'] canvas")
|
||||||
|
canvas.show().prop width: @canvasWidth, height: @canvasHeight
|
||||||
|
builder = new SpriteBuilder(fullHero)
|
||||||
|
movieClip = builder.buildMovieClip(fullHero.get('actions').attack?.animation ? fullHero.get('actions').idle.animation)
|
||||||
|
movieClip.scaleX = movieClip.scaleY = canvas.prop('height') / 120 # Average hero height is ~110px tall at normal resolution
|
||||||
|
if fullHero.get('name') in ['Knight', 'Robot Walker'] # These are too big, so shrink them.
|
||||||
|
movieClip.scaleX *= 0.7
|
||||||
|
movieClip.scaleY *= 0.7
|
||||||
|
movieClip.regX = -fullHero.get('positions').registration.x
|
||||||
|
movieClip.regY = -fullHero.get('positions').registration.y
|
||||||
|
movieClip.x = canvas.prop('width') * 0.5
|
||||||
|
movieClip.y = canvas.prop('height') * 0.925 # This is where the feet go.
|
||||||
|
stage = new createjs.Stage(canvas[0])
|
||||||
|
@stages[heroIndex] = stage
|
||||||
|
stage.addChild movieClip
|
||||||
|
stage.update()
|
||||||
|
movieClip.gotoAndPlay 0
|
||||||
|
unless preloading
|
||||||
|
createjs.Ticker.addEventListener 'tick', stage
|
||||||
|
@playSelectionSound hero
|
||||||
|
if fullHero.loaded
|
||||||
|
_.defer onLoaded
|
||||||
|
else
|
||||||
|
@listenToOnce fullHero, 'sync', onLoaded
|
||||||
|
fullHero
|
||||||
|
|
||||||
|
playSelectionSound: (hero) ->
|
||||||
|
return if @$el.hasClass 'secret'
|
||||||
|
@currentSoundInstance?.stop()
|
||||||
|
return unless sounds = hero.get('soundTriggers')?.selected
|
||||||
|
return unless sound = sounds[Math.floor Math.random() * sounds.length]
|
||||||
|
name = AudioPlayer.nameForSoundReference sound
|
||||||
|
AudioPlayer.preloadSoundReference sound
|
||||||
|
@currentSoundInstance = AudioPlayer.playSound name, 1
|
||||||
|
@currentSoundInstance
|
||||||
|
|
||||||
|
buildCodeLanguages: ->
|
||||||
|
$select = @$el.find('#option-code-language')
|
||||||
|
$select.fancySelect().parent().find('.options li').each ->
|
||||||
|
languageName = $(@).text()
|
||||||
|
languageID = $(@).data('value')
|
||||||
|
blurb = $.i18n.t("choose_hero.#{languageID}_blurb")
|
||||||
|
$(@).text("#{languageName} - #{blurb}")
|
||||||
|
|
||||||
|
onCodeLanguageChanged: (e) ->
|
||||||
|
@codeLanguage = @$el.find('#option-code-language').val()
|
||||||
|
@codeLanguageChanged = true
|
||||||
|
|
||||||
|
saveAndHide: ->
|
||||||
|
hero = @selectedHero.get('original')
|
||||||
|
|
||||||
|
if @session
|
||||||
|
changed = @updateHeroConfig(@session, hero)
|
||||||
|
if @session.get('codeLanguage') isnt @codeLanguage
|
||||||
|
@session.set('codeLanguage', @codeLanguage)
|
||||||
|
changed = true
|
||||||
|
|
||||||
|
@session.patch() if changed
|
||||||
|
|
||||||
|
changed = @updateHeroConfig(me, hero)
|
||||||
|
aceConfig = _.clone(me.get('aceConfig'))
|
||||||
|
if @codeLanguage isnt aceConfig.language
|
||||||
|
aceConfig.language = @codeLanguage
|
||||||
|
me.set 'aceConfig', aceConfig
|
||||||
|
changed = true
|
||||||
|
|
||||||
|
me.patch() if changed
|
||||||
|
|
||||||
|
@hide()
|
||||||
|
|
||||||
|
updateHeroConfig: (model, hero) ->
|
||||||
|
heroConfig = _.clone(model.get('heroConfig')) or {}
|
||||||
|
if heroConfig.thangType isnt hero
|
||||||
|
heroConfig.thangType = hero
|
||||||
|
model.set('heroConfig', heroConfig)
|
||||||
|
return true
|
||||||
|
|
||||||
onHidden: ->
|
onHidden: ->
|
||||||
super()
|
super()
|
||||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
||||||
|
|
||||||
#addHeroViews: ->
|
destroy: ->
|
||||||
# keys = (hero.id for hero in @heroes.models)
|
for heroIndex, stage of @stages
|
||||||
# heroMap = _.zipObject keys, @heroes.models
|
createjs.Ticker.removeEventListener "tick", stage
|
||||||
# for heroStub in @$el.find('.replace-me')
|
stage.removeAllChildren()
|
||||||
# heroID = $(heroStub).data('hero-id')
|
super()
|
||||||
# hero = heroMap[heroID]
|
|
||||||
# heroView = new HeroView({hero: hero, includes: {name: true, stats: true, props: true}})
|
|
||||||
# heroView.render()
|
|
||||||
# $(heroStub).replaceWith(heroView.$el)
|
|
||||||
# @registerSubView(heroView)
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue