This commit is contained in:
Scott Erickson 2014-03-08 13:07:12 -08:00
commit ad6317434d
17 changed files with 65 additions and 49 deletions

View file

@ -389,7 +389,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@addMark('bounds').toggle true if @thang?.drawsBounds
@addMark('shadow').toggle true unless @thangType.get('shadow') is 0
mark.update() for name, mark of @marks
#@thang.effectNames = ['berserk', 'confuse', 'control', 'curse', 'fear', 'poison', 'paralyze', 'regen', 'sleep', 'slow', 'speed']
#@thang.effectNames = ['berserk', 'confuse', 'control', 'curse', 'fear', 'poison', 'paralyze', 'regen', 'sleep', 'slow', 'haste']
@updateEffectMarks() if @thang?.effectNames?.length or @previousEffectNames?.length
updateEffectMarks: ->

View file

@ -151,14 +151,14 @@ module.exports = class Mark extends CocoClass
@thangType.fetch()
markThangTypes[name] = @thangType
window.mtt = markThangTypes
onLoadedThangType: ->
@build()
@toggle(@toggleTo) if @toggleTo?
update: (pos=null) ->
return false unless @on and @mark
@mark.alpha = if @hidden then 0 else 1
@mark.visible = not @hidden
@updatePosition pos
@updateRotation()
@updateScale()

View file

@ -302,7 +302,7 @@ module.exports = Surface = class Surface extends CocoClass
world: @world
)
if @lastFrame < @world.totalFrames and @currentFrame >= @world.totalFrames
if @lastFrame < @world.totalFrames and @currentFrame >= @world.totalFrames - 1
@spriteBoss.stop()
@playbackOverScreen.show()
@ended = true

View file

@ -129,6 +129,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
new_password: "Новый пароль"
new_password_verify: "Подтверждение пароля"
email_subscriptions: "Email-подписки"
email_notifications: "Уведомления"
email_announcements: "Оповещения"
email_notifications_description: "Получать периодические уведомления для вашего аккаунта."
email_announcements_description: "Получать email-оповещения о последних новостях CodeCombat."
@ -200,7 +201,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
tome_available_spells: "Доступные заклинания"
hud_continue: "Продолжить (нажмите Shift+Пробел)"
spell_saved: "Заклинание сохранено"
# skip_tutorial: "Skip (esc)"
skip_tutorial: "Пропуск (Esc)"
admin:
av_title: "Админ панель"
@ -298,7 +299,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
practices_title: "Лучшие уважаемые практики"
practices_description: "Это наши обещания тебе, игрок, менее юридическим языком."
privacy_title: "Конфиденциальность"
privacy_description: "Мы не будем продавать какой-либо личной информации. Мы намерены заработать деньги с помощью рекрутинга в конечном счете, но будьте уверены, мы не будем распространять вашу личную информацию заинтересованным компаниям без вашего явного согласия."
privacy_description: "Мы не будем продавать какой-либо личной информации. Мы намерены заработать деньги с помощью рекрутинга в конечном счёте, но будьте уверены, мы не будем распространять вашу личную информацию заинтересованным компаниям без вашего явного согласия."
security_title: "Безопасность"
security_description: "Мы стремимся сохранить вашу личную информацию в безопасности. Как проект с открытым исходным кодом, наш сайт в свободном доступе для всех для пересмотра и совершенствования систем безопасности."
email_title: "Email"
@ -400,7 +401,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
more_about_adventurer: "Узнать больше о том, как стать Искателем приключений"
adventurer_subscribe_desc: "Получать email-ы при появлении новых уровней для тестирования."
scribe_summary_pref: "CodeCombat будет не просто кучей уровней. Он также будет ресурсом знаний в области программирования, к которому игроки могут присоединиться. Таким образом, каждый Ремесленник может ссылаться на подробную статью для назидания игрока: документация сродни тому, что создана "
scribe_summary_sufx: ". Если вам нравится объяснять концепции программирования, этот класс для вас."
scribe_summary_suf: ". Если вам нравится объяснять концепции программирования, этот класс для вас."
scribe_introduction_pref: "CodeCombat будет не просто кучей уровней. Он также включает в себя ресурс для познания, вики концепций программирования, которые уровни могут включать. Таким образом, вместо того, чтобы каждому Ремесленнику необходимо было подробно описывать, что такое оператор сравнения, они могут просто связать их уровень с уже написанной в назидание игрокам статьёй, описывающей их. Что-то по аналогии с "
scribe_introduction_url_mozilla: "Mozilla Developer Network"
scribe_introduction_suf: ". Если ваше представление о веселье это формулирование концепций программирования в форме Markdown, этот класс для вас."

View file

@ -27,11 +27,11 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
admin: "管理"
home: "首页"
contribute: "贡献"
legal: "法律"
legal: "版权声明"
about: "关于"
contact: "联系"
contact: "联系我们"
twitter_follow: "关注"
employers: "雇佣我们"
employers: "招募信息"
versions:
save_version_title: "保存新版本"
@ -200,7 +200,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
tome_available_spells: "可用的法术"
hud_continue: "继续(按 Shift-空格)"
spell_saved: "咒语已保存"
skip_tutorial: "跳过(esc)"
skip_tutorial: "跳过esc"
admin:
av_title: "管理员视图"

View file

@ -31,7 +31,7 @@ block content
h4(data-i18n="contribute.how_to_join") How to Join
p
a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact", data-i18n="contact_us_url")
a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact", data-i18n="contribute.contact_us_url")
| Contact us
span ,
span(data-i18n="contribute.ambassador_join_desc")

View file

@ -38,7 +38,7 @@ block content
h4(data-i18n="contribute.how_to_join") How to Join
p
a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact", data-i18n="contact_us_url")
a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact", data-i18n="contribute.contact_us_url")
| Contact us
span ,
span(data-i18n="contribute.counselor_join_desc")
@ -46,4 +46,4 @@ block content
| be interested in doing. We'll put you in our contact list and be in touch
| when we could use advice (not too often).
div.clearfix
div.clearfix

View file

@ -16,7 +16,7 @@ block content
span
span(data-i18n="classes.scribe_title_description") (Article Editor)
p
span(data-i18n="account_settings.scribe_introduction_pref")
span(data-i18n="contribute.scribe_introduction_pref")
| CodeCombat isn't just going to be a bunch of levels.
| It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into.
| That way rather than each Artisan having to describe in detail what a comparison operator is, they
@ -24,7 +24,7 @@ block content
| Something along the lines of what the
a(href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide", data-i18n="contribute.scribe_introduction_url_mozilla")
| Mozilla Developer Network
span(data-i18n="account_settings.scribe_introduction_suf")
span(data-i18n="contribute.scribe_introduction_suf")
| has built. If your idea of fun is articulating the concepts of programming in Markdown form,
| then this class might be for you.
@ -77,4 +77,4 @@ block content
li mattinsler
div.clearfix
div.clearfix

View file

@ -30,7 +30,7 @@
if me.get('anonymous')
p Sign in or create an account and get your solution on the leaderboard!
else
a#go-to-leaderboard-button.btn.btn-primary(href="/play/ladder/#{levelSlug}/team/#{team}") Go to the leaderboard!
a#go-to-leaderboard-button.btn.btn-primary(href="/play/ladder/#{levelSlug}#my-matches") Go to the leaderboard!
p You can submit your game to be ranked from the leaderboard page.
.modal-footer

View file

@ -14,7 +14,9 @@
div!= body
.modal-footer
if hasNextLevel
if level.get('type') === 'ladder'
a.btn.btn-primary(href="/play/ladder/#{level.get('slug')}#my-matches", data-dismiss="modal", data-i18n="play_level.victory_go_home") Go Home
else if hasNextLevel
button.btn.btn-primary.next-level-button(data-dismiss="modal", data-i18n="play_level.victory_play_next_level") Play Next Level
else
a.btn.btn-primary(href="/", data-dismiss="modal", data-i18n="play_level.victory_go_home") Go Home

View file

@ -55,7 +55,8 @@ module.exports = class LadderTabView extends CocoView
class LeaderboardData
constructor: (@level, @team, @session) ->
_.extend @, Backbone.Events
@topPlayers = new LeaderboardCollection(@level, {order:-1, scoreOffset: HIGHEST_SCORE, team: @team, limit: if @session then 10 else 20})
limit = 200 # if @session then 10 else 20 # We need to figure out paging.
@topPlayers = new LeaderboardCollection(@level, {order:-1, scoreOffset: HIGHEST_SCORE, team: @team, limit: limit})
@topPlayers.fetch()
@topPlayers.comparator = (model) ->
return -model.get('totalScore')

View file

@ -95,7 +95,7 @@ module.exports = class MyMatchesTabView extends CocoView
success = => @setRankingButtonText(button, 'ranked')
failure = => @setRankingButtonText(button, 'failed')
ajaxData = { session: sessionID, levelID: @level.attributes.original, levelMajorVersion: @level.attributes.version.major }
ajaxData = { session: sessionID, levelID: @level.id, originalLevelID: @level.attributes.original, levelMajorVersion: @level.attributes.version.major }
$.ajax '/queue/scoring', {
type: 'POST'
data: ajaxData

View file

@ -11,7 +11,7 @@ module.exports = class LadderPlayModal extends View
closeButton: true
startsLoading: true
@shownTutorialButton: false
events:
'click #skip-tutorial-button': 'hideTutorialButtons'
@ -21,7 +21,7 @@ module.exports = class LadderPlayModal extends View
@otherTeam = if team is 'ogres' then 'humans' else 'ogres'
@startLoadingChallengersMaybe()
@wizardType = ThangType.loadUniversalWizard()
# PART 1: Load challengers from the db unless some are in the matches
startLoadingChallengersMaybe: ->
@ -49,12 +49,12 @@ module.exports = class LadderPlayModal extends View
type: 'POST'
success: success
})
# PART 3: Make sure wizard is loaded
checkWizardLoaded: ->
if @wizardType.loaded then @finishRendering() else @wizardType.once 'sync', @finishRendering, @
# PART 4: Render
finishRendering: ->
@ -69,7 +69,7 @@ module.exports = class LadderPlayModal extends View
ctx.teamName = _.string.titleize @team
ctx.teamID = @team
ctx.otherTeamID = @otherTeam
teamsList = teamDataFromLevel @level
teams = {}
teams[team.id] = team for team in teamsList
@ -104,7 +104,7 @@ module.exports = class LadderPlayModal extends View
@$el.find('#normal-view').removeClass('secret')
@$el.find('.modal-header').removeClass('secret')
@$el.find('#noob-view').addClass('secret')
# Choosing challengers
getChallengers: ->
@ -165,7 +165,7 @@ class ChallengersData
@hardPlayer = new LeaderboardCollection(@level, {order:-1, scoreOffset: score + 5, limit: 1, team: @otherTeam})
@hardPlayer.fetch()
@hardPlayer.once 'sync', @challengerLoaded, @
challengerLoaded: ->
if @allLoaded()
@loaded = true

View file

@ -66,12 +66,15 @@ module.exports = class LadderView extends RootView
@insertSubView(@ladderTab = new LadderTabView({}, @level, @sessions))
@insertSubView(@myMatchesTab = new MyMatchesTabView({}, @level, @sessions))
@refreshInterval = setInterval(@fetchSessionsAndRefreshViews.bind(@), 10000)
@showPlayModal(document.location.hash[1..]) if document.location.hash and @sessions.loaded
hash = document.location.hash[1..] if document.location.hash
unless hash in ['my-matches', 'simulate', 'ladder']
@showPlayModal(hash) if @sessions.loaded
fetchSessionsAndRefreshViews: ->
@sessions.fetch({"success": @refreshViews})
refreshViews: =>
return if @destroyed
@ladderTab.refreshLadder()
@myMatchesTab.refreshMatches()
console.log "refreshed views!"
@ -114,12 +117,12 @@ module.exports = class LadderView extends RootView
onClickPlayButton: (e) ->
@showPlayModal($(e.target).closest('.play-button').data('team'))
showPlayModal: (teamID) ->
session = (s for s in @sessions.models when s.get('team') is teamID)[0]
modal = new LadderPlayModal({}, @level, session, teamID)
@openModalView modal
destroy: ->
clearInterval @refreshInterval
@simulator.destroy()

View file

@ -64,6 +64,7 @@ module.exports = class VictoryModal extends View
c.me = me
c.hasNextLevel = _.isObject(@level.get('nextLevel')) and (@level.get('name') isnt "Mobile Artillery")
c.levelName = @level.get('i18n')?[me.lang()]?.name ? @level.get('name')
c.level = @level
if me.get 'hourOfCode'
# Show the Hour of Code "I'm Done" tracking pixel after they played for 30 minutes
elapsed = (new Date() - new Date(me.get('dateCreated')))

View file

@ -10,4 +10,4 @@ c.extendBasicProperties(ArticleSchema, 'article')
c.extendSearchableProperties(ArticleSchema)
c.extendVersionedProperties(ArticleSchema, 'article')
module.exports = ArticleSchema
module.exports = ArticleSchema

View file

@ -8,6 +8,7 @@ db = require './../routes/db'
mongoose = require 'mongoose'
queues = require '../commons/queue'
LevelSession = require '../levels/sessions/LevelSession'
Level = require '../levels/Level'
TaskLog = require './task/ScoringTask'
bayes = new (require 'bayesian-battle')()
@ -48,7 +49,8 @@ addPairwiseTaskToQueue = (taskPair, cb) ->
module.exports.createNewTask = (req, res) ->
requestSessionID = req.body.session
requestLevelID = req.body.levelID
requestLevelID = req.body.originalLevelID
requestCurrentLevelID = req.body.levelID
requestLevelMajorVersion = parseInt(req.body.levelMajorVersion)
validatePermissions req, requestSessionID, (error, permissionsAreValid) ->
@ -56,21 +58,27 @@ module.exports.createNewTask = (req, res) ->
unless permissionsAreValid then return errors.forbidden res, "You do not have the permissions to submit that game to the leaderboard"
return errors.badInput res, "The session ID is invalid" unless typeof requestSessionID is "string"
fetchSessionToSubmit requestSessionID, (err, sessionToSubmit) ->
if err? then return errors.serverError res, "There was an error finding the given session."
updateSessionToSubmit sessionToSubmit, (err, data) ->
if err? then return errors.serverError res, "There was an error updating the session"
opposingTeam = calculateOpposingTeam(sessionToSubmit.team)
fetchInitialSessionsToRankAgainst opposingTeam,requestLevelID, requestLevelMajorVersion, (err, sessionsToRankAgainst) ->
if err? then return errors.serverError res, "There was an error fetching the sessions to rank against"
taskPairs = generateTaskPairs(sessionsToRankAgainst, sessionToSubmit)
sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
if taskPairError? then return errors.serverError res, "There was an error sending the task pairs to the queue"
sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"}
Level.findOne({_id: requestCurrentLevelID}).lean().select('type').exec (err, levelWithType) ->
if err? then return errors.serverError res, "There was an error finding the level type"
if not levelWithType.type or levelWithType.type isnt "ladder"
console.log "The level type of level with ID #{requestLevelID} is #{levelWithType.type}"
return errors.badInput res, "That level isn't a ladder level"
fetchSessionToSubmit requestSessionID, (err, sessionToSubmit) ->
if err? then return errors.serverError res, "There was an error finding the given session."
updateSessionToSubmit sessionToSubmit, (err, data) ->
if err? then return errors.serverError res, "There was an error updating the session"
opposingTeam = calculateOpposingTeam(sessionToSubmit.team)
fetchInitialSessionsToRankAgainst opposingTeam,requestLevelID, requestLevelMajorVersion, (err, sessionsToRankAgainst) ->
if err? then return errors.serverError res, "There was an error fetching the sessions to rank against"
taskPairs = generateTaskPairs(sessionsToRankAgainst, sessionToSubmit)
sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
if taskPairError? then return errors.serverError res, "There was an error sending the task pairs to the queue"
sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"}
module.exports.dispatchTaskToConsumer = (req, res) ->
if isUserAnonymous(req) then return errors.forbidden res, "You need to be logged in to simulate games"