mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-02-25 14:04:54 -05:00
Started getting hero-ladder level type working.
This commit is contained in:
parent
91db158c5e
commit
56a80e3615
23 changed files with 81 additions and 59 deletions
|
@ -91,9 +91,9 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
loadDependenciesForSession: (session) ->
|
loadDependenciesForSession: (session) ->
|
||||||
if session is @session
|
if session is @session
|
||||||
Backbone.Mediator.publish 'level:session-loaded', level: @level, session: @session
|
Backbone.Mediator.publish 'level:session-loaded', level: @level, session: @session
|
||||||
return unless @level.get('type', true) is 'hero'
|
return unless @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
heroConfig = session.get('heroConfig')
|
heroConfig = session.get('heroConfig')
|
||||||
heroConfig ?= me.get('heroConfig')
|
heroConfig ?= me.get('heroConfig') if session is @session
|
||||||
heroConfig ?= {inventory: {}, thangType: '529ffbf1cf1818f2be000001'} # If all else fails, assign Tharin as the hero.
|
heroConfig ?= {inventory: {}, thangType: '529ffbf1cf1818f2be000001'} # If all else fails, assign Tharin as the hero.
|
||||||
session.set 'heroConfig', heroConfig unless _.isEqual heroConfig, session.get('heroConfig')
|
session.set 'heroConfig', heroConfig unless _.isEqual heroConfig, session.get('heroConfig')
|
||||||
url = "/db/thang.type/#{heroConfig.thangType}/version"
|
url = "/db/thang.type/#{heroConfig.thangType}/version"
|
||||||
|
@ -334,7 +334,7 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
@initialized = true
|
@initialized = true
|
||||||
@world = new World()
|
@world = new World()
|
||||||
@world.levelSessionIDs = if @opponentSessionID then [@sessionID, @opponentSessionID] else [@sessionID]
|
@world.levelSessionIDs = if @opponentSessionID then [@sessionID, @opponentSessionID] else [@sessionID]
|
||||||
serializedLevel = @level.serialize(@supermodel, @session)
|
serializedLevel = @level.serialize(@supermodel, @session, @opponentSession)
|
||||||
@world.loadFromLevel serializedLevel, false
|
@world.loadFromLevel serializedLevel, false
|
||||||
console.log 'World has been initialized from level loader.'
|
console.log 'World has been initialized from level loader.'
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ module.exports = class Simulator extends CocoClass
|
||||||
@levelLoader = null
|
@levelLoader = null
|
||||||
|
|
||||||
setupGod: ->
|
setupGod: ->
|
||||||
@god.setLevel @level.serialize @supermodel
|
@god.setLevel @level.serialize @supermodel, @task.getSessions()[0], @task.getSessions()[1]
|
||||||
@god.setLevelSessionIDs (session.sessionID for session in @task.getSessions())
|
@god.setLevelSessionIDs (session.sessionID for session in @task.getSessions())
|
||||||
@god.setWorldClassMap @world.classMap
|
@god.setWorldClassMap @world.classMap
|
||||||
@god.setGoalManager new GoalManager(@world, @level.get 'goals')
|
@god.setGoalManager new GoalManager(@world, @level.get 'goals')
|
||||||
|
|
|
@ -540,7 +540,9 @@ module.exports = Surface = class Surface extends CocoClass
|
||||||
#- Camera focus on hero
|
#- Camera focus on hero
|
||||||
focusOnHero: ->
|
focusOnHero: ->
|
||||||
@heroLank = @lankBoss.lankFor 'Hero Placeholder'
|
@heroLank = @lankBoss.lankFor 'Hero Placeholder'
|
||||||
|
if me.team is 'ogres'
|
||||||
|
# TODO: do this for real
|
||||||
|
@heroLank = @lankBoss.lankFor 'Hero Placeholder 1'
|
||||||
|
|
||||||
#- Real-time playback
|
#- Real-time playback
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ module.exports = class Level extends CocoModel
|
||||||
@schema: require 'schemas/models/level'
|
@schema: require 'schemas/models/level'
|
||||||
urlRoot: '/db/level'
|
urlRoot: '/db/level'
|
||||||
|
|
||||||
serialize: (supermodel, session, cached=false) ->
|
serialize: (supermodel, session, otherSession, cached=false) ->
|
||||||
o = @denormalize supermodel, session # hot spot to optimize
|
o = @denormalize supermodel, session, otherSession # hot spot to optimize
|
||||||
|
|
||||||
# Figure out Components
|
# Figure out Components
|
||||||
o.levelComponents = if cached then @getCachedLevelComponents(supermodel) else $.extend true, [], (lc.attributes for lc in supermodel.getModels LevelComponent)
|
o.levelComponents = if cached then @getCachedLevelComponents(supermodel) else $.extend true, [], (lc.attributes for lc in supermodel.getModels LevelComponent)
|
||||||
|
@ -44,17 +44,24 @@ module.exports = class Level extends CocoModel
|
||||||
newLevelComponents.push(@cachedLevelComponents[levelComponent.id])
|
newLevelComponents.push(@cachedLevelComponents[levelComponent.id])
|
||||||
newLevelComponents
|
newLevelComponents
|
||||||
|
|
||||||
denormalize: (supermodel, session) ->
|
denormalize: (supermodel, session, otherSession) ->
|
||||||
o = $.extend true, {}, @attributes
|
o = $.extend true, {}, @attributes
|
||||||
if o.thangs and @get('type', true) is 'hero'
|
if o.thangs and @get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
# TOOD: figure out if/when/how we are doing this for non-Hero levels that aren't expecting denormalization.
|
|
||||||
for levelThang in o.thangs
|
for levelThang in o.thangs
|
||||||
@denormalizeThang(levelThang, supermodel, session)
|
@denormalizeThang(levelThang, supermodel, session, otherSession)
|
||||||
o
|
o
|
||||||
|
|
||||||
denormalizeThang: (levelThang, supermodel, session) ->
|
denormalizeThang: (levelThang, supermodel, session, otherSession) ->
|
||||||
levelThang.components ?= []
|
levelThang.components ?= []
|
||||||
isHero = levelThang.id is 'Hero Placeholder'
|
isHero = /Hero Placeholder/.test levelThang.id
|
||||||
|
if isHero and otherSession
|
||||||
|
# If it's a hero and there's another session, find the right session for it.
|
||||||
|
# If there is no other session (playing against default code, or on single player), clone all placeholders.
|
||||||
|
# TODO: actually look at the teams on these things to determine which session should go with which placeholder.
|
||||||
|
if levelThang.id is 'Hero Placeholder 1' and session.get('team') is 'humans'
|
||||||
|
session = otherSession
|
||||||
|
else if levelThang.id is 'Hero Placeholder' and session.get('team') is 'ogres'
|
||||||
|
session = otherSession
|
||||||
|
|
||||||
# Empty out placeholder Components and store their values if we're the hero placeholder.
|
# Empty out placeholder Components and store their values if we're the hero placeholder.
|
||||||
if isHero
|
if isHero
|
||||||
|
@ -129,6 +136,7 @@ module.exports = class Level extends CocoModel
|
||||||
# Example: Programmable must come last, since it has to override any Component-provided methods that any other Component might have created. Can't enumerate all soft dependencies.
|
# Example: Programmable must come last, since it has to override any Component-provided methods that any other Component might have created. Can't enumerate all soft dependencies.
|
||||||
# Example: Plans needs to come after everything except Programmable, since other Components that add plannable methods need to have done so by the time Plans is attached.
|
# Example: Plans needs to come after everything except Programmable, since other Components that add plannable methods need to have done so by the time Plans is attached.
|
||||||
# Example: Collides doesn't depend on Allied, but if both exist, Collides must come after Allied. Soft dependency example. Can't just figure out a proper priority to take care of it.
|
# Example: Collides doesn't depend on Allied, but if both exist, Collides must come after Allied. Soft dependency example. Can't just figure out a proper priority to take care of it.
|
||||||
|
# Example: Moves doesn't depend on Acts, but if both exist, Moves must come after Acts. Another soft dependency example.
|
||||||
# Decision? Just special case the sort logic in here until we have more examples than these two and decide how best to handle most of the cases then, since we don't really know the whole of the problem yet.
|
# Decision? Just special case the sort logic in here until we have more examples than these two and decide how best to handle most of the cases then, since we don't really know the whole of the problem yet.
|
||||||
# TODO: anything that depends on Programmable will break right now.
|
# TODO: anything that depends on Programmable will break right now.
|
||||||
|
|
||||||
|
@ -158,10 +166,13 @@ module.exports = class Level extends CocoModel
|
||||||
console.error parentType, thang.id or thang.name, 'does not have dependent Component', dependent, 'from', lc.name
|
console.error parentType, thang.id or thang.name, 'does not have dependent Component', dependent, 'from', lc.name
|
||||||
visit c2 if c2
|
visit c2 if c2
|
||||||
if lc.name is 'Collides'
|
if lc.name is 'Collides'
|
||||||
allied = _.find levelComponents, {name: 'Allied'}
|
if allied = _.find levelComponents, {name: 'Allied'}
|
||||||
if allied
|
allied = _.find(thang.components, {original: allied.original})
|
||||||
collides = _.find(thang.components, {original: allied.original})
|
visit allied if allied
|
||||||
visit collides if collides
|
if lc.name is 'Moves'
|
||||||
|
if acts = _.find levelComponents, {name: 'Acts'}
|
||||||
|
acts = _.find(thang.components, {original: acts.original})
|
||||||
|
visit acts if acts
|
||||||
#console.log thang.id, 'sorted comps adding', lc.name
|
#console.log thang.id, 'sorted comps adding', lc.name
|
||||||
sorted.push c
|
sorted.push c
|
||||||
for comp in thang.components
|
for comp in thang.components
|
||||||
|
|
|
@ -244,7 +244,7 @@ _.extend LevelSchema.properties,
|
||||||
icon: {type: 'string', format: 'image-file', title: 'Icon'}
|
icon: {type: 'string', format: 'image-file', title: 'Icon'}
|
||||||
banner: {type: 'string', format: 'image-file', title: 'Banner'}
|
banner: {type: 'string', format: 'image-file', title: 'Banner'}
|
||||||
goals: c.array {title: 'Goals', description: 'An array of goals which are visible to the player and can trigger scripts.'}, GoalSchema
|
goals: c.array {title: 'Goals', description: 'An array of goals which are visible to the player and can trigger scripts.'}, GoalSchema
|
||||||
type: c.shortString(title: 'Type', description: 'What kind of level this is.', 'enum': ['campaign', 'ladder', 'ladder-tutorial', 'hero'])
|
type: c.shortString(title: 'Type', description: 'What kind of level this is.', 'enum': ['campaign', 'ladder', 'ladder-tutorial', 'hero', 'hero-ladder', 'hero-coop'])
|
||||||
terrain: c.terrainString
|
terrain: c.terrainString
|
||||||
showsGuide: c.shortString(title: 'Shows Guide', description: 'If the guide is shown at the beginning of the level.', 'enum': ['first-time', 'always'])
|
showsGuide: c.shortString(title: 'Shows Guide', description: 'If the guide is shown at the beginning of the level.', 'enum': ['first-time', 'always'])
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ module.exports = class ThangComponentConfigView extends CocoView
|
||||||
schema.default ?= {}
|
schema.default ?= {}
|
||||||
_.merge schema.default, @additionalDefaults if @additionalDefaults
|
_.merge schema.default, @additionalDefaults if @additionalDefaults
|
||||||
|
|
||||||
if @level?.get('type', true) is 'hero'
|
if @level?.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
schema.required = []
|
schema.required = []
|
||||||
treemaOptions =
|
treemaOptions =
|
||||||
supermodel: @supermodel
|
supermodel: @supermodel
|
||||||
|
|
|
@ -46,7 +46,7 @@ module.exports = class LevelThangEditView extends CocoView
|
||||||
level: @level
|
level: @level
|
||||||
world: @world
|
world: @world
|
||||||
|
|
||||||
if @level.get('type', true) is 'hero' then options.thangType = thangType
|
if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] then options.thangType = thangType
|
||||||
|
|
||||||
@thangComponentEditView = new ThangComponentsEditView options
|
@thangComponentEditView = new ThangComponentsEditView options
|
||||||
@listenTo @thangComponentEditView, 'components-changed', @onComponentsChanged
|
@listenTo @thangComponentEditView, 'components-changed', @onComponentsChanged
|
||||||
|
|
|
@ -520,7 +520,7 @@ module.exports = class ThangsTabView extends CocoView
|
||||||
|
|
||||||
@level.set 'thangs', thangs
|
@level.set 'thangs', thangs
|
||||||
return if @editThangView
|
return if @editThangView
|
||||||
serializedLevel = @level.serialize @supermodel, null, true
|
serializedLevel = @level.serialize @supermodel, null, null, true
|
||||||
try
|
try
|
||||||
@world.loadFromLevel serializedLevel, false
|
@world.loadFromLevel serializedLevel, false
|
||||||
catch error
|
catch error
|
||||||
|
@ -552,14 +552,14 @@ module.exports = class ThangsTabView extends CocoView
|
||||||
if batchInsert
|
if batchInsert
|
||||||
if thangType.get('name') is 'Hero Placeholder'
|
if thangType.get('name') is 'Hero Placeholder'
|
||||||
thangID = 'Hero Placeholder'
|
thangID = 'Hero Placeholder'
|
||||||
return if @level.get('type', true) isnt 'hero' or @getThangByID(thangID)
|
return if not (@level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']) or @getThangByID(thangID)
|
||||||
else
|
else
|
||||||
thangID = "Random #{thangType.get('name')} #{@thangsBatch.length}"
|
thangID = "Random #{thangType.get('name')} #{@thangsBatch.length}"
|
||||||
else
|
else
|
||||||
thangID = Thang.nextID(thangType.get('name'), @world) until thangID and not @getThangByID(thangID)
|
thangID = Thang.nextID(thangType.get('name'), @world) until thangID and not @getThangByID(thangID)
|
||||||
if @cloneSourceThang
|
if @cloneSourceThang
|
||||||
components = _.cloneDeep @getThangByID(@cloneSourceThang.id).components
|
components = _.cloneDeep @getThangByID(@cloneSourceThang.id).components
|
||||||
else if @level.get('type', true) is 'hero'
|
else if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
components = [] # Load them all from default ThangType Components
|
components = [] # Load them all from default ThangType Components
|
||||||
else
|
else
|
||||||
components = _.cloneDeep thangType.get('components') ? []
|
components = _.cloneDeep thangType.get('components') ? []
|
||||||
|
|
|
@ -21,7 +21,7 @@ module.exports = class GameMenuModal extends ModalView
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
super options
|
super options
|
||||||
@options.showDevBits = me.isAdmin() or /https?:\/\/localhost/.test(window.location.href)
|
@options.showDevBits = me.isAdmin() or /https?:\/\/localhost/.test(window.location.href)
|
||||||
@options.showInventory = @options.level.get('type', true) is 'hero'
|
@options.showInventory = @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
@options.levelID = @options.level.get('slug')
|
@options.levelID = @options.level.get('slug')
|
||||||
@options.startingSessionHeroConfig = $.extend {}, true, (@options.session.get('heroConfig') ? {})
|
@options.startingSessionHeroConfig = $.extend {}, true, (@options.session.get('heroConfig') ? {})
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ module.exports = class MultiplayerView extends CocoView
|
||||||
c.team = @session.get 'team'
|
c.team = @session.get 'team'
|
||||||
c.levelSlug = @level?.get 'slug'
|
c.levelSlug = @level?.get 'slug'
|
||||||
# For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet.
|
# For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet.
|
||||||
if @level?.get('type') is 'ladder'
|
if @level?.get('type') in ['ladder', 'hero-ladder']
|
||||||
c.ladderGame = true
|
c.ladderGame = true
|
||||||
c.readyToRank = @session?.readyToRank()
|
c.readyToRank = @session?.readyToRank()
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ module.exports = class MultiplayerView extends CocoView
|
||||||
updateLinkSection: ->
|
updateLinkSection: ->
|
||||||
multiplayer = @$el.find('#multiplayer').prop('checked')
|
multiplayer = @$el.find('#multiplayer').prop('checked')
|
||||||
la = @$el.find('#link-area')
|
la = @$el.find('#link-area')
|
||||||
la.toggle if @level?.get('type') is 'ladder' then false else Boolean(multiplayer)
|
la.toggle if @level?.get('type') in ['ladder', 'hero-ladder'] then false else Boolean(multiplayer)
|
||||||
true
|
true
|
||||||
|
|
||||||
onHidden: ->
|
onHidden: ->
|
||||||
|
|
|
@ -68,7 +68,7 @@ module.exports = class SpectateLevelView extends RootView
|
||||||
@load()
|
@load()
|
||||||
|
|
||||||
setLevel: (@level, @supermodel) ->
|
setLevel: (@level, @supermodel) ->
|
||||||
serializedLevel = @level.serialize @supermodel, @session
|
serializedLevel = @level.serialize @supermodel, @session, @otherSession
|
||||||
@god?.setLevel serializedLevel
|
@god?.setLevel serializedLevel
|
||||||
if @world
|
if @world
|
||||||
@world.loadFromLevel serializedLevel, false
|
@world.loadFromLevel serializedLevel, false
|
||||||
|
@ -105,7 +105,7 @@ module.exports = class SpectateLevelView extends RootView
|
||||||
#at this point, all requisite data is loaded, and sessions are not denormalized
|
#at this point, all requisite data is loaded, and sessions are not denormalized
|
||||||
team = @world.teamForPlayer(0)
|
team = @world.teamForPlayer(0)
|
||||||
@loadOpponentTeam(team)
|
@loadOpponentTeam(team)
|
||||||
@god.setLevel @level.serialize @supermodel, @session
|
@god.setLevel @level.serialize @supermodel, @session, @otherSession
|
||||||
@god.setLevelSessionIDs if @otherSession then [@session.id, @otherSession.id] else [@session.id]
|
@god.setLevelSessionIDs if @otherSession then [@session.id, @otherSession.id] else [@session.id]
|
||||||
@god.setWorldClassMap @world.classMap
|
@god.setWorldClassMap @world.classMap
|
||||||
@setTeam team
|
@setTeam team
|
||||||
|
@ -119,7 +119,7 @@ module.exports = class SpectateLevelView extends RootView
|
||||||
@register()
|
@register()
|
||||||
@controlBar.setBus(@bus)
|
@controlBar.setBus(@bus)
|
||||||
@surface.showLevel()
|
@surface.showLevel()
|
||||||
if @level.get('type', true) isnt 'hero'
|
if not (@level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'])
|
||||||
if me.id isnt @session.get 'creator'
|
if me.id isnt @session.get 'creator'
|
||||||
@surface.createOpponentWizard
|
@surface.createOpponentWizard
|
||||||
id: @session.get('creator')
|
id: @session.get('creator')
|
||||||
|
|
|
@ -718,6 +718,17 @@ hero = [
|
||||||
x: 95.31
|
x: 95.31
|
||||||
y: 88.26
|
y: 88.26
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
name: 'Dueling Grounds'
|
||||||
|
type: 'hero-ladder'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'dueling-grounds'
|
||||||
|
original: '5442ba0e1e835500007eb1c7'
|
||||||
|
description: 'Battle head-to-head against another hero in this basic beginner combat arena.'
|
||||||
|
disabled: not me.isAdmin()
|
||||||
|
x: 17.54
|
||||||
|
y: 78.39
|
||||||
|
}
|
||||||
#{
|
#{
|
||||||
# name: ''
|
# name: ''
|
||||||
# type: 'hero'
|
# type: 'hero'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{hslToHex} = require 'lib/utils'
|
{hslToHex} = require 'lib/utils'
|
||||||
|
|
||||||
module.exports.teamDataFromLevel = (level) ->
|
module.exports.teamDataFromLevel = (level) ->
|
||||||
alliedSystem = _.find level.get('systems'), (value) -> value.config?.teams?
|
alliedSystem = _.find level.get('systems', true), (value) -> value.config?.teams?
|
||||||
teamNames = (teamName for teamName, teamConfig of alliedSystem.config.teams when teamConfig.playable)
|
teamNames = (teamName for teamName, teamConfig of alliedSystem.config.teams when teamConfig.playable)
|
||||||
teamConfigs = alliedSystem.config.teams
|
teamConfigs = alliedSystem.config.teams
|
||||||
|
|
||||||
|
|
|
@ -51,15 +51,15 @@ module.exports = class ControlBarView extends CocoView
|
||||||
super c
|
super c
|
||||||
c.worldName = @worldName
|
c.worldName = @worldName
|
||||||
c.multiplayerEnabled = @session.get('multiplayer')
|
c.multiplayerEnabled = @session.get('multiplayer')
|
||||||
c.ladderGame = @level.get('type') is 'ladder'
|
c.ladderGame = @level.get('type') in ['ladder', 'hero-ladder']
|
||||||
c.spectateGame = @spectateGame
|
c.spectateGame = @spectateGame
|
||||||
@homeViewArgs = [{supermodel: @supermodel}]
|
@homeViewArgs = [{supermodel: @supermodel}]
|
||||||
if @level.get('type', true) in ['ladder', 'ladder-tutorial']
|
if @level.get('type', true) in ['ladder', 'ladder-tutorial', 'hero-ladder']
|
||||||
levelID = @level.get('slug').replace /\-tutorial$/, ''
|
levelID = @level.get('slug').replace /\-tutorial$/, ''
|
||||||
@homeLink = c.homeLink = '/play/ladder/' + levelID
|
@homeLink = c.homeLink = '/play/ladder/' + levelID
|
||||||
@homeViewClass = require 'views/play/ladder/LadderView'
|
@homeViewClass = require 'views/play/ladder/LadderView'
|
||||||
@homeViewArgs.push levelID
|
@homeViewArgs.push levelID
|
||||||
else if @level.get('type', true) is 'hero'
|
else if @level.get('type', true) in ['hero', 'hero-coop']
|
||||||
@homeLink = c.homeLink = '/play'
|
@homeLink = c.homeLink = '/play'
|
||||||
@homeViewClass = require 'views/play/WorldMapView'
|
@homeViewClass = require 'views/play/WorldMapView'
|
||||||
else
|
else
|
||||||
|
|
|
@ -85,7 +85,7 @@ module.exports = class LevelHUDView extends CocoView
|
||||||
clearTimeout @hintNextSelectionTimeout
|
clearTimeout @hintNextSelectionTimeout
|
||||||
@$el.find('.no-selection-message').hide()
|
@$el.find('.no-selection-message').hide()
|
||||||
if not @thang
|
if not @thang
|
||||||
unless @options.level.get('type', true) is 'hero'
|
unless @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
@hintNextSelectionTimeout = _.delay((=> @$el.find('.no-selection-message').slideDown('slow')), 10000)
|
@hintNextSelectionTimeout = _.delay((=> @$el.find('.no-selection-message').slideDown('slow')), 10000)
|
||||||
return
|
return
|
||||||
@createAvatar thangType, @thang
|
@createAvatar thangType, @thang
|
||||||
|
|
|
@ -167,7 +167,7 @@ module.exports = class LevelPlaybackView extends CocoView
|
||||||
@togglePlaybackControls false
|
@togglePlaybackControls false
|
||||||
Backbone.Mediator.publish 'playback:real-time-playback-started', {}
|
Backbone.Mediator.publish 'playback:real-time-playback-started', {}
|
||||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'real-time-playback-start', volume: 1
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'real-time-playback-start', volume: 1
|
||||||
Backbone.Mediator.publish 'level:set-letterbox', on: true
|
Backbone.Mediator.publish 'level:set-letterbox', on: true if @options.level.get('type', true) is ['hero'] # not with flags...?
|
||||||
|
|
||||||
onRealTimeMultiplayerCast: (e) ->
|
onRealTimeMultiplayerCast: (e) ->
|
||||||
@realTime = true
|
@realTime = true
|
||||||
|
|
|
@ -118,7 +118,7 @@ module.exports = class PlayLevelView extends RootView
|
||||||
@supermodel.collections = givenSupermodel.collections
|
@supermodel.collections = givenSupermodel.collections
|
||||||
@supermodel.shouldSaveBackups = givenSupermodel.shouldSaveBackups
|
@supermodel.shouldSaveBackups = givenSupermodel.shouldSaveBackups
|
||||||
|
|
||||||
serializedLevel = @level.serialize @supermodel, @session
|
serializedLevel = @level.serialize @supermodel, @session, @otherSession
|
||||||
@god?.setLevel serializedLevel
|
@god?.setLevel serializedLevel
|
||||||
if @world
|
if @world
|
||||||
@world.loadFromLevel serializedLevel, false
|
@world.loadFromLevel serializedLevel, false
|
||||||
|
@ -215,8 +215,8 @@ module.exports = class PlayLevelView extends RootView
|
||||||
@session = @levelLoader.session
|
@session = @levelLoader.session
|
||||||
@world = @levelLoader.world
|
@world = @levelLoader.world
|
||||||
@level = @levelLoader.level
|
@level = @levelLoader.level
|
||||||
@$el.addClass 'hero' if @level.get('type', true) is 'hero'
|
@$el.addClass 'hero' if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
@$el.addClass 'flags' if @level.get('slug') is 'sky-span' # TODO: figure out when the player has flags.
|
@$el.addClass 'flags' if @level.get('slug') is 'sky-span' or (@level.get('type', true) in ['hero-ladder', 'hero-coop']) # TODO: figure out when the player has flags.
|
||||||
@otherSession = @levelLoader.opponentSession
|
@otherSession = @levelLoader.opponentSession
|
||||||
@worldLoadFakeResources = [] # first element (0) is 1%, last (100) is 100%
|
@worldLoadFakeResources = [] # first element (0) is 1%, last (100) is 100%
|
||||||
for percent in [1 .. 100]
|
for percent in [1 .. 100]
|
||||||
|
@ -251,7 +251,7 @@ module.exports = class PlayLevelView extends RootView
|
||||||
@session.set 'multiplayer', false
|
@session.set 'multiplayer', false
|
||||||
|
|
||||||
setupGod: ->
|
setupGod: ->
|
||||||
@god.setLevel @level.serialize @supermodel, @session
|
@god.setLevel @level.serialize @supermodel, @session, @otherSession
|
||||||
@god.setLevelSessionIDs if @otherSession then [@session.id, @otherSession.id] else [@session.id]
|
@god.setLevelSessionIDs if @otherSession then [@session.id, @otherSession.id] else [@session.id]
|
||||||
@god.setWorldClassMap @world.classMap
|
@god.setWorldClassMap @world.classMap
|
||||||
|
|
||||||
|
@ -268,9 +268,9 @@ module.exports = class PlayLevelView extends RootView
|
||||||
|
|
||||||
insertSubviews: ->
|
insertSubviews: ->
|
||||||
@insertSubView @tome = new TomeView levelID: @levelID, session: @session, otherSession: @otherSession, thangs: @world.thangs, supermodel: @supermodel, level: @level
|
@insertSubView @tome = new TomeView levelID: @levelID, session: @session, otherSession: @otherSession, thangs: @world.thangs, supermodel: @supermodel, level: @level
|
||||||
@insertSubView new LevelPlaybackView session: @session, levelID: @levelID
|
@insertSubView new LevelPlaybackView session: @session, levelID: @levelID, level: @level
|
||||||
@insertSubView new GoalsView {}
|
@insertSubView new GoalsView {}
|
||||||
@insertSubView new LevelFlagsView world: @world if @levelID is 'sky-span' # TODO: figure out when flags are available
|
@insertSubView new LevelFlagsView world: @world if @levelID is 'sky-span' or @level.get('type', true) in ['hero-ladder', 'hero-coop'] # TODO: figure out when flags are available
|
||||||
@insertSubView new GoldView {}
|
@insertSubView new GoldView {}
|
||||||
@insertSubView new HUDView {level: @level}
|
@insertSubView new HUDView {level: @level}
|
||||||
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
|
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
|
||||||
|
@ -297,11 +297,11 @@ module.exports = class PlayLevelView extends RootView
|
||||||
|
|
||||||
onLevelLoaded: (e) ->
|
onLevelLoaded: (e) ->
|
||||||
# Just the level has been loaded by the level loader
|
# Just the level has been loaded by the level loader
|
||||||
@showWizardSettingsModal() if not me.get('name') and not @isIPadApp() and e.level.get('type', true) isnt 'hero'
|
@showWizardSettingsModal() if not me.get('name') and not @isIPadApp() and not (e.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'])
|
||||||
|
|
||||||
onSessionLoaded: (e) ->
|
onSessionLoaded: (e) ->
|
||||||
# Just the level and session have been loaded by the level loader
|
# Just the level and session have been loaded by the level loader
|
||||||
if e.level.get('type', true) is 'hero' and not _.size e.session.get('heroConfig')?.inventory ? {}
|
if e.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] and not _.size e.session.get('heroConfig')?.inventory ? {}
|
||||||
@openModalView new GameMenuModal level: e.level, session: e.session
|
@openModalView new GameMenuModal level: e.level, session: e.session
|
||||||
|
|
||||||
onLoaded: ->
|
onLoaded: ->
|
||||||
|
@ -331,7 +331,7 @@ module.exports = class PlayLevelView extends RootView
|
||||||
initSurface: ->
|
initSurface: ->
|
||||||
webGLSurface = $('canvas#webgl-surface', @$el)
|
webGLSurface = $('canvas#webgl-surface', @$el)
|
||||||
normalSurface = $('canvas#normal-surface', @$el)
|
normalSurface = $('canvas#normal-surface', @$el)
|
||||||
@surface = new Surface(@world, normalSurface, webGLSurface, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, wizards: @level.get('type', true) isnt 'hero')
|
@surface = new Surface(@world, normalSurface, webGLSurface, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, wizards: not (@level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']))
|
||||||
worldBounds = @world.getBounds()
|
worldBounds = @world.getBounds()
|
||||||
bounds = [{x: worldBounds.left, y: worldBounds.top}, {x: worldBounds.right, y: worldBounds.bottom}]
|
bounds = [{x: worldBounds.left, y: worldBounds.top}, {x: worldBounds.right, y: worldBounds.bottom}]
|
||||||
@surface.camera.setBounds(bounds)
|
@surface.camera.setBounds(bounds)
|
||||||
|
@ -346,7 +346,7 @@ module.exports = class PlayLevelView extends RootView
|
||||||
if window.currentModal and not window.currentModal.destroyed and window.currentModal.constructor isnt VictoryModal
|
if window.currentModal and not window.currentModal.destroyed and window.currentModal.constructor isnt VictoryModal
|
||||||
return Backbone.Mediator.subscribeOnce 'modal:closed', @onLevelStarted, @
|
return Backbone.Mediator.subscribeOnce 'modal:closed', @onLevelStarted, @
|
||||||
@surface.showLevel()
|
@surface.showLevel()
|
||||||
if @otherSession and @level.get('type', true) isnt 'hero'
|
if @otherSession and not (@level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'])
|
||||||
# TODO: colorize name and cloud by team, colorize wizard by user's color config
|
# TODO: colorize name and cloud by team, colorize wizard by user's color config
|
||||||
@surface.createOpponentWizard id: @otherSession.get('creator'), name: @otherSession.get('creatorName'), team: @otherSession.get('team'), levelSlug: @level.get('slug'), codeLanguage: @otherSession.get('submittedCodeLanguage')
|
@surface.createOpponentWizard id: @otherSession.get('creator'), name: @otherSession.get('creatorName'), team: @otherSession.get('team'), levelSlug: @level.get('slug'), codeLanguage: @otherSession.get('submittedCodeLanguage')
|
||||||
if @isEditorPreview
|
if @isEditorPreview
|
||||||
|
@ -377,7 +377,7 @@ module.exports = class PlayLevelView extends RootView
|
||||||
return if @alreadyLoadedState
|
return if @alreadyLoadedState
|
||||||
@alreadyLoadedState = true
|
@alreadyLoadedState = true
|
||||||
state = @originalSessionState
|
state = @originalSessionState
|
||||||
if @level.get('type', true) is 'hero'
|
if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
Backbone.Mediator.publish 'level:suppress-selection-sounds', suppress: true
|
Backbone.Mediator.publish 'level:suppress-selection-sounds', suppress: true
|
||||||
Backbone.Mediator.publish 'tome:select-primary-sprite', {}
|
Backbone.Mediator.publish 'tome:select-primary-sprite', {}
|
||||||
Backbone.Mediator.publish 'level:suppress-selection-sounds', suppress: false
|
Backbone.Mediator.publish 'level:suppress-selection-sounds', suppress: false
|
||||||
|
@ -443,7 +443,7 @@ module.exports = class PlayLevelView extends RootView
|
||||||
onDonePressed: -> @showVictory()
|
onDonePressed: -> @showVictory()
|
||||||
|
|
||||||
onShowVictory: (e) ->
|
onShowVictory: (e) ->
|
||||||
$('#level-done-button').show() unless @level.get('type', true) is 'hero'
|
$('#level-done-button').show() unless @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
|
||||||
@showVictory() if e.showModal
|
@showVictory() if e.showModal
|
||||||
setTimeout(@preloadNextLevel, 3000)
|
setTimeout(@preloadNextLevel, 3000)
|
||||||
return if @victorySeen
|
return if @victorySeen
|
||||||
|
@ -455,7 +455,8 @@ module.exports = class PlayLevelView extends RootView
|
||||||
|
|
||||||
showVictory: ->
|
showVictory: ->
|
||||||
options = {level: @level, supermodel: @supermodel, session: @session}
|
options = {level: @level, supermodel: @supermodel, session: @session}
|
||||||
ModalClass = if @level.get('type', true) is 'hero' then HeroVictoryModal else VictoryModal
|
ModalClass = if @level.get('type', true) in ['hero', 'hero-coop'] then HeroVictoryModal else VictoryModal
|
||||||
|
# TODO: made HeroVictoryModal able to support hero-ladder and then switch over for that level type, too
|
||||||
victoryModal = new ModalClass(options)
|
victoryModal = new ModalClass(options)
|
||||||
@openModalView(victoryModal)
|
@openModalView(victoryModal)
|
||||||
if me.get('anonymous')
|
if me.get('anonymous')
|
||||||
|
|
|
@ -36,9 +36,6 @@ module.exports = class VictoryModal extends ModalView
|
||||||
@session = options.session
|
@session = options.session
|
||||||
@saveReviewEventually = _.debounce(@saveReviewEventually, 2000)
|
@saveReviewEventually = _.debounce(@saveReviewEventually, 2000)
|
||||||
@loadExistingFeedback()
|
@loadExistingFeedback()
|
||||||
if @level.get('type', true) is 'hero'
|
|
||||||
@closeButton = false
|
|
||||||
@closesOnClickOutside = false
|
|
||||||
super options
|
super options
|
||||||
|
|
||||||
loadExistingFeedback: ->
|
loadExistingFeedback: ->
|
||||||
|
@ -82,7 +79,7 @@ module.exports = class VictoryModal extends ModalView
|
||||||
c.hasNextLevel = _.isObject(@level.get('nextLevel'))
|
c.hasNextLevel = _.isObject(@level.get('nextLevel'))
|
||||||
c.levelName = utils.i18n @level.attributes, 'name'
|
c.levelName = utils.i18n @level.attributes, 'name'
|
||||||
c.level = @level
|
c.level = @level
|
||||||
if c.level.get('type') is 'ladder'
|
if c.level.get('type') in ['ladder', 'hero-ladder']
|
||||||
c.readyToRank = @session.readyToRank()
|
c.readyToRank = @session.readyToRank()
|
||||||
if me.get 'hourOfCode'
|
if me.get 'hourOfCode'
|
||||||
# Show the Hour of Code "I'm Done" tracking pixel after they played for 30 minutes
|
# Show the Hour of Code "I'm Done" tracking pixel after they played for 30 minutes
|
||||||
|
|
|
@ -133,7 +133,7 @@ module.exports = class Spell
|
||||||
writable = @permissions.readwrite.length > 0
|
writable = @permissions.readwrite.length > 0
|
||||||
skipProtectAPI = @skipProtectAPI or not writable
|
skipProtectAPI = @skipProtectAPI or not writable
|
||||||
problemContext = @createProblemContext thang
|
problemContext = @createProblemContext thang
|
||||||
aetherOptions = createAetherOptions functionName: @name, codeLanguage: @language, functionParameters: @parameters, skipProtectAPI: skipProtectAPI, includeFlow: @levelType is 'hero', problemContext: problemContext
|
aetherOptions = createAetherOptions functionName: @name, codeLanguage: @language, functionParameters: @parameters, skipProtectAPI: skipProtectAPI, includeFlow: @levelType in ['hero', 'hero-ladder', 'hero-coop'], problemContext: problemContext
|
||||||
aether = new Aether aetherOptions
|
aether = new Aether aetherOptions
|
||||||
if @worker
|
if @worker
|
||||||
workerMessage =
|
workerMessage =
|
||||||
|
|
|
@ -121,7 +121,7 @@ module.exports = class SpellPaletteView extends CocoView
|
||||||
else
|
else
|
||||||
propStorage =
|
propStorage =
|
||||||
'this': ['apiProperties', 'apiMethods']
|
'this': ['apiProperties', 'apiMethods']
|
||||||
if @options.level.get('type', true) isnt 'hero' or not @options.programmable
|
if not (@options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']) or not @options.programmable
|
||||||
@organizePalette propStorage, allDocs, excludedDocs
|
@organizePalette propStorage, allDocs, excludedDocs
|
||||||
else
|
else
|
||||||
@organizePaletteHero propStorage, allDocs, excludedDocs
|
@organizePaletteHero propStorage, allDocs, excludedDocs
|
||||||
|
@ -162,7 +162,7 @@ module.exports = class SpellPaletteView extends CocoView
|
||||||
if tabbify and _.find @entries, ((entry) -> entry.doc.owner isnt 'this')
|
if tabbify and _.find @entries, ((entry) -> entry.doc.owner isnt 'this')
|
||||||
@entryGroups = _.groupBy @entries, groupForEntry
|
@entryGroups = _.groupBy @entries, groupForEntry
|
||||||
else
|
else
|
||||||
i18nKey = if @options.level.get('type', true) is 'hero' then 'play_level.tome_your_skills' else 'play_level.tome_available_spells'
|
i18nKey = if @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] then 'play_level.tome_your_skills' else 'play_level.tome_available_spells'
|
||||||
defaultGroup = $.i18n.t i18nKey
|
defaultGroup = $.i18n.t i18nKey
|
||||||
@entryGroups = {}
|
@entryGroups = {}
|
||||||
@entryGroups[defaultGroup] = @entries
|
@entryGroups[defaultGroup] = @entries
|
||||||
|
@ -218,7 +218,7 @@ module.exports = class SpellPaletteView extends CocoView
|
||||||
return true if doc.owner is owner
|
return true if doc.owner is owner
|
||||||
return (owner is 'this' or owner is 'more') and (not doc.owner? or doc.owner is 'this')
|
return (owner is 'this' or owner is 'more') and (not doc.owner? or doc.owner is 'this')
|
||||||
if not doc and not excludedDocs['__' + prop]
|
if not doc and not excludedDocs['__' + prop]
|
||||||
console.log 'could not find doc for', prop, 'from', allDocs['__' + prop], 'for', owner, 'of', propGroups, 'with item', item
|
console.log 'could not find doc for', prop, 'from', allDocs['__' + prop], 'for', owner, 'of', propsByItem, 'with item', item
|
||||||
doc ?= prop
|
doc ?= prop
|
||||||
if doc
|
if doc
|
||||||
@entries.push @addEntry(doc, shortenize, false, owner is 'snippets', item, propIndex > 0)
|
@entries.push @addEntry(doc, shortenize, false, owner is 'snippets', item, propIndex > 0)
|
||||||
|
|
|
@ -186,7 +186,7 @@ module.exports = class TomeView extends CocoView
|
||||||
@thangList?.$el.show()
|
@thangList?.$el.show()
|
||||||
|
|
||||||
onSpriteSelected: (e) ->
|
onSpriteSelected: (e) ->
|
||||||
return if @spellView and @options.level.get('type', true) is 'hero' # Never deselect the hero in the Tome.
|
return if @spellView and @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] # Never deselect the hero in the Tome.
|
||||||
thang = e.thang
|
thang = e.thang
|
||||||
spellName = e.spellName
|
spellName = e.spellName
|
||||||
@spellList?.$el.hide()
|
@spellList?.$el.hide()
|
||||||
|
|
|
@ -67,7 +67,7 @@ LevelHandler = class LevelHandler extends Handler
|
||||||
sessionQuery.team = req.query.team
|
sessionQuery.team = req.query.team
|
||||||
|
|
||||||
# TODO: generalize this for levels based on their teams
|
# TODO: generalize this for levels based on their teams
|
||||||
else if level.get('type') is 'ladder'
|
else if level.get('type') in ['ladder', 'hero-ladder']
|
||||||
sessionQuery.team = 'humans'
|
sessionQuery.team = 'humans'
|
||||||
|
|
||||||
Session.findOne(sessionQuery).exec (err, doc) =>
|
Session.findOne(sessionQuery).exec (err, doc) =>
|
||||||
|
|
|
@ -279,7 +279,7 @@ fetchAndVerifyLevelType = (levelID, cb) ->
|
||||||
.lean()
|
.lean()
|
||||||
query.exec (err, levelWithType) ->
|
query.exec (err, levelWithType) ->
|
||||||
if err? then return cb err
|
if err? then return cb err
|
||||||
if not levelWithType.type or levelWithType.type isnt 'ladder' then return cb 'Level isn\'t of type "ladder"'
|
if not levelWithType.type or not (levelWithType.type in ['ladder', 'hero-ladder']) then return cb 'Level isn\'t of type "ladder"'
|
||||||
cb null
|
cb null
|
||||||
|
|
||||||
fetchSessionObjectToSubmit = (sessionID, callback) ->
|
fetchSessionObjectToSubmit = (sessionID, callback) ->
|
||||||
|
|
Loading…
Reference in a new issue