Hooked up hero choice from ChooseHeroView and PlayLevelModal. Tried to fix some oddities with achievements. Fixed .

This commit is contained in:
Nick Winter 2014-09-20 15:18:21 -07:00
parent ae7a2dfe6a
commit ae14bd1ced
17 changed files with 113 additions and 55 deletions

View file

@ -89,9 +89,9 @@ module.exports = class LevelLoader extends CocoClass
loadDependenciesForSession: (session) ->
return unless @level.get('type', true) is 'hero'
heroConfig = session.get('heroConfig')
unless heroConfig
heroConfig = {inventory: {}, thangType: '529ffbf1cf1818f2be000001'} # Temp: assign Tharin as the hero
session.set 'heroConfig', heroConfig
heroConfig ?= me.get('heroConfig')
heroConfig ?= {inventory: {}, thangType: '529ffbf1cf1818f2be000001'} # If we got here not from PlayLevelModal (like level editor preview), assign Tharin as the hero.
session.set 'heroConfig', heroConfig unless _.isEqual heroConfig, session.get('heroConfig')
url = "/db/thang.type/#{heroConfig.thangType}/version?project=name,components,original"
@worldNecessities.push @maybeLoadURL(url, ThangType, 'thang')

View file

@ -59,12 +59,7 @@ _.extend LevelSessionSchema.properties,
screenshot:
type: 'string'
heroConfig: c.object {description: 'Which hero the player is using, equipped with what inventory.'},
inventory:
type: 'object'
description: 'The inventory of the hero: slots to item ThangTypes.'
additionalProperties: c.objectId(description: 'An item ThangType.')
thangType: c.objectId(links: [{rel: 'db', href: '/db/thang.type/{($)}/version'}], title: 'Thang Type', description: 'The ThangType of the hero.', format: 'thang-type')
heroConfig: c.HeroConfigSchema
state: c.object {},
complete:

View file

@ -45,7 +45,7 @@ visa = c.shortString
title: 'US Work Status'
description: 'Are you authorized to work in the US, or do you need visa sponsorship? (If you live in Canada or Australia, mark authorized.)'
enum: ['Authorized to work in the US', 'Need visa sponsorship']
_.extend UserSchema.properties,
email: c.shortString({title: 'Email', format: 'email'})
firstName: c.shortString({title: 'First Name'})
@ -64,6 +64,7 @@ _.extend UserSchema.properties,
music: { type: 'boolean' }
autocastDelay: { type: 'integer' }
lastLevel: { type: 'string' }
heroConfig: c.HeroConfigSchema
emailSubscriptions: c.array {uniqueItems: true}, {'enum': emailSubscriptions}
emails: c.object {title: 'Email Settings', default: generalNews: {enabled: true}, anyNotes: {enabled: true}, recruitNotes: {enabled: true} },
@ -114,7 +115,7 @@ _.extend UserSchema.properties,
simulatedBy: {type: 'integer', minimum: 0 }
simulatedFor: {type: 'integer', minimum: 0 }
jobProfile: c.object {title: 'Job Profile', default: { active: false, lookingFor: 'Full-time', jobTitle: 'Software Developer', city: 'Defaultsville, CA', country: 'USA', skills: ['javascript'], shortDescription: 'Programmer seeking to build great software.', longDescription: '* I write great code.\n* You need great code?\n* Great!' }},
lookingFor: {title: 'Looking For', type: 'string', enum: ['Full-time', 'Part-time', 'Remote', 'Contracting', 'Internship'], description: 'What kind of developer position do you want?'}
jobTitle: {type: 'string', maxLength: 50, title: 'Desired Job Title', description: 'What role are you looking for? Ex.: "Full Stack Engineer", "Front-End Developer", "iOS Developer"' }

View file

@ -202,3 +202,10 @@ me.activity = me.object {description: 'Stats on an activity'},
count: {type: 'integer', minimum: 0}
me.terrainString = me.shortString {enum: ['Grass', 'Dungeon', 'Indoor'], title: 'Terrain', description: 'Which terrain type this is.'}
me.HeroConfigSchema = me.object {description: 'Which hero the player is using, equipped with what inventory.'},
inventory:
type: 'object'
description: 'The inventory of the hero: slots to item ThangTypes.'
additionalProperties: me.objectId(description: 'An item ThangType.')
thangType: me.objectId(links: [{rel: 'db', href: '/db/thang.type/{($)}/version'}], title: 'Thang Type', description: 'The ThangType of the hero.', format: 'thang-type')

View file

@ -38,7 +38,3 @@ module.exports =
'supermodel:load-progress-changed': c.object {required: ['progress']},
progress: {type: 'number', minimum: 0, maximum: 1}
'options:hero-changed': c.object {required: ['hero']},
hero: {type: 'object'}
locked: {type: 'boolean'}

View file

@ -155,4 +155,4 @@ module.exports =
'level:edit-wizard-settings': c.object {}
'level:inventory-changed': c.object {}
'level:hero-config-changed': c.object {}

View file

@ -244,9 +244,10 @@ $user-achievements-scale: 0.8
position: fixed
right: 0px
bottom: 0px
z-index: 9001
cursor: pointer
.popup
cursor: default
left: 600px
.user-level

View file

@ -32,11 +32,13 @@ $heroCanvasHeight: 330px
height: $maxHeroPortraitSize
margin: 0px 3px
background-size: contain
@include transition(0.5s ease)
border: 2px solid black
border-radius: 2px
position: relative
&.initialized
@include transition(0.5s ease)
&.active
border-color: gold

View file

@ -66,14 +66,14 @@ module.exports = class AchievementPopup extends CocoView
super()
@container.prepend @$el
if @popup
@$el.animate
left: 0
@$el.on 'click', (e) =>
@$el.animate
left: 600
, =>
hide = =>
return if @destroyed
@$el.animate {left: 600}, =>
@$el.remove()
@destroy()
@$el.animate left: 0
@$el.on 'click', hide
_.delay hide, 10000 unless $('#editor-achievement-edit-view').length
getContainer: ->
unless @container

View file

@ -50,15 +50,18 @@ module.exports = class ChooseHeroView extends CocoView
afterRender: ->
super()
return unless @supermodel.finished()
@$el.find('.hero-item:first-child, .hero-indicator:first-child').addClass('active')
heroes = @heroes.models
@$el.find('.hero-indicator').each ->
heroID = $(@).data('hero-id')
hero = _.find heroes, (hero) -> hero.get('original') is heroID
$(@).css('background-image', "url(#{hero.getPortraitURL()})").tooltip()
_.defer => $(@).addClass 'initialized'
@canvasWidth = 313 # @$el.find('canvas').width() # unreliable, whatever
@canvasHeight = @$el.find('canvas').height()
@onHeroChanged direction: null, relatedTarget: @$el.find('.hero-item')[0]
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]
onHeroChanged: (e) ->
direction = e.direction # 'left' or 'right'
@ -70,8 +73,10 @@ module.exports = class ChooseHeroView extends CocoView
size = 100 - (50 / 3) * distance
$(@).css width: size, height: size, top: -(100 - size) / 2
heroInfo = temporaryHeroInfo[hero.get('slug')]
locked = heroInfo.status is 'Locked'
hero = @loadHero hero, heroIndex
Backbone.Mediator.publish 'options:hero-changed', hero: hero, locked: heroInfo.status is 'Locked'
@selectedHero = hero unless locked
$('#choose-inventory-button').prop 'disabled', locked
loadHero: (hero, heroIndex) ->
createjs.Ticker.removeEventListener 'tick', stage for stage in _.values @stages
@ -103,6 +108,10 @@ module.exports = class ChooseHeroView extends CocoView
@listenToOnce fullHero, 'sync', onLoaded
fullHero
onHidden: ->
temporaryHeroInfo =
captain:
fullName: 'Captain Anya Weston'

View file

@ -43,5 +43,27 @@ module.exports = class GameMenuModal extends ModalView
onHidden: ->
super()
subview.onHidden?() for subviewKey, subview of @subviews
me.patch()
patchingMe = @updateHeroConfig()
me.patch() unless patchingMe # Might need to patch for options menu
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
updateHeroConfig: ->
sessionHeroConfig = @options.session.get('heroConfig') ? {}
lastHeroConfig = me.get('heroConfig') ? {}
thangType = @subviews.choose_hero_view.selectedHero.get 'original'
inventory = @subviews.inventory_view.getCurrentEquipmentConfig()
patchSession = patchMe = false
props = thangType: thangType, inventory: inventory
for key, val of props when val
patchSession ||= not _.isEqual val, sessionHeroConfig[key]
patchMe ||= not _.isEqual val, lastHeroConfig[key]
sessionHeroConfig[key] = val
lastHeroConfig[key] = val
if patchSession
@options.session.set 'heroConfig', sessionHeroConfig
@options.session.patch success: ->
_.defer -> Backbone.Mediator.publish 'level:hero-config-changed', {}
if patchMe
me.set 'heroConfig', lastHeroConfig
me.patch()
patchMe

View file

@ -24,7 +24,7 @@ module.exports = class InventoryView extends CocoView
initialize: (options) ->
super(arguments...)
@items = new CocoCollection([], {model: ThangType})
@equipment = options.equipment or @options.session?.get('heroConfig')?.inventory or {}
@equipment = options.equipment or @options.session?.get('heroConfig')?.inventory or me.get('heroConfig')?.inventory or {}
@items.url = '/db/thang.type?view=items&project=name,components,original,rasterIcon'
@supermodel.loadCollection(@items, 'items')
@ -234,16 +234,6 @@ module.exports = class InventoryView extends CocoView
continue unless slotItemID
item = _.find @items.models, {id:slotItemID}
config[slotName] = item.get('original')
config
onHidden: ->
inventory = @getCurrentEquipmentConfig()
heroConfig = @options.session.get('heroConfig') ? {}
return if _.isEqual inventory, (heroConfig.inventory ? {})
heroConfig.inventory = inventory
heroConfig.thangType ?= '529ffbf1cf1818f2be000001' # Temp: assign Tharin as the hero
@options.session.set 'heroConfig', heroConfig
@options.session.patch success: ->
_.defer ->
Backbone.Mediator.publish 'level:inventory-changed', {}

View file

@ -552,10 +552,10 @@ hero = [
y: 53.1
}
{
name: 'Lowest Kithmen'
name: 'Lowly Kithmen'
type: 'hero'
difficulty: 1
id: 'lowest-kithguards'
id: 'lowly-kithmen'
image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
description: 'Use your glasses to seek out and attack the Kithmen.'
x: 39.4

View file

@ -70,7 +70,7 @@ module.exports = class PlayLevelView extends RootView
'real-time-multiplayer:joined-game': 'onJoinedRealTimeMultiplayerGame'
'real-time-multiplayer:left-game': 'onLeftRealTimeMultiplayerGame'
'real-time-multiplayer:manual-cast': 'onRealTimeMultiplayerCast'
'level:inventory-changed': 'onInventoryChanged'
'level:hero-config-changed': 'onHeroConfigChanged'
events:
'click #level-done-button': 'onDonePressed'
@ -371,7 +371,7 @@ module.exports = class PlayLevelView extends RootView
break
Backbone.Mediator.publish 'tome:cast-spell', {}
onInventoryChanged: (e) ->
onHeroConfigChanged: (e) ->
# Doesn't work because the new inventory ThangTypes may not be loaded.
#@setLevel @level, @supermodel
#Backbone.Mediator.publish 'tome:cast-spell', {}

View file

@ -2,6 +2,8 @@ ModalView = require 'views/kinds/ModalView'
template = require 'templates/play/modal/play-level-modal'
ChooseHeroView = require 'views/game-menu/ChooseHeroView'
InventoryView = require 'views/game-menu/InventoryView'
PlayLevelView = require 'views/play/level/PlayLevelView'
LevelSession = require 'models/LevelSession'
module.exports = class PlayLevelModal extends ModalView
className: 'modal fade play-modal'
@ -13,12 +15,17 @@ module.exports = class PlayLevelModal extends ModalView
'click #choose-hero-button': 'onClickChooseHero'
'click #play-level-button': 'onClickPlayLevel'
subscriptions:
'options:hero-changed': 'onHeroChanged'
constructor: (options) ->
super options
@options.showDevBits = true
@loadSession()
loadSession: ->
url = "/db/level/#{@options.levelID}/session"
#url += "?team=#{@team}" if @options.team # TODO: figure out how to get the teams for multiplayer PVP hero style
session = new LevelSession().setURL url
@session = @supermodel.loadModel(session, 'level_session').model
@options.session = @session
getRenderData: (context={}) ->
context = super(context)
@ -30,14 +37,39 @@ module.exports = class PlayLevelModal extends ModalView
afterRender: ->
super()
return unless @supermodel.finished()
@session.url = -> '/db/level.session/' + @id
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
@insertSubView @chooseHeroView = new ChooseHeroView @options
@insertSubView @inventoryView = new InventoryView @options
@inventoryView.$el.addClass 'secret'
onHidden: ->
super()
unless @navigatingToPlay
skipSessionSave = not @options.session.get('levelName')? # Has to have been already started.
@updateHeroConfig null, skipSessionSave
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
super()
updateHeroConfig: (callback, skipSessionSave) ->
sessionHeroConfig = @options.session.get('heroConfig') ? {}
lastHeroConfig = me.get('heroConfig') ? {}
thangType = @subviews.choose_hero_view.selectedHero.get 'original'
inventory = @subviews.inventory_view.getCurrentEquipmentConfig()
patchSession = patchMe = false
props = thangType: thangType, inventory: inventory
for key, val of props when val
patchSession ||= not _.isEqual val, sessionHeroConfig[key]
patchMe ||= not _.isEqual val, lastHeroConfig[key]
sessionHeroConfig[key] = val
lastHeroConfig[key] = val
if patchMe
me.set 'heroConfig', lastHeroConfig
me.patch()
if patchSession
@options.session.set 'heroConfig', sessionHeroConfig
@options.session.patch success: callback unless skipSessionSave
else
callback?()
onClickChooseInventory: (e) ->
@chooseHeroView.$el.add('#choose-inventory-button, #choose-hero-header').addClass 'secret'
@ -48,8 +80,10 @@ module.exports = class PlayLevelModal extends ModalView
@inventoryView.$el.add('#choose-hero-button, #play-level-button, #choose-inventory-header').addClass 'secret'
onClickPlayLevel: (e) ->
console.log 'should play!'
onHeroChanged: (e) ->
@$el.find('#choose-inventory-button').prop 'disabled', Boolean e.locked
@hero = e.hero
@showLoading()
@updateHeroConfig =>
@navigatingToPlay = true
Backbone.Mediator.publish 'router:navigate', {
route: "/play/#{@options.levelPath || 'level'}/#{@options.levelID}",
viewClass: PlayLevelView,
viewArgs: [{supermodel: @supermodel}, @options.levelID]}

View file

@ -115,9 +115,9 @@ class EarnedAchievementHandler extends Handler
earned.previouslyAchievedAmount = 0
expFunction = achievement.getExpFunction()
newPoints = expFunction(earned.achievedAmount) * achievement.get('worth')
newPoints = expFunction(earned.achievedAmount) * achievement.get('worth') ? 10
else
newPoints = achievement.get 'worth'
newPoints = achievement.get('worth') ? 10
earned.earnedPoints = newPoints
newTotalPoints += newPoints

View file

@ -193,7 +193,8 @@ UserSchema.statics.editableProperties = [
'name', 'photoURL', 'password', 'anonymous', 'wizardColor1', 'volume',
'firstName', 'lastName', 'gender', 'facebookID', 'gplusID', 'emails',
'testGroupNumber', 'music', 'hourOfCode', 'hourOfCodeComplete', 'preferredLanguage',
'wizard', 'aceConfig', 'autocastDelay', 'lastLevel', 'jobProfile', 'savedEmployerFilterAlerts'
'wizard', 'aceConfig', 'autocastDelay', 'lastLevel', 'jobProfile', 'savedEmployerFilterAlerts',
'heroConfig'
]
UserSchema.plugin plugins.NamedPlugin