Refactor level type checks for easy greppability (level.isType)

This commit is contained in:
Nick Winter 2016-07-14 08:58:43 -07:00
parent 87ed53b24b
commit c0a70cb2ab
32 changed files with 114 additions and 115 deletions

View file

@ -52,7 +52,7 @@ module.exports = class LevelLoader extends CocoClass
@listenToOnce @supermodel, 'loaded-all', @onSupermodelLoaded
# Supermodel (Level) Loading
loadWorldNecessities: ->
# TODO: Actually trigger loading, instead of in the constructor
new Promise((resolve, reject) =>
@ -72,9 +72,9 @@ module.exports = class LevelLoader extends CocoClass
@listenToOnce @level, 'sync', @onLevelLoaded
onLevelLoaded: ->
if not @sessionless and @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course']
if not @sessionless and @level.isType('hero', 'hero-ladder', 'hero-coop', 'course')
@sessionDependenciesRegistered = {}
if (@courseID and @level.get('type', true) not in ['course', 'course-ladder']) or window.serverConfig.picoCTF
if (@courseID and not @level.isType('course', 'course-ladder')) or window.serverConfig.picoCTF
# Because we now use original hero levels for both hero and course levels, we fake being a course level in this context.
originalGet = @level.get
@level.get = ->
@ -179,7 +179,7 @@ module.exports = class LevelLoader extends CocoClass
@consolidateFlagHistory() if @opponentSession?.loaded
else if session is @opponentSession
@consolidateFlagHistory() if @session.loaded
if @level.get('type', true) in ['course'] # course-ladder is hard to handle because there's 2 sessions
if @level.isType('course') # course-ladder is hard to handle because there's 2 sessions
heroThangType = me.get('heroConfig')?.thangType or ThangType.heroes.captain
console.log "Course mode, loading custom hero: ", heroThangType if LOG
url = "/db/thang.type/#{heroThangType}/version"
@ -188,7 +188,7 @@ module.exports = class LevelLoader extends CocoClass
@worldNecessities.push heroResource
@sessionDependenciesRegistered[session.id] = true
return
return unless @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
return unless @level.isType('hero', 'hero-ladder', 'hero-coop')
heroConfig = session.get('heroConfig')
heroConfig ?= me.get('heroConfig') if session is @session and not @headless
heroConfig ?= {}
@ -453,7 +453,7 @@ module.exports = class LevelLoader extends CocoClass
@grabTeamConfigs()
@thangTypeTeams = {}
for thang in @level.get('thangs')
if @level.get('type', true) in ['hero', 'course'] and thang.id is 'Hero Placeholder'
if @level.isType('hero', 'course') and thang.id is 'Hero Placeholder'
continue # No team colors for heroes on single-player levels
for component in thang.components
if team = component.config?.team

View file

@ -74,7 +74,7 @@ module.exports = class LevelSetupManager extends CocoClass
@session.set 'heroConfig', {"thangType":raider,"inventory":{}}
@onInventoryModalPlayClicked()
return
if @level.get('type', true) in ['course', 'course-ladder'] or window.serverConfig.picoCTF
if @level.isType('course', 'course-ladder') or window.serverConfig.picoCTF
@onInventoryModalPlayClicked()
return
@heroesModal = new PlayHeroesModal({supermodel: @supermodel, session: @session, confirmButtonI18N: 'play.next', level: @level, hadEverChosenHero: @options.hadEverChosenHero})

View file

@ -34,7 +34,7 @@ module.exports = class Level extends CocoModel
for tt in supermodel.getModels ThangType
if tmap[tt.get('original')] or
(tt.get('kind') isnt 'Hero' and tt.get('kind')? and tt.get('components') and not tt.notInLevel) or
(tt.get('kind') is 'Hero' and ((@get('type', true) in ['course', 'course-ladder', 'game-dev']) or tt.get('original') in sessionHeroes))
(tt.get('kind') is 'Hero' and (@isType('course', 'course-ladder', 'game-dev') or tt.get('original') in sessionHeroes))
o.thangTypes.push (original: tt.get('original'), name: tt.get('name'), components: $.extend(true, [], tt.get('components')))
@sortThangComponents o.thangTypes, o.levelComponents, 'ThangType'
@fillInDefaultComponentConfiguration o.thangTypes, o.levelComponents
@ -59,7 +59,7 @@ module.exports = class Level extends CocoModel
denormalize: (supermodel, session, otherSession) ->
o = $.extend true, {}, @attributes
if o.thangs and @get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']
if o.thangs and @isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev')
thangTypesWithComponents = (tt for tt in supermodel.getModels(ThangType) when tt.get('components')?)
thangTypesByOriginal = _.indexBy thangTypesWithComponents, (tt) -> tt.get('original') # Optimization
for levelThang in o.thangs
@ -68,7 +68,7 @@ module.exports = class Level extends CocoModel
denormalizeThang: (levelThang, supermodel, session, otherSession, thangTypesByOriginal) ->
levelThang.components ?= []
isHero = /Hero Placeholder/.test(levelThang.id) and @get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
isHero = /Hero Placeholder/.test(levelThang.id) and @isType('hero', 'hero-ladder', 'hero-coop')
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.
@ -147,7 +147,7 @@ module.exports = class Level extends CocoModel
levelThang.components.push placeholderComponent
# Load the user's chosen hero AFTER getting stats from default char
if /Hero Placeholder/.test(levelThang.id) and @get('type', true) in ['course'] and not @headless and not @sessionless
if /Hero Placeholder/.test(levelThang.id) and @isType('course') and not @headless and not @sessionless
heroThangType = me.get('heroConfig')?.thangType or ThangType.heroes.captain
levelThang.thangType = heroThangType if heroThangType
@ -263,6 +263,9 @@ module.exports = class Level extends CocoModel
isLadder: ->
return @get('type')?.indexOf('ladder') > -1
isType: (types...) ->
return @get('type', true) in types
fetchNextForCourse: ({ levelOriginalID, courseInstanceID, courseID, sessionID }, options={}) ->
if courseInstanceID
options.url = "/db/course_instance/#{courseInstanceID}/levels/#{levelOriginalID}/sessions/#{sessionID}/next"

View file

@ -195,7 +195,7 @@ module.exports = class ClanDetailsView extends RootView
if level.concepts?
for concept in level.concepts
@conceptsProgression.push concept unless concept in @conceptsProgression
if level.type is 'hero-ladder' and level.slug not in ['capture-their-flag']
if level.type is 'hero-ladder' and level.slug not in ['capture-their-flag'] # Would use isType, but it's not a Level model
@arenas.push level
@campaignLevelProgressions.push campaignLevelProgression
@render?()

View file

@ -63,7 +63,7 @@ module.exports = class CourseDetailsView extends RootView
# need to figure out the next course instance
@courseComplete = true
@courseInstances.comparator = 'courseID'
# TODO: make this logic use locked course content to figure out the next course, then fetch the
# TODO: make this logic use locked course content to figure out the next course, then fetch the
# course instance for that
@supermodel.trackRequest(@courseInstances.fetchForClassroom(classroomID).then(=>
@nextCourseInstance = _.find @courseInstances.models, (ci) => ci.get('courseID') > @courseID
@ -87,7 +87,7 @@ module.exports = class CourseDetailsView extends RootView
@levelConceptMap[level.get('original')] ?= {}
for concept in level.get('concepts')
@levelConceptMap[level.get('original')][concept] = true
if level.get('type') is 'course-ladder'
if level.isType('course-ladder')
@arenaLevel = level
# console.log 'onLevelSessionsSync'
@ -125,13 +125,13 @@ module.exports = class CourseDetailsView extends RootView
for concept, state of conceptStateMap
@conceptsCompleted[concept] ?= 0
@conceptsCompleted[concept]++
onClickPlayLevel: (e) ->
levelSlug = $(e.target).closest('.btn-play-level').data('level-slug')
levelID = $(e.target).closest('.btn-play-level').data('level-id')
level = @levels.findWhere({original: levelID})
window.tracker?.trackEvent 'Students Class Course Play Level', category: 'Students', courseID: @courseID, courseInstanceID: @courseInstanceID, levelSlug: levelSlug, ['Mixpanel']
if level.get('type') is 'course-ladder'
if level.isType('course-ladder')
viewClass = 'views/ladder/LadderView'
viewArgs = [{supermodel: @supermodel}, levelSlug]
route = '/play/ladder/' + levelSlug

View file

@ -46,7 +46,7 @@ module.exports = class ThangComponentConfigView extends CocoView
schema.default ?= {}
_.merge schema.default, @additionalDefaults if @additionalDefaults
if @level?.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']
if @level?.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev')
schema.required = []
treemaOptions =
supermodel: @supermodel

View file

@ -41,7 +41,7 @@ module.exports = class LevelThangEditView extends CocoView
level: @level
world: @world
if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev'] then options.thangType = thangType
if @level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev') then options.thangType = thangType
@thangComponentEditView = new ThangComponentsEditView options
@listenTo @thangComponentEditView, 'components-changed', @onComponentsChanged

View file

@ -251,7 +251,7 @@ module.exports = class ThangsTabView extends CocoView
@dragged = 0
@willUnselectSprite = false
@gameUIState.set('canDragCamera', true)
if @addThangLank?.thangType.get('kind') is 'Wall'
@paintingWalls = true
@gameUIState.set('canDragCamera', false)
@ -259,7 +259,7 @@ module.exports = class ThangsTabView extends CocoView
else if @addThangLank
# We clicked on the background when we had an add Thang selected, so add it
@addThang @addThangType, @addThangLank.thang.pos
else if e.onBackground
@gameUIState.set('selected', [])
@ -331,18 +331,18 @@ module.exports = class ThangsTabView extends CocoView
@onSpriteContextMenu e
clearInterval(@movementInterval) if @movementInterval?
@movementInterval = null
return unless _.any(selected)
for singleSelected in selected
pos = singleSelected.thang.pos
thang = _.find(@level.get('thangs') ? [], {id: singleSelected.thang.id})
path = "#{@pathForThang(thang)}/components/original=#{LevelComponent.PhysicalID}"
physical = @thangsTreema.get path
continue if not physical or (physical.config.pos.x is pos.x and physical.config.pos.y is pos.y)
@thangsTreema.set path + '/config/pos', x: pos.x, y: pos.y, z: pos.z
if @willUnselectSprite
clickedSprite = _.find(selected, {sprite: e.sprite})
@gameUIState.set('selected', _.without(selected, clickedSprite))
@ -379,7 +379,7 @@ module.exports = class ThangsTabView extends CocoView
thang = selected?.thang
previousSprite?.setNameLabel?(null) unless previousSprite is sprite
if thang and not (@addThangLank and @addThangType.get('name') in overlappableThangTypeNames)
# We clicked on a Thang (or its Treema), so select the Thang
@selectAddThang(null, true)
@ -619,7 +619,7 @@ module.exports = class ThangsTabView extends CocoView
onTreemaThangSelected: (e, selectedTreemas) =>
selectedThangTreemas = _.filter(selectedTreemas, (t) -> t instanceof ThangNode)
thangIDs = (node.data.id for node in selectedThangTreemas)
lanks = (@surface.lankBoss.lanks[thangID] for thangID in thangIDs when thangID)
lanks = (@surface.lankBoss.lanks[thangID] for thangID in thangIDs when thangID)
selected = ({ thang: lank.thang, sprite: lank } for lank in lanks when lank)
@gameUIState.set('selected', selected)
@ -636,14 +636,14 @@ module.exports = class ThangsTabView extends CocoView
if batchInsert
if thangType.get('name') is 'Hero Placeholder'
thangID = 'Hero Placeholder'
return if not (@level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']) or @getThangByID(thangID)
return if not @level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev') or @getThangByID(thangID)
else
thangID = "Random #{thangType.get('name')} #{@thangsBatch.length}"
else
thangID = Thang.nextID(thangType.get('name'), @world) until thangID and not @getThangByID(thangID)
if @cloneSourceThang
components = _.cloneDeep @getThangByID(@cloneSourceThang.id).components
else if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']
else if @level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev')
components = [] # Load them all from default ThangType Components
else
components = _.cloneDeep thangType.get('components') ? []

View file

@ -51,7 +51,7 @@ module.exports = class VerifierView extends RootView
for campaign in @campaigns.models when campaign.get('type') in ['course', 'hero'] and campaign.get('slug') isnt 'picoctf'
@levelsByCampaign[campaign.get('slug')] ?= {levels: [], checked: true}
campaignInfo = @levelsByCampaign[campaign.get('slug')]
for levelID, level of campaign.get('levels') when level.type not in ['hero-ladder', 'course-ladder', 'game-dev']
for levelID, level of campaign.get('levels') when level.type not in ['hero-ladder', 'course-ladder', 'game-dev'] # Would use isType, but it's not a Level model
campaignInfo.levels.push level.slug
filterCodeLanguages: ->

View file

@ -24,7 +24,7 @@ module.exports = class SimulateTabView extends CocoView
onLoaded: ->
super()
@render()
if (document.location.hash is '#simulate' or @options.level.get('type') is 'course-ladder') and not @simulator
if (document.location.hash is '#simulate' or @options.level.isType('course-ladder')) and not @simulator
@startSimulating()
afterRender: ->

View file

@ -398,7 +398,7 @@ module.exports = class CampaignView extends RootView
@particleMan.attach @$el.find('.map')
for level in @campaign.renderedLevels ? {}
particleKey = ['level', @terrain.replace('-branching-test', '')]
particleKey.push level.type if level.type and not (level.type in ['hero', 'course'])
particleKey.push level.type if level.type and not (level.type in ['hero', 'course']) # Would use isType, but it's not a Level model
particleKey.push 'replayable' if level.replayable
particleKey.push 'premium' if level.requiresSubscription
particleKey.push 'gate' if level.slug in ['kithgard-gates', 'siege-of-stonehold', 'clash-of-clones', 'summits-gate']
@ -532,7 +532,7 @@ module.exports = class CampaignView extends RootView
levelElement = $(e.target).parents('.level-info-container')
levelSlug = levelElement.data('level-slug')
level = _.find _.values(@campaign.get('levels')), slug: levelSlug
if level.type in ['hero-ladder', 'course-ladder']
if level.type in ['hero-ladder', 'course-ladder'] # Would use isType, but it's not a Level model
Backbone.Mediator.publish 'router:navigate', route: "/play/ladder/#{levelSlug}", viewClass: 'views/ladder/LadderView', viewArgs: [{supermodel: @supermodel}, levelSlug]
else
@showLeaderboard levelSlug

View file

@ -181,7 +181,7 @@ module.exports = class SpectateLevelView extends RootView
@insertSubView new GoldView {}
@insertSubView new HUDView {level: @level}
@insertSubView new DuelStatsView level: @level, session: @session, otherSession: @otherSession, supermodel: @supermodel, thangs: @world.thangs if @level.get('type') in ['hero-ladder', 'course-ladder']
@insertSubView new DuelStatsView level: @level, session: @session, otherSession: @otherSession, supermodel: @supermodel, thangs: @world.thangs if @level.isType('hero-ladder', 'course-ladder')
@insertSubView @controlBar = new ControlBarView {worldName: utils.i18n(@level.attributes, 'name'), session: @session, level: @level, supermodel: @supermodel, spectateGame: true}
# callbacks

View file

@ -45,7 +45,7 @@ module.exports = class ControlBarView extends CocoView
@observing = options.session.get('creator') isnt me.id
@levelNumber = ''
if @level.get('type') is 'course' and @level.get('campaignIndex')?
if @level.isType('course') and @level.get('campaignIndex')?
@levelNumber = @level.get('campaignIndex') + 1
if @courseInstanceID
@courseInstance = new CourseInstance(_id: @courseInstanceID)
@ -64,7 +64,7 @@ module.exports = class ControlBarView extends CocoView
@supermodel.trackRequest(@campaign.fetch())
)
super options
if @level.get('type') in ['hero-ladder', 'course-ladder'] and me.isAdmin()
if @level.isType('hero-ladder', 'course-ladder') and me.isAdmin()
@isMultiplayerLevel = true
@multiplayerStatusManager = new MultiplayerStatusManager @levelID, @onMultiplayerStateChanged
if @level.get 'replayable'
@ -95,7 +95,7 @@ module.exports = class ControlBarView extends CocoView
super c
c.worldName = @worldName
c.multiplayerEnabled = @session.get('multiplayer')
c.ladderGame = @level.get('type') in ['ladder', 'hero-ladder', 'course-ladder']
c.ladderGame = @level.isType('ladder', 'hero-ladder', 'course-ladder')
if c.isMultiplayerLevel = @isMultiplayerLevel
c.multiplayerStatus = @multiplayerStatusManager?.status
if @level.get 'replayable'
@ -110,23 +110,23 @@ module.exports = class ControlBarView extends CocoView
if me.isSessionless()
@homeLink = "/teachers/courses"
@homeViewClass = "views/courses/TeacherCoursesView"
else if @level.get('type', true) in ['ladder', 'ladder-tutorial', 'hero-ladder', 'course-ladder']
else if @level.isType('ladder', 'ladder-tutorial', 'hero-ladder', 'course-ladder')
levelID = @level.get('slug')?.replace(/\-tutorial$/, '') or @level.id
@homeLink = '/play/ladder/' + levelID
@homeViewClass = 'views/ladder/LadderView'
@homeViewArgs.push levelID
if leagueID = @getQueryVariable 'league'
leagueType = if @level.get('type') is 'course-ladder' then 'course' else 'clan'
leagueType = if @level.isType('course-ladder') then 'course' else 'clan'
@homeViewArgs.push leagueType
@homeViewArgs.push leagueID
@homeLink += "/#{leagueType}/#{leagueID}"
else if @level.get('type', true) in ['hero', 'hero-coop'] or window.serverConfig.picoCTF
else if @level.isType('hero', 'hero-coop') or window.serverConfig.picoCTF
@homeLink = '/play'
@homeViewClass = 'views/play/CampaignView'
campaign = @level.get 'campaign'
@homeLink += '/' + campaign
@homeViewArgs.push campaign
else if @level.get('type', true) in ['course']
else if @level.isType('course')
@homeLink = '/courses'
@homeViewClass = 'views/courses/CoursesView'
if @courseID
@ -136,7 +136,7 @@ module.exports = class ControlBarView extends CocoView
if @courseInstanceID
@homeLink += "/#{@courseInstanceID}"
@homeViewArgs.push @courseInstanceID
#else if @level.get('type', true) is 'game-dev' # TODO
#else if @level.isType('game-dev') # TODO
else
@homeLink = '/'
@homeViewClass = 'views/HomeView'
@ -153,7 +153,7 @@ module.exports = class ControlBarView extends CocoView
@setupManager.open()
onClickHome: (e) ->
if @level.get('type', true) in ['course']
if @level.isType('course')
category = if me.isTeacher() then 'Teachers' else 'Students'
window.tracker?.trackEvent 'Play Level Back To Levels', category: category, levelSlug: @levelSlug, ['Mixpanel']
e.preventDefault()

View file

@ -49,7 +49,7 @@ module.exports = class LevelGoalsView extends CocoView
goals = []
for goal in e.goals
state = e.goalStates[goal.id]
continue if goal.optional and @level.get('type', true) is 'course' and state.status isnt 'success'
continue if goal.optional and @level.isType('course') and state.status isnt 'success'
if goal.hiddenGoal
continue if goal.optional and state.status isnt 'success'
continue if not goal.optional and state.status isnt 'failure'

View file

@ -100,7 +100,7 @@ module.exports = class LevelHUDView extends CocoView
@stage?.stopTalking()
createProperties: ->
if @options.level.get('type') in ['game-dev']
if @options.level.isType('game-dev')
name = 'Game' # TODO: we don't need the HUD at all
else if @thang.id in ['Hero Placeholder', 'Hero Placeholder 1']
name = @thangType?.getHeroShortName() or 'Hero'

View file

@ -59,7 +59,7 @@ module.exports = class LevelLoadingView extends CocoView
goalList = goalContainer.find('ul')
goalCount = 0
for goalID, goal of @level.get('goals') when (not goal.team or goal.team is (e.team or 'humans')) and not goal.hiddenGoal
continue if goal.optional and @level.get('type', true) is 'course'
continue if goal.optional and @level.isType('course')
name = utils.i18n goal, 'name'
goalList.append $('<li>' + name + '</li>')
++goalCount

View file

@ -205,7 +205,7 @@ module.exports = class PlayLevelView extends RootView
@session = @levelLoader.session
@world = @levelLoader.world
@level = @levelLoader.level
@$el.addClass 'hero' if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']
@$el.addClass 'hero' if @level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev')
@$el.addClass 'flags' if _.any(@world.thangs, (t) -> (t.programmableProperties and 'findFlags' in t.programmableProperties) or t.inventory?.flag) or @level.get('slug') is 'sky-span'
# TODO: Update terminology to always be opponentSession or otherSession
# TODO: E.g. if it's always opponent right now, then variable names should be opponentSession until we have coop play
@ -271,7 +271,7 @@ module.exports = class PlayLevelView extends RootView
@insertSubView new LevelDialogueView {level: @level, sessionID: @session.id}
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
@insertSubView new ProblemAlertView session: @session, level: @level, supermodel: @supermodel
@insertSubView new DuelStatsView level: @level, session: @session, otherSession: @otherSession, supermodel: @supermodel, thangs: @world.thangs if @level.get('type') in ['hero-ladder', 'course-ladder']
@insertSubView new DuelStatsView level: @level, session: @session, otherSession: @otherSession, supermodel: @supermodel, thangs: @world.thangs if @level.isType('hero-ladder', 'course-ladder')
@insertSubView @controlBar = new ControlBarView {worldName: utils.i18n(@level.attributes, 'name'), session: @session, level: @level, supermodel: @supermodel, courseID: @courseID, courseInstanceID: @courseInstanceID}
@insertSubView @hintsView = new HintsView({ @session, @level, @hintsState }), @$('.hints-view')
#_.delay (=> Backbone.Mediator.publish('level:set-debug', debug: true)), 5000 if @isIPadApp() # if me.displayName() is 'Nick'
@ -310,12 +310,12 @@ module.exports = class PlayLevelView extends RootView
else if e.level.get('slug') is 'assembly-speed'
raider = '55527eb0b8abf4ba1fe9a107'
e.session.set 'heroConfig', {"thangType":raider,"inventory":{}}
else if e.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] and not _.size e.session.get('heroConfig')?.inventory ? {}
else if e.level.isType('hero', 'hero-ladder', 'hero-coop') and not _.size e.session.get('heroConfig')?.inventory ? {}
@setupManager?.destroy()
@setupManager = new LevelSetupManager({supermodel: @supermodel, level: e.level, levelID: @levelID, parent: @, session: e.session, courseID: @courseID, courseInstanceID: @courseInstanceID})
@setupManager.open()
@onRealTimeMultiplayerLevelLoaded e.session if e.level.get('type') in ['hero-ladder', 'course-ladder']
@onRealTimeMultiplayerLevelLoaded e.session if e.level.isType('hero-ladder', 'course-ladder')
onLoaded: ->
_.defer => @onLevelLoaderLoaded()
@ -325,7 +325,7 @@ module.exports = class PlayLevelView extends RootView
return unless @levelLoader.progress() is 1 # double check, since closing the guide may trigger this early
# Save latest level played.
if not @observing and not (@levelLoader.level.get('type') in ['ladder', 'ladder-tutorial'])
if not @observing and not (@levelLoader.level.isType('ladder', 'ladder-tutorial'))
me.set('lastLevel', @levelID)
me.save()
application.tracker?.identify()
@ -360,7 +360,7 @@ module.exports = class PlayLevelView extends RootView
@surface.camera.zoomTo({x: 0, y: 0}, 0.1, 0)
findPlayerNames: ->
return {} unless @level.get('type') in ['ladder', 'hero-ladder', 'course-ladder']
return {} unless @level.isType('ladder', 'hero-ladder', 'course-ladder')
playerNames = {}
for session in [@session, @otherSession] when session?.get('team')
playerNames[session.get('team')] = session.get('creatorName') or 'Anonymous'
@ -386,7 +386,7 @@ module.exports = class PlayLevelView extends RootView
@selectHero()
onLoadingViewUnveiled: (e) ->
if @level.get('type') in ['course-ladder', 'hero-ladder'] or @observing
if @level.isType('course-ladder', 'hero-ladder') or @observing
# We used to autoplay by default, but now we only do it if the level says to in the introduction script.
Backbone.Mediator.publish 'level:set-playing', playing: true
@loadingView.$el.remove()
@ -440,7 +440,7 @@ module.exports = class PlayLevelView extends RootView
simulateNextGame: ->
return @simulator.fetchAndSimulateOneGame() if @simulator
simulatorOptions = background: true, leagueID: @courseInstanceID
simulatorOptions.levelID = @level.get('slug') if @level.get('type', true) in ['course-ladder', 'hero-ladder']
simulatorOptions.levelID = @level.get('slug') if @level.isType('course-ladder', 'hero-ladder')
@simulator = new Simulator simulatorOptions
# Crude method of mitigating Simulator memory leak issues
fetchAndSimulateOneGameOriginal = @simulator.fetchAndSimulateOneGame
@ -462,31 +462,30 @@ module.exports = class PlayLevelView extends RootView
cores = window.navigator.hardwareConcurrency or defaultCores # Available on Chrome/Opera, soon Safari
defaultHeapLimit = 793000000
heapLimit = window.performance?.memory?.jsHeapSizeLimit or defaultHeapLimit # Only available on Chrome, basically just says 32- vs. 64-bit
levelType = @level.get 'type', true
gamesSimulated = me.get('simulatedBy')
console.debug "Should we start simulating? Cores:", window.navigator.hardwareConcurrency, "Heap limit:", window.performance?.memory?.jsHeapSizeLimit, "Load duration:", @loadDuration
return false unless $.browser?.desktop
return false if $.browser?.msie or $.browser?.msedge
return false if $.browser.linux
return false if me.level() < 8
if levelType in ['course', 'game-dev']
if @level.isType('course', 'game-dev')
return false
else if levelType is 'hero' and gamesSimulated
else if @level.isType('hero') and gamesSimulated
return false if stillBuggy
return false if cores < 8
return false if heapLimit < defaultHeapLimit
return false if @loadDuration > 10000
else if levelType is 'hero-ladder' and gamesSimulated
else if @level.isType('hero-ladder') and gamesSimulated
return false if stillBuggy
return false if cores < 4
return false if heapLimit < defaultHeapLimit
return false if @loadDuration > 15000
else if levelType is 'hero-ladder' and not gamesSimulated
else if @level.isType('hero-ladder') and not gamesSimulated
return false if stillBuggy
return false if cores < 8
return false if heapLimit <= defaultHeapLimit
return false if @loadDuration > 20000
else if levelType is 'course-ladder'
else if @level.isType('course-ladder')
return false if cores <= defaultCores
return false if heapLimit < defaultHeapLimit
return false if @loadDuration > 18000
@ -542,7 +541,7 @@ module.exports = class PlayLevelView extends RootView
onDonePressed: -> @showVictory()
onShowVictory: (e) ->
$('#level-done-button').show() unless @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']
$('#level-done-button').show() unless @level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev')
@showVictory() if e.showModal
return if @victorySeen
@victorySeen = true
@ -560,7 +559,7 @@ module.exports = class PlayLevelView extends RootView
return if @level.hasLocalChanges() # Don't award achievements when beating level changed in level editor
@endHighlight()
options = {level: @level, supermodel: @supermodel, session: @session, hasReceivedMemoryWarning: @hasReceivedMemoryWarning, courseID: @courseID, courseInstanceID: @courseInstanceID, world: @world}
ModalClass = if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev'] then HeroVictoryModal else VictoryModal
ModalClass = if @level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev') then HeroVictoryModal else VictoryModal
ModalClass = CourseVictoryModal if @isCourseMode() or me.isSessionless()
ModalClass = PicoCTFVictoryModal if window.serverConfig.picoCTF
victoryModal = new ModalClass(options)

View file

@ -49,7 +49,7 @@ module.exports = class HeroVictoryModal extends ModalView
@session = options.session
@level = options.level
@thangTypes = {}
if @level.get('type', true) in ['hero', 'hero-ladder', 'course', 'course-ladder', 'game-dev']
if @level.isType('hero', 'hero-ladder', 'course', 'course-ladder', 'game-dev')
achievements = new CocoCollection([], {
url: "/db/achievement?related=#{@session.get('level').original}"
model: Achievement
@ -63,14 +63,14 @@ module.exports = class HeroVictoryModal extends ModalView
else
@readyToContinue = true
@playSound 'victory'
if @level.get('type', true) is 'course'
if @level.isType('course')
if nextLevel = @level.get('nextLevel')
@nextLevel = new Level().setURL "/db/level/#{nextLevel.original}/version/#{nextLevel.majorVersion}"
@nextLevel = @supermodel.loadModel(@nextLevel).model
if @courseID
@course = new Course().setURL "/db/course/#{@courseID}"
@course = @supermodel.loadModel(@course).model
if @level.get('type', true) in ['course', 'course-ladder']
if @level.isType('course', 'course-ladder')
@saveReviewEventually = _.debounce(@saveReviewEventually, 2000)
@loadExistingFeedback()
# TODO: support game-dev
@ -155,7 +155,7 @@ module.exports = class HeroVictoryModal extends ModalView
c = super()
c.levelName = utils.i18n @level.attributes, 'name'
# TODO: support 'game-dev'
if @level.get('type', true) not in ['hero', 'game-dev']
if @level.isType('hero', 'game-dev')
c.victoryText = utils.i18n @level.get('victory') ? {}, 'body'
earnedAchievementMap = _.indexBy(@newEarnedAchievements or [], (ea) -> ea.get('achievement'))
for achievement in (@achievements?.models or [])
@ -192,7 +192,7 @@ module.exports = class HeroVictoryModal extends ModalView
c.thangTypes = @thangTypes
c.me = me
c.readyToRank = @level.get('type', true) in ['hero-ladder', 'course-ladder'] and @session.readyToRank()
c.readyToRank = @level.isType('hero-ladder', 'course-ladder') and @session.readyToRank()
c.level = @level
c.i18n = utils.i18n
@ -211,10 +211,10 @@ module.exports = class HeroVictoryModal extends ModalView
# Show the "I'm done" button between 30 - 120 minutes if they definitely came from Hour of Code
c.showHourOfCodeDoneButton = showDone
c.showLeaderboard = @level.get('scoreTypes')?.length > 0 and @level.get('type', true) isnt 'course'
c.showLeaderboard = @level.get('scoreTypes')?.length > 0 and not @level.isType('course')
c.showReturnToCourse = not c.showLeaderboard and not me.get('anonymous') and @level.get('type', true) in ['course', 'course-ladder']
c.isCourseLevel = @level.get('type', true) in ['course']
c.showReturnToCourse = not c.showLeaderboard and not me.get('anonymous') and @level.isType('course', 'course-ladder')
c.isCourseLevel = @level.isType('course')
c.currentCourseName = @course?.get('name')
c.currentLevelName = @level?.get('name')
c.nextLevelName = @nextLevel?.get('name')
@ -223,17 +223,17 @@ module.exports = class HeroVictoryModal extends ModalView
afterRender: ->
super()
@$el.toggleClass 'with-achievements', @level.get('type', true) in ['hero', 'hero-ladder', 'game-dev'] # TODO: support game-dev
@$el.toggleClass 'with-achievements', @level.isType('hero', 'hero-ladder', 'game-dev') # TODO: support game-dev
return unless @supermodel.finished()
@playSelectionSound hero, true for original, hero of @thangTypes # Preload them
@updateSavingProgressStatus()
@initializeAnimations()
if @level.get('type', true) in ['hero-ladder', 'course-ladder']
if @level.isType('hero-ladder', 'course-ladder')
@ladderSubmissionView = new LadderSubmissionView session: @session, level: @level
@insertSubView @ladderSubmissionView, @$el.find('.ladder-submission-view')
initializeAnimations: ->
return @endSequentialAnimations() unless @level.get('type', true) in ['hero', 'hero-ladder', 'game-dev'] # TODO: support game-dev
return @endSequentialAnimations() unless @level.isType('hero', 'hero-ladder', 'game-dev') # TODO: support game-dev
@updateXPBars 0
#playVictorySound = => @playSound 'victory-title-appear' # TODO: actually add this
@$el.find('#victory-header').delay(250).queue(->
@ -264,7 +264,7 @@ module.exports = class HeroVictoryModal extends ModalView
beginSequentialAnimations: ->
return if @destroyed
return unless @level.get('type', true) in ['hero', 'hero-ladder', 'game-dev'] # TODO: support game-dev
return unless @level.isType('hero', 'hero-ladder', 'game-dev') # TODO: support game-dev
@sequentialAnimatedPanels = _.map(@animatedPanels.find('.reward-panel'), (panel) -> {
number: $(panel).data('number')
previousNumber: $(panel).data('previous-number')
@ -394,7 +394,7 @@ module.exports = class HeroVictoryModal extends ModalView
viewArgs = [{supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel}, @level.get('slug')]
ladderURL = "/play/ladder/#{@level.get('slug') || @level.id}"
if leagueID = (@courseInstanceID or @getQueryVariable 'league')
leagueType = if @level.get('type') is 'course-ladder' then 'course' else 'clan'
leagueType = if @level.isType('course-ladder') then 'course' else 'clan'
viewArgs.push leagueType
viewArgs.push leagueID
ladderURL += "/#{leagueType}/#{leagueID}"
@ -414,14 +414,14 @@ module.exports = class HeroVictoryModal extends ModalView
{'kithgard-gates': 'forest', 'kithgard-mastery': 'forest', 'siege-of-stonehold': 'desert', 'clash-of-clones': 'mountain', 'summits-gate': 'glacier'}[@level.get('slug')] or @level.get 'campaign' # Much easier to just keep this updated than to dynamically figure it out.
getNextLevelLink: (returnToCourse=false) ->
if @level.get('type', true) is 'course' and nextLevel = @level.get('nextLevel') and not returnToCourse
if @level.isType('course') and nextLevel = @level.get('nextLevel') and not returnToCourse
# need to do something more complicated to load its slug
console.log 'have @nextLevel', @nextLevel, 'from nextLevel', nextLevel
link = "/play/level/#{@nextLevel.get('slug')}"
if @courseID
link += "?course=#{@courseID}"
link += "&course-instance=#{@courseInstanceID}" if @courseInstanceID
else if @level.get('type', true) is 'course'
else if @level.isType('course')
link = "/courses"
if @courseID
link += "/#{@courseID}"
@ -440,12 +440,12 @@ module.exports = class HeroVictoryModal extends ModalView
justBeatLevel: @level
supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel
_.merge options, extraOptions if extraOptions
if @level.get('type', true) is 'course' and @nextLevel and not options.returnToCourse
if @level.isType('course') and @nextLevel and not options.returnToCourse
viewClass = require 'views/play/level/PlayLevelView'
options.courseID = @courseID
options.courseInstanceID = @courseInstanceID
viewArgs = [options, @nextLevel.get('slug')]
else if @level.get('type', true) is 'course'
else if @level.isType('course')
# TODO: shouldn't set viewClass and route in different places
viewClass = require 'views/courses/CoursesView'
viewArgs = [options]
@ -453,7 +453,7 @@ module.exports = class HeroVictoryModal extends ModalView
viewClass = require 'views/courses/CourseDetailsView'
viewArgs.push @courseID
viewArgs.push @courseInstanceID if @courseInstanceID
else if @level.get('type', true) is 'course-ladder'
else if @level.isType('course-ladder')
leagueID = @courseInstanceID or @getQueryVariable 'league'
nextLevelLink = "/play/ladder/#{@level.get('slug')}"
nextLevelLink += "/course/#{leagueID}" if leagueID

View file

@ -71,7 +71,7 @@ module.exports = class VictoryModal extends ModalView
c.me = me
c.levelName = utils.i18n @level.attributes, 'name'
c.level = @level
if c.level.get('type') is 'ladder'
if c.level.isType('ladder')
c.readyToRank = @session.readyToRank()
c

View file

@ -139,7 +139,7 @@ module.exports = class DocFormatter
if @doc.args
arg.example = arg.example.replace thisToken[@options.language], 'hero' for arg in @doc.args when arg.example
if @doc.shortName is 'loop' and @options.level.get('type', true) in ['course', 'course-ladder']
if @doc.shortName is 'loop' and @options.level.isType('course', 'course-ladder')
@replaceSimpleLoops()
replaceSimpleLoops: ->

View file

@ -20,8 +20,6 @@ module.exports = class Spell
@supermodel = options.supermodel
@skipProtectAPI = options.skipProtectAPI
@worker = options.worker
@levelID = options.levelID
@levelType = options.level.get('type', true)
@level = options.level
p = options.programmableMethod
@ -49,7 +47,7 @@ module.exports = class Spell
@isAISource = true
@thangs = {}
if @canRead() # We can avoid creating these views if we'll never use them.
@view = new SpellView {spell: @, level: options.level, session: @session, otherSession: @otherSession, worker: @worker, god: options.god, @supermodel}
@view = new SpellView {spell: @, level: options.level, session: @session, otherSession: @otherSession, worker: @worker, god: options.god, @supermodel, levelID: options.levelID}
@view.render() # Get it ready and code loaded in advance
@tabView = new SpellListTabEntryView
hintsState: options.hintsState
@ -87,7 +85,7 @@ module.exports = class Spell
catch e
console.error "Couldn't create example code template of", @originalSource, "\nwith context", context, "\nError:", e
if /loop/.test(@originalSource) and @levelType in ['course', 'course-ladder']
if /loop/.test(@originalSource) and @level.isType('course', 'course-ladder')
# Temporary hackery to make it look like we meant while True: in our sample code until we can update everything
@originalSource = switch @language
when 'python' then @originalSource.replace /loop:/, 'while True:'
@ -169,9 +167,9 @@ module.exports = class Spell
createAether: (thang) ->
writable = @permissions.readwrite.length > 0 and not @isAISource
skipProtectAPI = @skipProtectAPI or not writable or @levelType in ['game-dev']
skipProtectAPI = @skipProtectAPI or not writable or @level.isType('game-dev')
problemContext = @createProblemContext thang
includeFlow = (@levelType in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']) and not skipProtectAPI
includeFlow = @level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev') and not skipProtectAPI
aetherOptions = createAetherOptions
functionName: @name
codeLanguage: @language

View file

@ -37,7 +37,6 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
context.maximizeShortcutVerbose = "#{ctrl}+#{shift}+M: #{$.i18n.t 'keyboard_shortcuts.maximize_editor'}"
context.includeSpellList = @options.level.get('slug') in ['break-the-prison', 'zone-of-danger', 'k-means-cluster-wars', 'brawlwood', 'dungeon-arena', 'sky-span', 'minimax-tic-tac-toe']
context.codeLanguage = @options.codeLanguage
context.levelType = @options.level.get 'type', true
context
afterRender: ->

View file

@ -84,7 +84,7 @@ module.exports = class SpellPaletteEntryView extends CocoView
Backbone.Mediator.publish 'tome:palette-pin-toggled', entry: @, pinned: @popoverPinned
onClick: (e) =>
if true or @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']
if true or @options.level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev')
# Jiggle instead of pin for hero levels
# Actually, do it all the time, because we recently busted the pin CSS. TODO: restore pinning
jigglyPopover = $('.spell-palette-popover.popover')

View file

@ -157,7 +157,7 @@ module.exports = class SpellPaletteView extends CocoView
else
propStorage =
'this': ['apiProperties', 'apiMethods']
if not (@options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']) or not @options.programmable
if not @options.level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev') or not @options.programmable
@organizePalette propStorage, allDocs, excludedDocs
else
@organizePaletteHero propStorage, allDocs, excludedDocs
@ -199,7 +199,7 @@ module.exports = class SpellPaletteView extends CocoView
if tabbify and _.find @entries, ((entry) -> entry.doc.owner isnt 'this')
@entryGroups = _.groupBy @entries, groupForEntry
else
i18nKey = if @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev'] then 'play_level.tome_your_skills' else 'play_level.tome_available_spells'
i18nKey = if @options.level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev') then 'play_level.tome_your_skills' else 'play_level.tome_available_spells'
defaultGroup = $.i18n.t i18nKey
@entryGroups = {}
@entryGroups[defaultGroup] = @entries

View file

@ -502,7 +502,7 @@ module.exports = class SpellView extends CocoView
return unless @zatanna and @autocomplete
@zatanna.addCodeCombatSnippets @options.level, @, e
translateFindNearest: ->
# If they have advanced glasses but are playing a level which assumes earlier glasses, we'll adjust the sample code to use the more advanced APIs instead.
@ -554,7 +554,7 @@ module.exports = class SpellView extends CocoView
@createToolbarView()
createDebugView: ->
return if @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev'] # We'll turn this on later, maybe, but not yet.
return if @options.level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev') # We'll turn this on later, maybe, but not yet.
@debugView = new SpellDebugView ace: @ace, thang: @thang, spell:@spell
@$el.append @debugView.render().$el.hide()
@ -811,7 +811,7 @@ module.exports = class SpellView extends CocoView
for aetherProblem, problemIndex in aether.getAllProblems()
continue if key = aetherProblem.userInfo?.key and key of seenProblemKeys
seenProblemKeys[key] = true if key
@problems.push problem = new Problem aether, aetherProblem, @ace, isCast, @spell.levelID
@problems.push problem = new Problem aether, aetherProblem, @ace, isCast, @options.levelID
if isCast and problemIndex is 0
if problem.aetherProblem.range?
lineOffsetPx = 0
@ -859,7 +859,7 @@ module.exports = class SpellView extends CocoView
@userCodeProblem.set 'errRange', aetherProblem.range if aetherProblem.range
@userCodeProblem.set 'errType', aetherProblem.type if aetherProblem.type
@userCodeProblem.set 'language', aether.language.id if aether.language?.id
@userCodeProblem.set 'levelID', @spell.levelID if @spell.levelID
@userCodeProblem.set 'levelID', @options.levelID if @options.levelID
@userCodeProblem.save()
null

View file

@ -60,7 +60,7 @@ module.exports = class TomeView extends CocoView
@worker = @createWorker()
programmableThangs = _.filter @options.thangs, (t) -> t.isProgrammable and t.programmableMethods
@createSpells programmableThangs, programmableThangs[0]?.world # Do before spellList, thangList, and castButton
unless @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev']
unless @options.level.isType('hero', 'hero-ladder', 'hero-coop', 'course', 'course-ladder', 'game-dev')
@spellList = @insertSubView new SpellListView spells: @spells, supermodel: @supermodel, level: @options.level
@castButton = @insertSubView new CastButtonView spells: @spells, level: @options.level, session: @options.session, god: @options.god
@teamSpellMap = @generateTeamSpellMap(@spells)

View file

@ -1,6 +1,6 @@
utils = require 'core/utils'
defaults =
defaults =
autoLineEndings:
# Mapping ace mode language to line endings to automatically insert
# E.g. javascript: ";"
@ -69,7 +69,7 @@ module.exports = class Zatanna
@editor.commands.on 'afterExec', @doLiveCompletion
setAceOptions: () ->
aceOptions =
aceOptions =
'enableLiveAutocompletion': @options.liveCompletion
'enableBasicAutocompletion': @options.basic
'enableSnippets': @options.completers.snippets
@ -92,20 +92,20 @@ module.exports = class Zatanna
else if typeof comp is 'string'
if @completers[comp]? and @editor.completers[@completers[comp].pos] isnt @completers[comp].comp
@editor.completers.splice(@completers[comp].pos, 0, @completers[comp].comp)
else
else
@editor.completers = []
for type, comparator of @completers
if @options.completers[type] is true
@activateCompleter type
@activateCompleter type
addSnippets: (snippets, language) ->
@options.language = language
ace.config.loadModule 'ace/ext/language_tools', () =>
@snippetManager = ace.require('ace/snippets').snippetManager
snippetModulePath = 'ace/snippets/' + language
ace.config.loadModule snippetModulePath, (m) =>
ace.config.loadModule snippetModulePath, (m) =>
if m?
@snippetManager.files[language] = m
@snippetManager.files[language] = m
@snippetManager.unregister m.snippets if m.snippets?.length > 0
@snippetManager.unregister @oldSnippets if @oldSnippets?
m.snippets = if @options.snippetsLangDefaults then @snippetManager.parseSnippetFile m.snippetText else []
@ -265,7 +265,7 @@ module.exports = class Zatanna
when 'python' then 'loop:\n self.moveRight()\n ${1:}'
when 'javascript' then 'loop {\n this.moveRight();\n ${1:}\n}'
else content
if /loop/.test(content) and level.get('type') in ['course', 'course-ladder']
if /loop/.test(content) and level.isType('course', 'course-ladder')
# Temporary hackery to make it look like we meant while True: in our loop snippets until we can update everything
content = switch e.language
when 'python' then content.replace /loop:/, 'while True:'

View file

@ -35,7 +35,7 @@ module.exports = class GameMenuModal extends ModalView
submenus = _.without submenus, 'options' if window.serverConfig.picoCTF
submenus = _.without submenus, 'guide' unless docs.specificArticles?.length or docs.generalArticles?.length or window.serverConfig.picoCTF
submenus = _.without submenus, 'save-load' unless me.isAdmin() or /https?:\/\/localhost/.test(window.location.href)
submenus = _.without submenus, 'multiplayer' unless me.isAdmin() or (@level?.get('type') in ['ladder', 'hero-ladder', 'course-ladder'] and @level.get('slug') not in ['ace-of-coders', 'elemental-wars'])
submenus = _.without submenus, 'multiplayer' unless me.isAdmin() or (@level?.isType('ladder', 'hero-ladder', 'course-ladder') and @level.get('slug') not in ['ace-of-coders', 'elemental-wars'])
@includedSubmenus = submenus
context.showTab = @options.showTab ? submenus[0]
context.submenus = submenus
@ -47,7 +47,7 @@ module.exports = class GameMenuModal extends ModalView
context
showsChooseHero: ->
return false if @level?.get('type') in ['course', 'course-ladder']
return false if @level?.isType('course', 'course-ladder')
return false if @options.levelID in ['zero-sum', 'ace-of-coders', 'elemental-wars']
return true

View file

@ -19,7 +19,7 @@ module.exports = class LevelGuideView extends CocoView
@levelSlug = options.level.get('slug')
@sessionID = options.session.get('_id')
@requiresSubscription = not me.isPremium()
@isCourseLevel = options.level.get('type', true) in ['course', 'course-ladder']
@isCourseLevel = options.level.isType('course', 'course-ladder')
@helpVideos = if @isCourseLevel then [] else options.level.get('helpVideos') ? []
@trackedHelpVideoStart = @trackedHelpVideoFinish = false
# A/B Testing video tutorial styles

View file

@ -27,7 +27,7 @@ module.exports = class MultiplayerView extends CocoView
@levelID = @level?.get 'slug'
@session = options.session
@listenTo @session, 'change:multiplayer', @updateLinkSection
@watchRealTimeSessions() if @level?.get('type') in ['hero-ladder', 'course-ladder'] and me.isAdmin()
@watchRealTimeSessions() if @level?.isType('hero-ladder', 'course-ladder') and me.isAdmin()
destroy: ->
@realTimeSessions?.off 'add', @onRealTimeSessionAdded
@ -42,12 +42,12 @@ module.exports = class MultiplayerView extends CocoView
c.team = @session.get 'team'
c.levelSlug = @levelID
# For now, ladderGame will disallow multiplayer, because session code combining doesn't play nice yet.
if @level?.get('type') in ['ladder', 'hero-ladder', 'course-ladder']
if @level?.isType('ladder', 'hero-ladder', 'course-ladder')
c.ladderGame = true
c.readyToRank = @session?.readyToRank()
# Real-time multiplayer stuff
if @level?.get('type') in ['hero-ladder', 'course-ladder'] and me.isAdmin()
if @level?.isType('hero-ladder', 'course-ladder') and me.isAdmin()
c.levelID = @session.get('levelID')
c.realTimeSessions = @realTimeSessions
c.currentRealTimeSession = @currentRealTimeSession if @currentRealTimeSession
@ -76,7 +76,7 @@ module.exports = class MultiplayerView extends CocoView
viewArgs = [{supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel}, @levelID]
ladderURL = "/play/ladder/#{@levelID}"
if leagueID = @getQueryVariable 'league'
leagueType = if @level?.get('type') is 'course-ladder' then 'course' else 'clan'
leagueType = if @level?.isType('course-ladder') then 'course' else 'clan'
viewArgs.push leagueType
viewArgs.push leagueID
ladderURL += "/#{leagueType}/#{leagueID}"
@ -86,7 +86,7 @@ module.exports = class MultiplayerView extends CocoView
updateLinkSection: ->
multiplayer = @$el.find('#multiplayer').prop('checked')
la = @$el.find('#link-area')
la.toggle if @level?.get('type') in ['ladder', 'hero-ladder', 'course-ladder'] then false else Boolean(multiplayer)
la.toggle if @level?.isType('ladder', 'hero-ladder', 'course-ladder') then false else Boolean(multiplayer)
true
onHidden: ->

View file

@ -31,6 +31,6 @@ AnalyticsLogEventSchema.statics.logEvent = (user, event, properties={}) ->
unless config.proxy
analyticsMongoose = mongoose.createConnection()
analyticsMongoose.open "mongodb://#{config.mongo.analytics_host}:#{config.mongo.analytics_port}/#{config.mongo.analytics_db}", (error) ->
log.error "Couldnt connect to analytics", error if error
log.error "Couldn't connect to analytics", error if error
module.exports = AnalyticsLogEvent = analyticsMongoose.model('analytics.log.event', AnalyticsLogEventSchema, config.mongo.analytics_collection)

View file

@ -110,7 +110,7 @@ if config.mongo.level_session_replica_string?
levelSessionMongo = mongoose.createConnection()
levelSessionMongo.open config.mongo.level_session_replica_string, (error) ->
if error
log.error "Couldnt connect to session mongo!", error
log.error "Couldn't connect to session mongo!", error
else
log.info "Connected to seperate level session server with string", config.mongo.level_session_replica_string
else
@ -122,7 +122,7 @@ if config.mongo.level_session_aux_replica_string?
auxLevelSessionMongo = mongoose.createConnection()
auxLevelSessionMongo.open config.mongo.level_session_aux_replica_string, (error) ->
if error
log.error "Couldnt connect to AUX session mongo!", error
log.error "Couldn't connect to AUX session mongo!", error
else
log.info "Connected to seperate level AUX session server with string", config.mongo.level_session_aux_replica_string