From c0a70cb2aba4b94e0b8a3358d223eef96002db35 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 14 Jul 2016 08:58:43 -0700 Subject: [PATCH] Refactor level type checks for easy greppability (level.isType) --- app/lib/LevelLoader.coffee | 12 +++---- app/lib/LevelSetupManager.coffee | 2 +- app/models/Level.coffee | 11 +++--- app/views/clans/ClanDetailsView.coffee | 2 +- app/views/courses/CourseDetailsView.coffee | 8 ++--- .../component/ThangComponentConfigView.coffee | 2 +- .../level/thangs/LevelThangEditView.coffee | 2 +- .../editor/level/thangs/ThangsTabView.coffee | 20 +++++------ app/views/editor/verifier/VerifierView.coffee | 2 +- app/views/ladder/SimulateTabView.coffee | 2 +- app/views/play/CampaignView.coffee | 4 +-- app/views/play/SpectateView.coffee | 2 +- app/views/play/level/ControlBarView.coffee | 18 +++++----- app/views/play/level/LevelGoalsView.coffee | 2 +- app/views/play/level/LevelHUDView.coffee | 2 +- app/views/play/level/LevelLoadingView.coffee | 2 +- app/views/play/level/PlayLevelView.coffee | 31 ++++++++-------- .../play/level/modal/HeroVictoryModal.coffee | 36 +++++++++---------- .../play/level/modal/VictoryModal.coffee | 2 +- app/views/play/level/tome/DocFormatter.coffee | 2 +- app/views/play/level/tome/Spell.coffee | 10 +++--- .../level/tome/SpellListTabEntryView.coffee | 1 - .../level/tome/SpellPaletteEntryView.coffee | 2 +- .../play/level/tome/SpellPaletteView.coffee | 4 +-- app/views/play/level/tome/SpellView.coffee | 8 ++--- app/views/play/level/tome/TomeView.coffee | 2 +- .../play/level/tome/editor/zatanna.coffee | 14 ++++---- app/views/play/menu/GameMenuModal.coffee | 4 +-- app/views/play/menu/GuideView.coffee | 2 +- app/views/play/menu/MultiplayerView.coffee | 10 +++--- server/models/AnalyticsLogEvent.coffee | 4 +-- server/models/LevelSession.coffee | 4 +-- 32 files changed, 114 insertions(+), 115 deletions(-) diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index 02b0b0753..d2a4c7bb1 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -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 diff --git a/app/lib/LevelSetupManager.coffee b/app/lib/LevelSetupManager.coffee index 78d0c7205..f9d00a823 100644 --- a/app/lib/LevelSetupManager.coffee +++ b/app/lib/LevelSetupManager.coffee @@ -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}) diff --git a/app/models/Level.coffee b/app/models/Level.coffee index acad5b8a6..268b1700f 100644 --- a/app/models/Level.coffee +++ b/app/models/Level.coffee @@ -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" diff --git a/app/views/clans/ClanDetailsView.coffee b/app/views/clans/ClanDetailsView.coffee index 8e8d7bc12..c9bcdb1e3 100644 --- a/app/views/clans/ClanDetailsView.coffee +++ b/app/views/clans/ClanDetailsView.coffee @@ -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?() diff --git a/app/views/courses/CourseDetailsView.coffee b/app/views/courses/CourseDetailsView.coffee index 0c03ab445..84b128df6 100644 --- a/app/views/courses/CourseDetailsView.coffee +++ b/app/views/courses/CourseDetailsView.coffee @@ -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 diff --git a/app/views/editor/component/ThangComponentConfigView.coffee b/app/views/editor/component/ThangComponentConfigView.coffee index dc5498b41..08b20ebf9 100644 --- a/app/views/editor/component/ThangComponentConfigView.coffee +++ b/app/views/editor/component/ThangComponentConfigView.coffee @@ -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 diff --git a/app/views/editor/level/thangs/LevelThangEditView.coffee b/app/views/editor/level/thangs/LevelThangEditView.coffee index 84429d644..5dc7bc3f0 100644 --- a/app/views/editor/level/thangs/LevelThangEditView.coffee +++ b/app/views/editor/level/thangs/LevelThangEditView.coffee @@ -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 diff --git a/app/views/editor/level/thangs/ThangsTabView.coffee b/app/views/editor/level/thangs/ThangsTabView.coffee index 1e794a40d..c2a631f47 100644 --- a/app/views/editor/level/thangs/ThangsTabView.coffee +++ b/app/views/editor/level/thangs/ThangsTabView.coffee @@ -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') ? [] diff --git a/app/views/editor/verifier/VerifierView.coffee b/app/views/editor/verifier/VerifierView.coffee index 32c8e22e2..41a9500a6 100644 --- a/app/views/editor/verifier/VerifierView.coffee +++ b/app/views/editor/verifier/VerifierView.coffee @@ -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: -> diff --git a/app/views/ladder/SimulateTabView.coffee b/app/views/ladder/SimulateTabView.coffee index 2be7ed186..4fac4239d 100644 --- a/app/views/ladder/SimulateTabView.coffee +++ b/app/views/ladder/SimulateTabView.coffee @@ -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: -> diff --git a/app/views/play/CampaignView.coffee b/app/views/play/CampaignView.coffee index 931a5244c..641f19e1e 100644 --- a/app/views/play/CampaignView.coffee +++ b/app/views/play/CampaignView.coffee @@ -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 diff --git a/app/views/play/SpectateView.coffee b/app/views/play/SpectateView.coffee index 272b69d5b..b9122bd59 100644 --- a/app/views/play/SpectateView.coffee +++ b/app/views/play/SpectateView.coffee @@ -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 diff --git a/app/views/play/level/ControlBarView.coffee b/app/views/play/level/ControlBarView.coffee index 8254e9b18..6e07caa8a 100644 --- a/app/views/play/level/ControlBarView.coffee +++ b/app/views/play/level/ControlBarView.coffee @@ -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() diff --git a/app/views/play/level/LevelGoalsView.coffee b/app/views/play/level/LevelGoalsView.coffee index 1c37e1245..d4749ae88 100644 --- a/app/views/play/level/LevelGoalsView.coffee +++ b/app/views/play/level/LevelGoalsView.coffee @@ -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' diff --git a/app/views/play/level/LevelHUDView.coffee b/app/views/play/level/LevelHUDView.coffee index 661da3aaf..b2cad7500 100644 --- a/app/views/play/level/LevelHUDView.coffee +++ b/app/views/play/level/LevelHUDView.coffee @@ -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' diff --git a/app/views/play/level/LevelLoadingView.coffee b/app/views/play/level/LevelLoadingView.coffee index eb9024d14..c0b3b82f3 100644 --- a/app/views/play/level/LevelLoadingView.coffee +++ b/app/views/play/level/LevelLoadingView.coffee @@ -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 $('
  • ' + name + '
  • ') ++goalCount diff --git a/app/views/play/level/PlayLevelView.coffee b/app/views/play/level/PlayLevelView.coffee index 45340f0d7..d2148fb2d 100644 --- a/app/views/play/level/PlayLevelView.coffee +++ b/app/views/play/level/PlayLevelView.coffee @@ -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) diff --git a/app/views/play/level/modal/HeroVictoryModal.coffee b/app/views/play/level/modal/HeroVictoryModal.coffee index 1f7a46672..66eed4f9b 100644 --- a/app/views/play/level/modal/HeroVictoryModal.coffee +++ b/app/views/play/level/modal/HeroVictoryModal.coffee @@ -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 diff --git a/app/views/play/level/modal/VictoryModal.coffee b/app/views/play/level/modal/VictoryModal.coffee index fcc8bdb9b..360ff0937 100644 --- a/app/views/play/level/modal/VictoryModal.coffee +++ b/app/views/play/level/modal/VictoryModal.coffee @@ -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 diff --git a/app/views/play/level/tome/DocFormatter.coffee b/app/views/play/level/tome/DocFormatter.coffee index 93cdd1d6f..ec4e14cbd 100644 --- a/app/views/play/level/tome/DocFormatter.coffee +++ b/app/views/play/level/tome/DocFormatter.coffee @@ -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: -> diff --git a/app/views/play/level/tome/Spell.coffee b/app/views/play/level/tome/Spell.coffee index 71b68fb3d..f34f99fe1 100644 --- a/app/views/play/level/tome/Spell.coffee +++ b/app/views/play/level/tome/Spell.coffee @@ -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 diff --git a/app/views/play/level/tome/SpellListTabEntryView.coffee b/app/views/play/level/tome/SpellListTabEntryView.coffee index b15798bbb..aabe6683a 100644 --- a/app/views/play/level/tome/SpellListTabEntryView.coffee +++ b/app/views/play/level/tome/SpellListTabEntryView.coffee @@ -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: -> diff --git a/app/views/play/level/tome/SpellPaletteEntryView.coffee b/app/views/play/level/tome/SpellPaletteEntryView.coffee index cbada6610..7e7b883c9 100644 --- a/app/views/play/level/tome/SpellPaletteEntryView.coffee +++ b/app/views/play/level/tome/SpellPaletteEntryView.coffee @@ -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') diff --git a/app/views/play/level/tome/SpellPaletteView.coffee b/app/views/play/level/tome/SpellPaletteView.coffee index 87f7b21f4..42954a37d 100644 --- a/app/views/play/level/tome/SpellPaletteView.coffee +++ b/app/views/play/level/tome/SpellPaletteView.coffee @@ -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 diff --git a/app/views/play/level/tome/SpellView.coffee b/app/views/play/level/tome/SpellView.coffee index c3e2b7e14..834757ac2 100644 --- a/app/views/play/level/tome/SpellView.coffee +++ b/app/views/play/level/tome/SpellView.coffee @@ -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 diff --git a/app/views/play/level/tome/TomeView.coffee b/app/views/play/level/tome/TomeView.coffee index 442b8cf4b..14c3057c0 100644 --- a/app/views/play/level/tome/TomeView.coffee +++ b/app/views/play/level/tome/TomeView.coffee @@ -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) diff --git a/app/views/play/level/tome/editor/zatanna.coffee b/app/views/play/level/tome/editor/zatanna.coffee index 81d2ef5d6..57907b17e 100644 --- a/app/views/play/level/tome/editor/zatanna.coffee +++ b/app/views/play/level/tome/editor/zatanna.coffee @@ -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:' diff --git a/app/views/play/menu/GameMenuModal.coffee b/app/views/play/menu/GameMenuModal.coffee index a62a47cc2..efe19ec2f 100644 --- a/app/views/play/menu/GameMenuModal.coffee +++ b/app/views/play/menu/GameMenuModal.coffee @@ -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 diff --git a/app/views/play/menu/GuideView.coffee b/app/views/play/menu/GuideView.coffee index d456ad687..fcd794117 100644 --- a/app/views/play/menu/GuideView.coffee +++ b/app/views/play/menu/GuideView.coffee @@ -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 diff --git a/app/views/play/menu/MultiplayerView.coffee b/app/views/play/menu/MultiplayerView.coffee index 13b28f149..4925744ce 100644 --- a/app/views/play/menu/MultiplayerView.coffee +++ b/app/views/play/menu/MultiplayerView.coffee @@ -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: -> diff --git a/server/models/AnalyticsLogEvent.coffee b/server/models/AnalyticsLogEvent.coffee index e824ad776..e00234607 100644 --- a/server/models/AnalyticsLogEvent.coffee +++ b/server/models/AnalyticsLogEvent.coffee @@ -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) diff --git a/server/models/LevelSession.coffee b/server/models/LevelSession.coffee index bc3076fdc..f61c9f4f8 100644 --- a/server/models/LevelSession.coffee +++ b/server/models/LevelSession.coffee @@ -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