mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 15:48:11 -05:00
Refactor level type checks for easy greppability (level.isType)
This commit is contained in:
parent
87ed53b24b
commit
c0a70cb2ab
32 changed files with 114 additions and 115 deletions
|
@ -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
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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?()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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') ? []
|
||||
|
|
|
@ -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: ->
|
||||
|
|
|
@ -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: ->
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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: ->
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: ->
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:'
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: ->
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue