mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-04-27 06:23:41 -04:00
Merge branch 'master' of https://github.com/codecombat/codecombat
This commit is contained in:
commit
ad6317434d
17 changed files with 65 additions and 49 deletions
app
lib/surface
locale
templates
views/play
server
|
@ -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: ->
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, этот класс для вас."
|
||||
|
|
|
@ -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: "管理员视图"
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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')))
|
||||
|
|
|
@ -10,4 +10,4 @@ c.extendBasicProperties(ArticleSchema, 'article')
|
|||
c.extendSearchableProperties(ArticleSchema)
|
||||
c.extendVersionedProperties(ArticleSchema, 'article')
|
||||
|
||||
module.exports = ArticleSchema
|
||||
module.exports = ArticleSchema
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue