mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-23 23:58:02 -05:00
Start to rework CampaignView when we're in picoCTF mode
This commit is contained in:
parent
0aa3418e44
commit
fe351be32e
7 changed files with 64 additions and 20 deletions
|
@ -76,6 +76,7 @@
|
|||
<script>
|
||||
|
||||
// Placeholder for iPad, which inspects the user object at the bottom of an injected page.
|
||||
window.serverConfig = "serverConfigTag";
|
||||
window.userObject = "userObjectTag";
|
||||
window.me = {
|
||||
get: function(attribute) { return window.userObject[attribute]; }
|
||||
|
|
|
@ -14,6 +14,8 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
|
||||
routes:
|
||||
'': ->
|
||||
if window.serverConfig.picoCTF
|
||||
return @routeDirectly 'play/CampaignView', ['picoctf'], {}
|
||||
# Testing new home page
|
||||
group = me.getHomepageGroup()
|
||||
return @routeDirectly('HomeView', [], { withTeacherNote: true }) if group is 'home-with-note'
|
||||
|
@ -147,6 +149,7 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
@navigate e, {trigger: true}
|
||||
|
||||
routeDirectly: (path, args, options={}) ->
|
||||
path = 'play/CampaignView' if window.serverConfig.picoCTF and not /^(views\/)?play/.test(path)
|
||||
path = "views/#{path}" if not _.string.startsWith(path, 'views/')
|
||||
ViewClass = @tryToLoadModule path
|
||||
if not ViewClass and application.moduleLoader.load(path)
|
||||
|
|
|
@ -49,6 +49,7 @@ Application = initialize: ->
|
|||
@isProduction = -> document.location.href.search('https?://localhost:3000') is -1
|
||||
@isIPadApp = webkit?.messageHandlers? and navigator.userAgent?.indexOf('CodeCombat-iPad') isnt -1
|
||||
$('body').addClass 'ipad' if @isIPadApp
|
||||
$('body').addClass 'picoctf' if window.serverConfig.picoCTF
|
||||
if $.browser.msie and parseInt($.browser.version) is 10
|
||||
$("html").addClass("ie10")
|
||||
@tracker = new Tracker()
|
||||
|
|
|
@ -414,4 +414,10 @@ body > iframe[src^="https://apis.google.com"]
|
|||
border: 2px solid #350f0d
|
||||
background: #e6251c
|
||||
color: white
|
||||
padding: 0.0em 0.6em 0.1em
|
||||
padding: 0.0em 0.6em 0.1em
|
||||
|
||||
body.picoctf .picoctf-hide
|
||||
display: none
|
||||
|
||||
body:not(.picoctf) .picoctf-show
|
||||
display: none
|
||||
|
|
|
@ -611,13 +611,23 @@ $gameControlMargin: 30px
|
|||
margin: 15px 0
|
||||
min-width: 100px
|
||||
|
||||
#small-nav-logo
|
||||
.small-nav-logo, .picoctf-powered-by
|
||||
position: absolute
|
||||
top: 1%
|
||||
left: 1%
|
||||
height: 60px
|
||||
z-index: 1
|
||||
|
||||
.picoctf-logo .small-nav-logo
|
||||
height: 30px
|
||||
|
||||
.picoctf-powered-by
|
||||
color: rgb(227, 173, 53)
|
||||
top: calc(1% + 30px)
|
||||
|
||||
img
|
||||
height: 30px
|
||||
|
||||
body.ipad #campaign-view
|
||||
// iPad only supports up to Kithgard Gates for now.
|
||||
.campaign-switch
|
||||
|
@ -625,3 +635,4 @@ body.ipad #campaign-view
|
|||
|
||||
body[lang='ru'] .portals h2
|
||||
font-size: 26px
|
||||
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
a(href="/")
|
||||
img#small-nav-logo(src="/images/pages/base/logo.png", title="CodeCombat - Learn how to code by playing a game", alt="CodeCombat")
|
||||
a(href="/").picoctf-hide
|
||||
img.small-nav-logo(src="/images/pages/base/logo.png", title="CodeCombat - Learn how to code by playing a game", alt="CodeCombat")
|
||||
|
||||
.picoctf-show
|
||||
a(href="http://staging.picoctf.com").picoctf-logo
|
||||
img.small-nav-logo(src="http://picoctf.com/img/2014_logo_blue2.svg", title="picoCTF home", alt="picoCTF home")
|
||||
a(href="http://codecombat.com").picoctf-powered-by
|
||||
em.spr powered by
|
||||
img(src="/images/pages/base/logo.png", title="Powered by CodeCombat - Learn how to code by playing a game ", alt="Powered by CodeCombat")
|
||||
|
||||
if campaign
|
||||
.map
|
||||
|
@ -36,7 +43,7 @@ if campaign
|
|||
.level-status
|
||||
h3= i18n(level, 'name') + (level.disabled ? " (Coming soon!)" : (level.locked ? " (Locked)" : ""))
|
||||
- var description = i18n(level, 'description') || level.description || ""
|
||||
.level-description!= marked(description)
|
||||
.level-description!= marked(description, {sanitize: !picoCTF})
|
||||
if level.disabled
|
||||
p
|
||||
span.spr(data-i18n="play.awaiting_levels_adventurer_prefix") We release five levels per week.
|
||||
|
@ -99,7 +106,7 @@ else
|
|||
p.campaign-description
|
||||
span= i18n(campaign.attributes, 'description')
|
||||
|
||||
.game-controls.header-font
|
||||
.game-controls.header-font.picoctf-hide
|
||||
button.btn.poll.hidden(data-i18n="[title]play.poll")
|
||||
a.btn.clans(href="/clans", data-i18n="[title]clans.clans")
|
||||
button.btn.items(data-toggle='coco-modal', data-target='play/modal/PlayItemsModal', data-i18n="[title]play.items")
|
||||
|
@ -114,7 +121,7 @@ else
|
|||
if me.get('anonymous', true)
|
||||
button.btn.settings(data-toggle='coco-modal', data-target='core/AuthModal', data-i18n="[title]play.settings")
|
||||
|
||||
.user-status.header-font
|
||||
.user-status.header-font.picoctf-hide
|
||||
.user-status-line
|
||||
span.gem.gem-30
|
||||
span#gems-count.spr= me.gems()
|
||||
|
@ -137,7 +144,7 @@ button.btn.btn-lg.btn-inverse.campaign-control-button#volume-button(data-i18n="[
|
|||
.glyphicon.glyphicon-volume-up
|
||||
|
||||
if campaign && !editorMode
|
||||
button.btn.btn-lg.btn-inverse.campaign-control-button#back-button(data-i18n="[title]resources.campaigns", title="Campaigns")
|
||||
button.btn.btn-lg.btn-inverse.campaign-control-button.picoctf-hide#back-button(data-i18n="[title]resources.campaigns", title="Campaigns")
|
||||
.glyphicon.glyphicon-globe
|
||||
|
||||
if editorMode
|
||||
|
|
|
@ -63,18 +63,22 @@ module.exports = class CampaignView extends RootView
|
|||
|
||||
constructor: (options, @terrain) ->
|
||||
super options
|
||||
@terrain = 'picoctf' if window.serverConfig.picoCTF
|
||||
@editorMode = options?.editorMode
|
||||
if @editorMode
|
||||
@terrain ?= 'dungeon'
|
||||
@levelStatusMap = {}
|
||||
@levelPlayCountMap = {}
|
||||
@levelDifficultyMap = {}
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', {cache: false}, 0).model
|
||||
@listenToOnce @sessions, 'sync', @onSessionsLoaded
|
||||
unless @terrain
|
||||
@campaigns = @supermodel.loadCollection(new CampaignsCollection(), 'campaigns', null, 1).model
|
||||
@listenToOnce @campaigns, 'sync', @onCampaignsLoaded
|
||||
return
|
||||
if window.serverConfig.picoCTF
|
||||
@supermodel.addRequestResource(url: '/picoctf/problems', success: @onPicoCTFProblemsLoaded).load()
|
||||
else
|
||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', {cache: false}, 0).model
|
||||
@listenToOnce @sessions, 'sync', @onSessionsLoaded
|
||||
unless @terrain
|
||||
@campaigns = @supermodel.loadCollection(new CampaignsCollection(), 'campaigns', null, 1).model
|
||||
@listenToOnce @campaigns, 'sync', @onCampaignsLoaded
|
||||
return
|
||||
|
||||
@campaign = new Campaign({_id:@terrain})
|
||||
@campaign.saveBackups = @editorMode
|
||||
|
@ -187,6 +191,7 @@ module.exports = class CampaignView extends RootView
|
|||
context.levelDifficultyMap = @levelDifficultyMap
|
||||
context.levelPlayCountMap = @levelPlayCountMap
|
||||
context.isIPadApp = application.isIPadApp
|
||||
context.picoCTF = window.serverConfig.picoCTF
|
||||
context.requiresSubscription = @requiresSubscription
|
||||
context.editorMode = @editorMode
|
||||
context.adjacentCampaigns = _.filter _.values(_.cloneDeep(@campaign?.get('adjacentCampaigns') or {})), (ac) =>
|
||||
|
@ -267,10 +272,18 @@ module.exports = class CampaignView extends RootView
|
|||
level.locked = true if level.slug is 'kithgard-mastery' and @calculateExperienceScore() is 0
|
||||
level.locked = false if @levelStatusMap[level.slug] in ['started', 'complete']
|
||||
level.locked = false if @editorMode
|
||||
level.locked = false if @campaign?.get('name') is 'Auditions'
|
||||
level.locked = false if @campaign?.get('name') is 'Intro'
|
||||
level.locked = false if @campaign?.get('name') in ['Auditions', 'Intro']
|
||||
level.locked = false if me.isInGodMode()
|
||||
#level.locked = false if level.slug is 'robot-ragnarok'
|
||||
if window.serverConfig.picoCTF
|
||||
if problem = _.find(@picoCTFProblems or [], pid: level.picoCTFProblem)
|
||||
level.locked = false if problem.unlocked
|
||||
level.description = """
|
||||
### #{problem.name}
|
||||
#{problem.description}
|
||||
|
||||
#{problem.category} - #{problem.score} points
|
||||
""" # Skipping #{problem.hints}
|
||||
level.disabled = true if level.adminOnly and @levelStatusMap[level.slug] not in ['started', 'complete']
|
||||
level.disabled = false if me.isInGodMode()
|
||||
level.color = 'rgb(255, 80, 60)'
|
||||
|
@ -338,7 +351,7 @@ module.exports = class CampaignView extends RootView
|
|||
adultPoint = me.get('ageRange') in ['18-24', '25-34', '35-44', '45-100'] # They have to have answered the poll for this, likely after Shadow Guard.
|
||||
speedPoints = 0
|
||||
for [levelSlug, speedThreshold] in [['dungeons-of-kithgard', 50], ['gems-in-the-deep', 55], ['shadow-guard', 55], ['forgetful-gemsmith', 40], ['true-names', 40]]
|
||||
if _.find(@sessions.models, (session) -> session.get('levelID') is levelSlug)?.attributes.playtime <= speedThreshold
|
||||
if _.find(@sessions?.models, (session) -> session.get('levelID') is levelSlug)?.attributes.playtime <= speedThreshold
|
||||
++speedPoints
|
||||
experienceScore = adultPoint + speedPoints # 0-6 score of how likely we think they are to be experienced and ready for Kithgard Mastery
|
||||
return experienceScore
|
||||
|
@ -421,11 +434,13 @@ module.exports = class CampaignView extends RootView
|
|||
@levelStatusMap[session.get('levelID')] = if session.get('state')?.complete then 'complete' else 'started'
|
||||
@levelDifficultyMap[session.get('levelID')] = session.get('state').difficulty if session.get('state')?.difficulty
|
||||
@render()
|
||||
@loadUserPollsRecord() unless me.get 'anonymous'
|
||||
@loadUserPollsRecord() unless me.get('anonymous') or window.serverConfig.picoCTF
|
||||
|
||||
onCampaignsLoaded: (e) ->
|
||||
@render()
|
||||
|
||||
onPicoCTFProblemsLoaded: (@picoCTFProblems) =>
|
||||
|
||||
preloadLevel: (levelSlug) ->
|
||||
levelURL = "/db/level/#{levelSlug}"
|
||||
level = new Level().setURL levelURL
|
||||
|
@ -447,7 +462,7 @@ module.exports = class CampaignView extends RootView
|
|||
|
||||
onClickMap: (e) ->
|
||||
@$levelInfo?.hide()
|
||||
if @sessions.models.length < 3
|
||||
if @sessions?.models.length < 3
|
||||
# Restore the next level higlight for very new players who might otherwise get lost.
|
||||
@highlightElement '.level.next', delay: 500, duration: 60000, rotation: 0, sides: ['top']
|
||||
|
||||
|
@ -482,7 +497,7 @@ module.exports = class CampaignView extends RootView
|
|||
canPlayAnyway = not @requiresSubscription or level.adventurer or @levelStatusMap[level.slug]
|
||||
if requiresSubscription and not canPlayAnyway
|
||||
@openModalView new SubscribeModal()
|
||||
# TODO: Added levelID on 2/9/16. Remove level property and associated AnalyticsLogEvent 'properties.level' index later.
|
||||
# TODO: Added levelID on 2/9/16. Remove level property and associated AnalyticsLogEvent 'properties.level' index later.
|
||||
window.tracker?.trackEvent 'Show subscription modal', category: 'Subscription', label: 'map level clicked', level: levelSlug, levelID: levelSlug
|
||||
else
|
||||
@startLevel levelElement
|
||||
|
|
Loading…
Reference in a new issue