mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-02 11:58:10 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
83df107cdf
24 changed files with 244 additions and 248 deletions
|
@ -188,10 +188,17 @@ self.retrieveValueFromFrame = function retrieveValueFromFrame(args) {
|
|||
{
|
||||
try
|
||||
{
|
||||
var flowStates = self.debugWorld.userCodeMap[currentThangID][currentSpellID].flow.states;
|
||||
//we have to go to the second last flowState as we run the world for one additional frame
|
||||
//to collect the flow
|
||||
value = _.last(flowStates[flowStates.length - 1].statements).variables[prop];
|
||||
if (Aether.globals[prop])
|
||||
{
|
||||
value = Aether.globals[prop];
|
||||
}
|
||||
else
|
||||
{
|
||||
var flowStates = self.debugWorld.userCodeMap[currentThangID][currentSpellID].flow.states;
|
||||
//we have to go to the second last flowState as we run the world for one additional frame
|
||||
//to collect the flow
|
||||
value = _.last(flowStates[flowStates.length - 1].statements).variables[prop];
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
|
|
|
@ -69,7 +69,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@marks = {}
|
||||
@labels = {}
|
||||
@ranges = []
|
||||
@handledAoEs = {}
|
||||
@handledDisplayEvents = {}
|
||||
@age = 0
|
||||
@scaleFactor = @targetScaleFactor = 1
|
||||
if @thangType.isFullyLoaded()
|
||||
|
@ -213,6 +213,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@updatePosition()
|
||||
frameChanged = frameChanged or @targetScaleFactor isnt @scaleFactor
|
||||
if frameChanged
|
||||
@handledDisplayEvents = {}
|
||||
@updateScale() # must happen before rotation
|
||||
@updateAlpha()
|
||||
@updateRotation()
|
||||
|
@ -220,6 +221,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@updateStats()
|
||||
@updateGold()
|
||||
@showAreaOfEffects()
|
||||
@showTextEvents()
|
||||
@updateHealthBar()
|
||||
@updateMarks()
|
||||
@updateLabels()
|
||||
|
@ -228,9 +230,9 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
return unless @thang?.currentEvents
|
||||
for event in @thang.currentEvents
|
||||
continue unless event.startsWith 'aoe-'
|
||||
continue if @handledAoEs[event]
|
||||
continue if @handledDisplayEvents[event]
|
||||
|
||||
@handledAoEs[event] = true
|
||||
@handledDisplayEvents[event] = true
|
||||
args = JSON.parse(event[4...])
|
||||
pos = @options.camera.worldToSurface {x:args[0], y:args[1]}
|
||||
circle = new createjs.Shape()
|
||||
|
@ -248,7 +250,31 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
.call =>
|
||||
return if @destroyed
|
||||
@options.groundLayer.removeChild circle
|
||||
delete @handledAoEs[event]
|
||||
delete @handledDisplayEvents[event]
|
||||
|
||||
showTextEvents: ->
|
||||
return unless @thang?.currentEvents
|
||||
for event in @thang.currentEvents
|
||||
continue unless event.startsWith 'text-'
|
||||
continue if @handledDisplayEvents[event]
|
||||
@handledDisplayEvents[event] = true
|
||||
options = JSON.parse(event[5...])
|
||||
label = new createjs.Text options.text, "bold #{options.size or 16}px Arial", options.color or '#FFF'
|
||||
label.shadow = new createjs.Shadow '#000', 0, 0, 2
|
||||
offset = @getOffset 'aboveHead'
|
||||
[label.x, label.y] = [@imageObject.x + offset.x - label.getMeasuredWidth() / 2, @imageObject.y + offset.y]
|
||||
@options.floatingLayer.addChild label
|
||||
window.labels ?= []
|
||||
window.labels.push label
|
||||
label.alpha = 0
|
||||
createjs.Tween.get(label)
|
||||
.to({y:label.y-2, alpha:1}, 200, createjs.Ease.linear)
|
||||
.to({y:label.y-12}, 1000, createjs.Ease.linear)
|
||||
.to({y:label.y-22, alpha:0}, 1000, createjs.Ease.linear)
|
||||
.call =>
|
||||
return if @destroyed
|
||||
@options.floatingLayer.removeChild label
|
||||
|
||||
|
||||
cache: ->
|
||||
bounds = @imageObject.getBounds()
|
||||
|
@ -472,7 +498,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
Backbone.Mediator.publish ourEventName, newEvent
|
||||
|
||||
addHealthBar: ->
|
||||
return unless @thang?.health? and "health" in (@thang?.hudProperties ? [])
|
||||
return unless @thang?.health? and "health" in (@thang?.hudProperties ? []) and @options.floatingLayer
|
||||
healthColor = healthColors[@thang?.team] ? healthColors["neutral"]
|
||||
healthOffset = @getOffset 'aboveHead'
|
||||
bar = @healthBar = createProgressBar(healthColor, healthOffset)
|
||||
|
|
|
@ -20,7 +20,7 @@ module.exports = class Mark extends CocoClass
|
|||
@build()
|
||||
|
||||
destroy: ->
|
||||
createjs.Tween.removeTweens @mark
|
||||
createjs.Tween.removeTweens @mark if @mark
|
||||
@mark?.parent?.removeChild @mark
|
||||
@markSprite?.destroy()
|
||||
@sprite = null
|
||||
|
|
|
@ -591,12 +591,14 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@mouseInBounds = mib
|
||||
|
||||
restoreWorldState: ->
|
||||
@world.getFrame(@getCurrentFrame()).restoreState()
|
||||
frame = @world.getFrame(@getCurrentFrame())
|
||||
frame.restoreState()
|
||||
current = Math.max(0, Math.min(@currentFrame, @world.totalFrames - 1))
|
||||
if current - Math.floor(current) > 0.01
|
||||
next = Math.ceil current
|
||||
ratio = current % 1
|
||||
@world.frames[next].restorePartialState ratio if next > 1
|
||||
frame.clearEvents() if parseInt(@currentFrame) is parseInt(@lastFrame)
|
||||
@spriteBoss.updateSounds()
|
||||
|
||||
updateState: (frameChanged) ->
|
||||
|
|
|
@ -36,6 +36,8 @@ module.exports = class WorldFrame
|
|||
#console.log "Frame", @time, "restoring state for", thang.id, "in particular and saying it don't exist"
|
||||
return
|
||||
thangState.restore()
|
||||
|
||||
clearEvents: -> thang.currentEvents = [] for thang in @world.thangs
|
||||
|
||||
toString: ->
|
||||
map = ((' ' for x in [0 .. @world.width]) \
|
||||
|
|
|
@ -233,8 +233,6 @@
|
|||
victory_sign_up: "Sign Up to Save Progress"
|
||||
victory_sign_up_poke: "Want to save your code? Create a free account!"
|
||||
victory_rate_the_level: "Rate the level: "
|
||||
victory_rank_my_game: "Rank My Game"
|
||||
victory_ranking_game: "Submitting..."
|
||||
victory_return_to_ladder: "Return to Ladder"
|
||||
victory_play_next_level: "Play Next Level"
|
||||
victory_go_home: "Go Home"
|
||||
|
|
|
@ -36,11 +36,11 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
|
||||
nav:
|
||||
play: "Jugar"
|
||||
# community: "Community"
|
||||
community: "Comunidad"
|
||||
editor: "Editor"
|
||||
blog: "Blog"
|
||||
forum: "Foro"
|
||||
# account: "Account"
|
||||
account: "Cuenta"
|
||||
admin: "Admin"
|
||||
home: "Inicio"
|
||||
contribute: "Colaborar"
|
||||
|
@ -152,7 +152,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
autosave: "Los cambios se guardan automáticamente"
|
||||
me_tab: "Yo"
|
||||
picture_tab: "Foto"
|
||||
# upload_picture: "Upload a picture"
|
||||
upload_picture: "Sube una imagen"
|
||||
wizard_tab: "Mago"
|
||||
password_tab: "Contraseña"
|
||||
emails_tab: "Correos electrónicos"
|
||||
|
@ -168,7 +168,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
# email_any_notes: "Any Notifications"
|
||||
# email_any_notes_description: "Disable to stop all activity notification emails."
|
||||
# email_recruit_notes: "Job Opportunities"
|
||||
# email_recruit_notes_description: "If you play really well, we may contact you about getting you a (better) job."
|
||||
email_recruit_notes_description: "Si tu juegas realmente bien, puede que contactemos contigo para que consigas un trabajo (mejor)."
|
||||
contributor_emails: "Correos para colaboradores"
|
||||
contribute_prefix: "¡Buscamos gente que se una a nuestro comunidad! Comprueba la "
|
||||
contribute_page: "página de colaboraciones"
|
||||
|
@ -180,8 +180,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
job_profile: "Perfil de trabajo"
|
||||
job_profile_approved: "Tu perfil de trabajo ha sido aprobado por CodeCombat. Los empleadores podrán verlo hasta que lo marques como inactivo o no haya sido cambiado durante cuatro semanas."
|
||||
job_profile_explanation: "¡Hola! Rellena esto y estaremos en contacto para hablar sobre encontrarte un trabajo como desarrollador de software."
|
||||
# sample_profile: "See a sample profile"
|
||||
# view_profile: "View Your Profile"
|
||||
sample_profile: "Mira un perfil de ejemplo"
|
||||
view_profile: "Mira tu perfil"
|
||||
|
||||
account_profile:
|
||||
edit_settings: "Ajustes"
|
||||
|
@ -199,7 +199,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
|
||||
employers:
|
||||
want_to_hire_our_players: "¿Quieres contratar jugadores expertos de CodeCombat?"
|
||||
# see_candidates: "Click here to see our candidates"
|
||||
see_candidates: "Click aquí para ver a nuestros candidatos"
|
||||
candidates_count_prefix: "Actualmente tenemos "
|
||||
candidates_count_many: "muchos"
|
||||
candidates_count_suffix: "desarrolladores altamente cualificados, y examinados atentamente, buscando trabajo."
|
||||
|
@ -210,8 +210,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
candidate_top_skills: "Mejores Habilidades"
|
||||
candidate_years_experience: "Años Exp"
|
||||
candidate_last_updated: "Última actualización"
|
||||
# candidate_approved: "Us?"
|
||||
# candidate_active: "Them?"
|
||||
candidate_approved: "¿Nosotros?"
|
||||
candidate_active: "¿Ellos?"
|
||||
|
||||
play_level:
|
||||
level_load_error: "No se pudo cargar el nivel: "
|
||||
|
@ -246,7 +246,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
multiplayer_hint_label: "Pista:"
|
||||
multiplayer_hint: " Haz un click en el link para que se seleccione, después utiliza Ctrl-C o ⌘-C para copiar el link."
|
||||
multiplayer_coming_soon: "¡Más opciones de Multijugador están por venir!"
|
||||
# multiplayer_sign_in_leaderboard: "Sign in or create an account and get your solution on the leaderboard."
|
||||
multiplayer_sign_in_leaderboard: "Logueate o crea una cuentra para guardar tus resultados en la tabla de clasificación."
|
||||
guide_title: "Guía"
|
||||
tome_minion_spells: "Los hechizos de tus súbditos"
|
||||
tome_read_only_spells: "Hechizos de solo lectura"
|
||||
|
@ -321,9 +321,9 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
lg_title: "Últimos Juegos"
|
||||
clas: "CLAs"
|
||||
|
||||
# community:
|
||||
# level_editor: "Level Editor"
|
||||
# main_title: "CodeCombat Community"
|
||||
community:
|
||||
level_editor: "Editor de niveles"
|
||||
main_title: "Comunidad de CodeCombat"
|
||||
# facebook: "Facebook"
|
||||
# twitter: "Twitter"
|
||||
# gplus: "Google+"
|
||||
|
@ -337,7 +337,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
thang_description: "Construye unidades, su lógica predeterminada, gráficos y audio. Actualmente sólo se permite importar gráficos vectoriales exportados de Flash."
|
||||
level_title: "Editor de Niveles"
|
||||
level_description: "Incluye las herramientas para escribir scripts, subir audio, y construir una lógica personalidad con la que crear todo tipo de niveles. ¡Todo lo que usamos nosotros!"
|
||||
# got_questions: "Questions about using the CodeCombat editors?"
|
||||
got_questions: "¿Preguntas sobre el uso de los editores CodeCombat?"
|
||||
contact_us: "¡Contacta con nosotros!"
|
||||
hipchat_prefix: "También puedes encontrarnos en nuestra"
|
||||
hipchat_url: "sala de HipChat."
|
||||
|
@ -379,9 +379,9 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
new_article_title: "Crear un nuevo artículo"
|
||||
new_thang_title: "Crea un nuevo tipo de objeto"
|
||||
new_level_title: "Crear un nuevo nivel"
|
||||
# new_article_title_signup: "Sign Up to Create a New Article"
|
||||
new_article_title_signup: "Registrarte para crear un nuevo artículo"
|
||||
# new_thang_title_signup: "Sign Up to Create a New Thang Type"
|
||||
# new_level_title_signup: "Sign Up to Create a New Level"
|
||||
new_level_title_signup: "Registrarte para crear un nuevo nivel"
|
||||
article_search_title: "Buscar artículos aquí"
|
||||
thang_search_title: "Busca tipos de objetos aquí"
|
||||
level_search_title: "Buscar niveles aquí"
|
||||
|
@ -651,11 +651,11 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
simple_ai: "IA sencilla"
|
||||
warmup: "calentamiento"
|
||||
vs: "VS"
|
||||
# friends_playing: "Friends Playing"
|
||||
# sign_up_for_friends: "Sign up to play with your friends!"
|
||||
# social_connect_blurb: "Connect and play against your friends!"
|
||||
# invite_friends_to_battle: "Invite your friends to join you in battle!"
|
||||
# fight: "Fight!"
|
||||
friends_playing: "Amigos jugando"
|
||||
sign_up_for_friends: "¡Registrate para jugar con tus amigos!"
|
||||
social_connect_blurb: "¡Conectate y juega contra tus amigos!"
|
||||
invite_friends_to_battle: "¡Invita a tus amigos a unirse a la batalla!"
|
||||
fight: "¡Pelea!"
|
||||
# watch_victory: "Watch your victory"
|
||||
# defeat_the: "Defeat the"
|
||||
|
||||
|
@ -700,15 +700,15 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
user_profile: "Perfil de usuario"
|
||||
patches: "Parches"
|
||||
model: "Modelo"
|
||||
# system: "System"
|
||||
# component: "Component"
|
||||
# components: "Components"
|
||||
system: "Sistema"
|
||||
component: "Componente"
|
||||
components: "Componentes"
|
||||
# thang: "Thang"
|
||||
# thangs: "Thangs"
|
||||
# level_session: "Your Session"
|
||||
# opponent_session: "Opponent Session"
|
||||
# article: "Article"
|
||||
# user_names: "User Names"
|
||||
# files: "Files"
|
||||
# top_simulators: "Top Simulators"
|
||||
# source_document: "Source Document"
|
||||
level_session: "Tu sesión"
|
||||
opponent_session: "Sesión del oponente"
|
||||
article: "Artículo"
|
||||
user_names: "Nombres de usuarios"
|
||||
files: "Archivos"
|
||||
top_simulators: "Top simuladores"
|
||||
source_document: "Documento fuente"
|
||||
|
|
3
app/styles/play/common/ladder_submission.sass
Normal file
3
app/styles/play/common/ladder_submission.sass
Normal file
|
@ -0,0 +1,3 @@
|
|||
.ladder-submission-view
|
||||
h3
|
||||
text-decoration: underline
|
7
app/templates/play/common/ladder_submission.jade
Normal file
7
app/templates/play/common/ladder_submission.jade
Normal file
|
@ -0,0 +1,7 @@
|
|||
button.btn.btn-success.rank-button
|
||||
span(data-i18n="ladder.rank_no_code").unavailable.hidden No New Code to Rank
|
||||
span(data-i18n="ladder.rank_my_game").rank.hidden Rank My Game!
|
||||
span(data-i18n="ladder.rank_submitting").submitting.hidden Submitting...
|
||||
span(data-i18n="ladder.rank_submitted").submitted.hidden Submitted for Ranking
|
||||
span(data-i18n="ladder.rank_failed").failed.hidden Failed to Rank
|
||||
span(data-i18n="ladder.rank_being_ranked").ranking.hidden Game Being Ranked
|
|
@ -31,6 +31,11 @@ block content
|
|||
a(href="#my-matches", data-toggle="tab", data-i18n="ladder.my_matches") My Matches
|
||||
li
|
||||
a(href="#simulate", data-toggle="tab", data-i18n="ladder.simulate") Simulate
|
||||
if level.get('name') == 'Greed'
|
||||
li
|
||||
a(href="#prizes", data-toggle="tab", data-i18n="ladder.prizes") Prizes
|
||||
li
|
||||
a(href="#rules", data-toggle="tab", data-i18n="ladder.rules") Rules
|
||||
|
||||
div.tab-content
|
||||
.tab-pane.active.well#ladder
|
||||
|
@ -39,3 +44,9 @@ block content
|
|||
#my-matches-tab-view
|
||||
.tab-pane.well#simulate
|
||||
#simulate-tab-view
|
||||
.tab-pane.well#prizes
|
||||
h1(data-i18n="ladder.prizes_remember_to_add_i18n_tags") Tournament Prizes
|
||||
p(data-i18n="ladder.prizes_but_this_is_just_placeholder") Fill in the Greed prizes list here.
|
||||
.tab-pane.well#rules
|
||||
h1(data-i18n="ladder.rules_remember_to_add_i18n_tags") Tournament Rules
|
||||
p(data-i18n="ladder.rules_but_this_is_just_placeholder") We probably don't have to translate legal documents from English, but we should translate any conversational summary.
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
//if matches.length
|
||||
// p#your-score
|
||||
// span Your Current Score:
|
||||
// span
|
||||
// strong= score
|
||||
|
||||
div#columns.row
|
||||
for team in teams
|
||||
div.matches-column.col-md-6
|
||||
|
@ -23,21 +17,13 @@ div#columns.row
|
|||
if team.session
|
||||
tr
|
||||
th(colspan=4)
|
||||
button.btn.btn-warning.btn-block.rank-button(data-session-id=team.session.id)
|
||||
span(data-i18n="ladder.rank_no_code").unavailable.hidden No New Code to Rank
|
||||
span(data-i18n="ladder.rank_my_game").rank.hidden Rank My Game!
|
||||
span(data-i18n="ladder.rank_submitting").submitting.hidden Submitting...
|
||||
span(data-i18n="ladder.rank_submitted").submitted.hidden Submitted for Ranking
|
||||
span(data-i18n="ladder.rank_failed").failed.hidden Failed to Rank
|
||||
span(data-i18n="ladder.rank_being_ranked").ranking.hidden Game Being Ranked
|
||||
.ladder-submission-view(data-session-id=team.session.id)
|
||||
|
||||
if team.chartData
|
||||
if team.scoreHistory
|
||||
tr
|
||||
th(colspan=4, style="color: #{team.primaryColor}")
|
||||
div(class="score-chart-wrapper", data-team-name=team.name, id="score-chart-#{team.name}")
|
||||
|
||||
|
||||
|
||||
tr
|
||||
th(data-i18n="general.result") Result
|
||||
th(data-i18n="general.opponent") Opponent
|
||||
|
|
|
@ -29,7 +29,7 @@ block modal-body-content
|
|||
if me.get('anonymous')
|
||||
p(data-i18n="play_level.multiplayer_sign_in_leaderboard") Sign in or create an account and get your solution on the leaderboard.
|
||||
else if readyToRank
|
||||
button.btn.btn-success.rank-game-button(data-i18n="play_level.victory_rank_my_game") Rank My Game
|
||||
.ladder-submission-view
|
||||
else
|
||||
a.btn.btn-primary(href="/play/ladder/#{levelSlug}#my-matches", data-i18n="play_level.victory_go_ladder") Return to Ladder
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ block modal-body-content
|
|||
|
||||
block modal-footer-content
|
||||
if readyToRank
|
||||
button.btn.btn-success.rank-game-button(data-i18n="play_level.victory_rank_my_game") Rank My Game
|
||||
.ladder-submission-view
|
||||
else 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_ladder") Return to Ladder
|
||||
else if hasNextLevel
|
||||
|
|
|
@ -221,8 +221,8 @@ module.exports = class ThangTypeEditView extends View
|
|||
@showMovieClip(animationName)
|
||||
else
|
||||
@showSprite(animationName)
|
||||
@updateScale()
|
||||
@updateRotation()
|
||||
@updateScale() # must happen after update rotation, because updateRotation calls the sprite update() method.
|
||||
|
||||
showMovieClip: (animationName) ->
|
||||
vectorParser = new SpriteBuilder(@thangType)
|
||||
|
@ -279,11 +279,12 @@ module.exports = class ThangTypeEditView extends View
|
|||
@currentSprite.update(true)
|
||||
|
||||
updateScale: =>
|
||||
value = (@scaleSlider.slider('value') + 1) / 10
|
||||
fixed = value.toFixed(1)
|
||||
@scale = value
|
||||
resValue = (@resolutionSlider.slider('value') + 1) / 10
|
||||
scaleValue = (@scaleSlider.slider('value') + 1) / 10
|
||||
fixed = scaleValue.toFixed(1)
|
||||
@scale = scaleValue
|
||||
@$el.find('.scale-label').text " #{fixed}x "
|
||||
@currentObject.scaleX = @currentObject.scaleY = value if @currentObject?
|
||||
@currentObject.scaleX = @currentObject.scaleY = scaleValue / resValue if @currentObject?
|
||||
@updateGrid()
|
||||
@updateDots()
|
||||
|
||||
|
|
88
app/views/play/common/ladder_submission_view.coffee
Normal file
88
app/views/play/common/ladder_submission_view.coffee
Normal file
|
@ -0,0 +1,88 @@
|
|||
CocoView = require 'views/kinds/CocoView'
|
||||
template = require 'templates/play/common/ladder_submission'
|
||||
|
||||
module.exports = class LadderSubmissionView extends CocoView
|
||||
class: "ladder-submission-view"
|
||||
template: template
|
||||
|
||||
events:
|
||||
'click .rank-button': 'rankSession'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@session = options.session
|
||||
@level = options.level
|
||||
|
||||
getRenderData: ->
|
||||
ctx = super()
|
||||
ctx.readyToRank = @session?.readyToRank()
|
||||
ctx.isRanking = @ession?.get('isRanking')
|
||||
ctx
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
return unless @supermodel.finished()
|
||||
@rankButton = @$el.find('.rank-button')
|
||||
@updateButton()
|
||||
|
||||
updateButton: ->
|
||||
rankingState = 'unavailable'
|
||||
if @session?.readyToRank()
|
||||
rankingState = 'rank'
|
||||
else if @session?.get 'isRanking'
|
||||
rankingState = 'ranking'
|
||||
@setRankingButtonText rankingState
|
||||
|
||||
setRankingButtonText: (spanClass) ->
|
||||
@rankButton.find('span').addClass('hidden')
|
||||
@rankButton.find(".#{spanClass}").removeClass('hidden')
|
||||
@rankButton.toggleClass 'disabled', spanClass isnt 'rank'
|
||||
|
||||
rankSession: (e) ->
|
||||
return unless @session.readyToRank()
|
||||
@setRankingButtonText 'submitting'
|
||||
success = =>
|
||||
@setRankingButtonText 'submitted' unless @destroyed
|
||||
Backbone.Mediator.publish 'ladder:game-submitted', session: @session, level: @level
|
||||
failure = (jqxhr, textStatus, errorThrown) =>
|
||||
console.log jqxhr.responseText
|
||||
@setRankingButtonText 'failed' unless @destroyed
|
||||
transpiledCode = @transpileSession()
|
||||
|
||||
ajaxData =
|
||||
session: @session.id
|
||||
levelID: @level.id
|
||||
originalLevelID: @level.get('original')
|
||||
levelMajorVersion: @level.get('version').major
|
||||
transpiledCode: transpiledCode
|
||||
|
||||
$.ajax '/queue/scoring', {
|
||||
type: 'POST'
|
||||
data: ajaxData
|
||||
success: success
|
||||
error: failure
|
||||
}
|
||||
|
||||
transpileSession: ->
|
||||
submittedCode = @session.get('code')
|
||||
transpiledCode = {}
|
||||
for thang, spells of submittedCode
|
||||
transpiledCode[thang] = {}
|
||||
for spellID, spell of spells
|
||||
unless _.contains(@session.get('teamSpells')[@session.get('team')], thang + "/" + spellID) then continue
|
||||
#DRY this
|
||||
aetherOptions =
|
||||
problems: {}
|
||||
language: "javascript"
|
||||
functionName: spellID
|
||||
functionParameters: []
|
||||
yieldConditionally: spellID is "plan"
|
||||
globals: ['Vector', '_']
|
||||
protectAPI: true
|
||||
includeFlow: false
|
||||
if spellID is "hear" then aetherOptions["functionParameters"] = ["speaker","message","data"]
|
||||
|
||||
aether = new Aether aetherOptions
|
||||
transpiledCode[thang][spellID] = aether.transpile spell
|
||||
transpiledCode
|
||||
|
|
@ -2,6 +2,7 @@ CocoView = require 'views/kinds/CocoView'
|
|||
Level = require 'models/Level'
|
||||
LevelSession = require 'models/LevelSession'
|
||||
LeaderboardCollection = require 'collections/LeaderboardCollection'
|
||||
LadderSubmissionView = require 'views/play/common/ladder_submission_view'
|
||||
{teamDataFromLevel} = require './utils'
|
||||
|
||||
module.exports = class MyMatchesTabView extends CocoView
|
||||
|
@ -9,9 +10,6 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
template: require 'templates/play/ladder/my_matches_tab'
|
||||
startsLoading: true
|
||||
|
||||
events:
|
||||
'click .rank-button': 'rankSession'
|
||||
|
||||
constructor: (options, @level, @sessions) ->
|
||||
super(options)
|
||||
@nameMap = {}
|
||||
|
@ -49,8 +47,6 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
@startsLoading = false
|
||||
@render()
|
||||
|
||||
|
||||
|
||||
getRenderData: ->
|
||||
ctx = super()
|
||||
ctx.level = @level
|
||||
|
@ -84,36 +80,18 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
scoreHistory = team.session?.get('scoreHistory')
|
||||
if scoreHistory?.length > 1
|
||||
team.scoreHistory = scoreHistory
|
||||
scoreHistory = _.last scoreHistory, 100 # Chart URL needs to be under 2048 characters for GET
|
||||
|
||||
team.currentScore = Math.round scoreHistory[scoreHistory.length - 1][1] * 100
|
||||
team.chartColor = team.primaryColor.replace '#', ''
|
||||
#times = (s[0] for s in scoreHistory)
|
||||
#times = ((100 * (t - times[0]) / (times[times.length - 1] - times[0])).toFixed(1) for t in times)
|
||||
# Let's try being independent of time.
|
||||
times = (i for s, i in scoreHistory)
|
||||
scores = (s[1] for s in scoreHistory)
|
||||
lowest = _.min scores #.concat([0])
|
||||
highest = _.max scores #.concat(50)
|
||||
scores = (Math.round(100 * (s - lowest) / (highest - lowest)) for s in scores)
|
||||
team.chartData = times.join(',') + '|' + scores.join(',')
|
||||
team.minScore = Math.round(100 * lowest)
|
||||
team.maxScore = Math.round(100 * highest)
|
||||
|
||||
ctx
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
@$el.find('.rank-button').each (i, el) =>
|
||||
button = $(el)
|
||||
sessionID = button.data('session-id')
|
||||
@$el.find('.ladder-submission-view').each (i, el) =>
|
||||
placeholder = $(el)
|
||||
sessionID = placeholder.data('session-id')
|
||||
session = _.find @sessions.models, {id: sessionID}
|
||||
rankingState = 'unavailable'
|
||||
if session.readyToRank()
|
||||
rankingState = 'rank'
|
||||
else if session.get 'isRanking'
|
||||
rankingState = 'ranking'
|
||||
@setRankingButtonText button, rankingState
|
||||
ladderSubmissionView = new LadderSubmissionView session: session, level: @level
|
||||
@insertSubView ladderSubmissionView, placeholder
|
||||
ladderSubmissionView.$el.find('.rank-button').addClass 'btn-block'
|
||||
|
||||
@$el.find('.score-chart-wrapper').each (i, el) =>
|
||||
scoreWrapper = $(el)
|
||||
|
@ -170,59 +148,3 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
.datum(data)
|
||||
.attr("class",lineClass)
|
||||
.attr("d",line)
|
||||
|
||||
rankSession: (e) ->
|
||||
button = $(e.target).closest('.rank-button')
|
||||
sessionID = button.data('session-id')
|
||||
session = _.find @sessions.models, {id: sessionID}
|
||||
return unless session.readyToRank()
|
||||
|
||||
@setRankingButtonText(button, 'submitting')
|
||||
success = =>
|
||||
@setRankingButtonText(button, 'submitted') unless @destroyed
|
||||
failure = (jqxhr, textStatus, errorThrown) =>
|
||||
console.log jqxhr.responseText
|
||||
@setRankingButtonText(button, 'failed') unless @destroyed
|
||||
transpiledCode = @transpileSession session
|
||||
|
||||
ajaxData =
|
||||
session: sessionID
|
||||
levelID: @level.id
|
||||
originalLevelID: @level.attributes.original
|
||||
levelMajorVersion: @level.attributes.version.major
|
||||
transpiledCode: transpiledCode
|
||||
|
||||
$.ajax '/queue/scoring', {
|
||||
type: 'POST'
|
||||
data: ajaxData
|
||||
success: success
|
||||
error: failure
|
||||
}
|
||||
|
||||
transpileSession: (session) ->
|
||||
submittedCode = session.get('code')
|
||||
transpiledCode = {}
|
||||
for thang, spells of submittedCode
|
||||
transpiledCode[thang] = {}
|
||||
for spellID, spell of spells
|
||||
unless _.contains(session.get('teamSpells')[session.get('team')], thang + "/" + spellID) then continue
|
||||
#DRY this
|
||||
aetherOptions =
|
||||
problems: {}
|
||||
language: "javascript"
|
||||
functionName: spellID
|
||||
functionParameters: []
|
||||
yieldConditionally: spellID is "plan"
|
||||
globals: ['Vector', '_']
|
||||
protectAPI: true
|
||||
includeFlow: false
|
||||
if spellID is "hear" then aetherOptions["functionParameters"] = ["speaker","message","data"]
|
||||
|
||||
aether = new Aether aetherOptions
|
||||
transpiledCode[thang][spellID] = aether.transpile spell
|
||||
transpiledCode
|
||||
|
||||
setRankingButtonText: (rankButton, spanClass) ->
|
||||
rankButton.find('span').addClass('hidden')
|
||||
rankButton.find(".#{spanClass}").removeClass('hidden')
|
||||
rankButton.toggleClass 'disabled', spanClass isnt 'rank'
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
View = require 'views/kinds/ModalView'
|
||||
template = require 'templates/play/level/modal/multiplayer'
|
||||
{me} = require('lib/auth')
|
||||
{me} = require 'lib/auth'
|
||||
LadderSubmissionView = require 'views/play/common/ladder_submission_view'
|
||||
|
||||
module.exports = class MultiplayerModal extends View
|
||||
id: 'level-multiplayer-modal'
|
||||
template: template
|
||||
|
||||
subscriptions:
|
||||
'ladder:game-submitted': 'onGameSubmitted'
|
||||
|
||||
events:
|
||||
'click textarea': 'onClickLink'
|
||||
'change #multiplayer': 'updateLinkSection'
|
||||
'click .rank-game-button': 'onRankGame'
|
||||
|
||||
constructor: (options) ->
|
||||
super(options)
|
||||
|
@ -36,10 +39,16 @@ module.exports = class MultiplayerModal extends View
|
|||
afterRender: ->
|
||||
super()
|
||||
@updateLinkSection()
|
||||
@ladderSubmissionView = new LadderSubmissionView session: @session, level: @level
|
||||
@insertSubView @ladderSubmissionView, @$el.find('.ladder-submission-view')
|
||||
|
||||
onClickLink: (e) ->
|
||||
e.target.select()
|
||||
|
||||
onGameSubmitted: (e) ->
|
||||
ladderURL = "/play/ladder/#{@level.get('slug')}#my-matches"
|
||||
Backbone.Mediator.publish 'router:navigate', route: ladderURL
|
||||
|
||||
updateLinkSection: ->
|
||||
multiplayer = @$el.find('#multiplayer').prop('checked')
|
||||
la = @$el.find('#link-area')
|
||||
|
@ -50,48 +59,5 @@ module.exports = class MultiplayerModal extends View
|
|||
multiplayer = Boolean(@$el.find('#multiplayer').prop('checked'))
|
||||
@session.set('multiplayer', multiplayer)
|
||||
|
||||
onRankGame: (e) ->
|
||||
button = @$el.find('.rank-game-button')
|
||||
button.text($.i18n.t('play_level.victory_ranking_game', defaultValue: 'Submitting...'))
|
||||
button.prop 'disabled', true
|
||||
ajaxData =
|
||||
session: @session.id
|
||||
levelID: @level.id
|
||||
originalLevelID: @level.get('original')
|
||||
levelMajorVersion: @level.get('version').major
|
||||
transpiledCode: @transpileSession(@session)
|
||||
ladderURL = "/play/ladder/#{@level.get('slug')}#my-matches"
|
||||
goToLadder = -> Backbone.Mediator.publish 'router:navigate', route: ladderURL
|
||||
$.ajax '/queue/scoring',
|
||||
type: 'POST'
|
||||
data: ajaxData
|
||||
success: goToLadder
|
||||
failure: (response) ->
|
||||
console.error "Couldn't submit game for ranking:", response
|
||||
goToLadder()
|
||||
|
||||
transpileSession: (session) ->
|
||||
submittedCode = session.get('code')
|
||||
transpiledCode = {}
|
||||
for thang, spells of submittedCode
|
||||
transpiledCode[thang] = {}
|
||||
for spellID, spell of spells
|
||||
unless _.contains(session.get('teamSpells')[session.get('team')], thang + "/" + spellID) then continue
|
||||
#DRY this
|
||||
aetherOptions =
|
||||
problems: {}
|
||||
language: "javascript"
|
||||
functionName: spellID
|
||||
functionParameters: []
|
||||
yieldConditionally: spellID is "plan"
|
||||
globals: ['Vector', '_']
|
||||
protectAPI: true
|
||||
includeFlow: false
|
||||
if spellID is "hear" then aetherOptions["functionParameters"] = ["speaker","message","data"]
|
||||
|
||||
aether = new Aether aetherOptions
|
||||
transpiledCode[thang][spellID] = aether.transpile spell
|
||||
transpiledCode
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
View = require 'views/kinds/ModalView'
|
||||
template = require 'templates/play/level/modal/victory'
|
||||
{me} = require 'lib/auth'
|
||||
LadderSubmissionView = require 'views/play/common/ladder_submission_view'
|
||||
LevelFeedback = require 'models/LevelFeedback'
|
||||
utils = require 'lib/utils'
|
||||
|
||||
|
@ -8,9 +9,11 @@ module.exports = class VictoryModal extends View
|
|||
id: 'level-victory-modal'
|
||||
template: template
|
||||
|
||||
subscriptions:
|
||||
'ladder:game-submitted': 'onGameSubmitted'
|
||||
|
||||
events:
|
||||
'click .next-level-button': 'onPlayNextLevel'
|
||||
'click .rank-game-button': 'onRankGame'
|
||||
|
||||
# review events
|
||||
'mouseover .rating i': (e) -> @showStars(@starNum($(e.target)))
|
||||
|
@ -58,48 +61,9 @@ module.exports = class VictoryModal extends View
|
|||
@saveReview() if @$el.find('.review textarea').val()
|
||||
Backbone.Mediator.publish('play-next-level')
|
||||
|
||||
onRankGame: (e) ->
|
||||
button = @$el.find('.rank-game-button')
|
||||
button.text($.i18n.t('play_level.victory_ranking_game', defaultValue: 'Submitting...'))
|
||||
button.prop 'disabled', true
|
||||
ajaxData =
|
||||
session: @session.id
|
||||
levelID: @level.id
|
||||
originalLevelID: @level.get('original')
|
||||
levelMajorVersion: @level.get('version').major
|
||||
transpiledCode: @transpileSession @session
|
||||
onGameSubmitted: (e) ->
|
||||
ladderURL = "/play/ladder/#{@level.get('slug')}#my-matches"
|
||||
goToLadder = -> Backbone.Mediator.publish 'router:navigate', route: ladderURL
|
||||
$.ajax '/queue/scoring',
|
||||
type: 'POST'
|
||||
data: ajaxData
|
||||
success: goToLadder
|
||||
failure: (response) ->
|
||||
console.error "Couldn't submit game for ranking:", response
|
||||
goToLadder()
|
||||
|
||||
transpileSession: (session) ->
|
||||
submittedCode = session.get('code')
|
||||
transpiledCode = {}
|
||||
for thang, spells of submittedCode
|
||||
transpiledCode[thang] = {}
|
||||
for spellID, spell of spells
|
||||
#DRY this
|
||||
unless _.contains(session.get('teamSpells')[session.get('team')], thang + "/" + spellID) then continue
|
||||
aetherOptions =
|
||||
problems: {}
|
||||
language: "javascript"
|
||||
functionName: spellID
|
||||
functionParameters: []
|
||||
yieldConditionally: spellID is "plan"
|
||||
globals: ['Vector', '_']
|
||||
protectAPI: true
|
||||
includeFlow: false
|
||||
if spellID is "hear" then aetherOptions["functionParameters"] = ["speaker","message","data"]
|
||||
|
||||
aether = new Aether aetherOptions
|
||||
transpiledCode[thang][spellID] = aether.transpile spell
|
||||
transpiledCode
|
||||
Backbone.Mediator.publish 'router:navigate', route: ladderURL
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
|
@ -126,6 +90,8 @@ module.exports = class VictoryModal extends View
|
|||
|
||||
afterRender: ->
|
||||
super()
|
||||
@ladderSubmissionView = new LadderSubmissionView session: @session, level: @level
|
||||
@insertSubView @ladderSubmissionView, @$el.find('.ladder-submission-view')
|
||||
|
||||
afterInsert: ->
|
||||
super()
|
||||
|
|
|
@ -79,7 +79,7 @@ module.exports = class CastButtonView extends View
|
|||
async.some _.values(@spells), (spell, callback) =>
|
||||
spell.hasChangedSignificantly spell.getSource(), null, callback
|
||||
, (castable) =>
|
||||
|
||||
Backbone.Mediator.publish 'tome:spell-has-changed-significantly-calculation', hasChangedSignificantly: castable
|
||||
@castButtonGroup.toggleClass('castable', castable).toggleClass('casting', @casting)
|
||||
if @casting
|
||||
s = $.i18n.t("play_level.tome_cast_button_casting", defaultValue: "Casting")
|
||||
|
|
|
@ -17,6 +17,7 @@ module.exports = class DebugView extends View
|
|||
'tome:spell-shown': 'changeCurrentThangAndSpell'
|
||||
'tome:cast-spells': 'onTomeCast'
|
||||
'surface:frame-changed': 'onFrameChanged'
|
||||
'tome:spell-has-changed-significantly-calculation': 'onSpellChangedCalculation'
|
||||
|
||||
events: {}
|
||||
|
||||
|
@ -34,6 +35,8 @@ module.exports = class DebugView extends View
|
|||
@cache = {}
|
||||
@lastFrameRequested = -1
|
||||
@workerIsSimulating = false
|
||||
@spellHasChanged = false
|
||||
|
||||
|
||||
|
||||
pad2: (num) ->
|
||||
|
@ -145,11 +148,17 @@ module.exports = class DebugView extends View
|
|||
onFrameChanged: (data) ->
|
||||
@currentFrame = data.frame
|
||||
@frameRate = data.world.frameRate
|
||||
|
||||
onSpellChangedCalculation: (data) ->
|
||||
@spellHasChanged = data.hasChangedSignificantly
|
||||
|
||||
update: ->
|
||||
if @variableChain
|
||||
if @variableChain.length is 2 and @variableChain[0] is "this"
|
||||
if @spellHasChanged
|
||||
@setTooltipText("You've changed this spell! \nPlease recast to use the hover debugger.")
|
||||
else if @variableChain.length is 2 and @variableChain[0] is "this"
|
||||
@setTooltipKeyAndValue(@variableChain.join("."),@stringifyValue(@thang[@variableChain[1]],0))
|
||||
else if @variableChain.length is 1 and Aether.globals[@variableChain[0]]
|
||||
@setTooltipKeyAndValue(@variableChain.join("."),@stringifyValue(Aether.globals[@variableChain[0]],0))
|
||||
else if @workerIsSimulating
|
||||
@setTooltipText("World is simulating, please wait...")
|
||||
else if @currentFrame is @lastFrameRequested and (cacheValue = @retrieveValueFromCache(@thang.id, @spell.name, @variableChain, @currentFrame))
|
||||
|
|
|
@ -360,7 +360,7 @@ module.exports = class SpellView extends View
|
|||
displayAether: (aether) ->
|
||||
@displayedAether = aether
|
||||
isCast = not _.isEmpty(aether.metrics) or _.some aether.problems.errors, {type: 'runtime'}
|
||||
isCast = isCast or @language isnt 'javascript' # Since we don't have linting for other languages
|
||||
isCast = isCast or @spell.language isnt 'javascript' # Since we don't have linting for other languages
|
||||
problem.destroy() for problem in @problems # Just in case another problem was added since clearAetherDisplay() ran.
|
||||
@problems = []
|
||||
annotations = []
|
||||
|
|
|
@ -35,7 +35,7 @@ path = __dirname
|
|||
|
||||
m = require 'module'
|
||||
request = require 'request'
|
||||
|
||||
Deferred = require "JQDeferred"
|
||||
originalLoader = m._load
|
||||
|
||||
unhook = () ->
|
||||
|
@ -90,6 +90,7 @@ GLOBAL.$ = GLOBAL.jQuery = (input) ->
|
|||
append: (input)-> exports: ()->
|
||||
|
||||
cookies = request.jar()
|
||||
$.when = Deferred.when
|
||||
|
||||
$.ajax = (options) ->
|
||||
responded = false
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
"graceful-fs": "~2.0.1",
|
||||
"node-force-domain": "~0.1.0",
|
||||
"mailchimp-api": "2.0.x",
|
||||
"express-useragent": "~0.0.9",
|
||||
"express-useragent": "~0.0.9",
|
||||
"gridfs-stream": "0.4.x",
|
||||
"stream-buffers": "0.2.x",
|
||||
"sendwithus": "2.0.x",
|
||||
|
@ -66,7 +66,8 @@
|
|||
"webworker-threads": "~0.4.11",
|
||||
"node-gyp": "~0.13.0",
|
||||
"aether": "~0.2.3",
|
||||
"JASON": "~0.1.3"
|
||||
"JASON": "~0.1.3",
|
||||
"JQDeferred": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jade": "0.33.x",
|
||||
|
@ -97,7 +98,7 @@
|
|||
"karma": "~0.10.9",
|
||||
"karma-coverage": "~0.1.4",
|
||||
"compressible": "~1.0.1",
|
||||
"jasmine-spec-reporter":"~0.3.0"
|
||||
"jasmine-spec-reporter": "~0.3.0"
|
||||
},
|
||||
"license": "MIT for the code, and CC-BY for the art and music",
|
||||
"private": true,
|
||||
|
|
|
@ -449,7 +449,7 @@ addMatchToSessions = (newScoreObject, callback) ->
|
|||
matchObject.opponents[sessionID].name = session.name
|
||||
matchObject.opponents[sessionID].totalScore = session.totalScore
|
||||
matchObject.opponents[sessionID].metrics = {}
|
||||
matchObject.opponents[sessionID].metrics.rank = Number(newScoreObject[sessionID].gameRanking)
|
||||
matchObject.opponents[sessionID].metrics.rank = Number(newScoreObject[sessionID]?.gameRanking ? 0)
|
||||
|
||||
#log.info "Match object computed, result: #{matchObject}"
|
||||
#log.info "Writing match object to database..."
|
||||
|
|
Loading…
Reference in a new issue