mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-25 00:28:31 -05:00
Merge pull request #366 from codecombat/master
Merge master into production
This commit is contained in:
commit
186a77e827
31 changed files with 429 additions and 341 deletions
|
@ -4,4 +4,4 @@
|
|||
|
||||
It just grants us a non-exclusive license to use your contribution and certifies you have the right to contribute the code you submit. For both our sakes, we need this before we can accept a pull request. Don't worry, it's super easy.
|
||||
|
||||
For more info, see [http://codecombat.com/legal](http://codecombat.com/legal).
|
||||
For more info, see [http://codecombat.com/legal](http://codecombat.com/legal).
|
||||
|
|
|
@ -106,7 +106,7 @@ module.exports = class God
|
|||
window.BOX2D_ENABLED = true
|
||||
@lastSerializedWorldFrames = serialized.frames
|
||||
|
||||
finishBeholdingWorld: (newWorld) ->
|
||||
finishBeholdingWorld: (newWorld) =>
|
||||
newWorld.findFirstChangedFrame @world
|
||||
@world = newWorld
|
||||
errorCount = (t for t in @world.thangs when t.errorsOut).length
|
||||
|
@ -131,6 +131,8 @@ module.exports = class God
|
|||
@dead = true
|
||||
Backbone.Mediator.unsubscribe('tome:cast-spells', @onTomeCast, @)
|
||||
@goalManager = null
|
||||
@fillWorkerPool = null
|
||||
@simulateWorld = null
|
||||
|
||||
#### Bad code for running worlds on main thread (profiling / IE9) ####
|
||||
simulateWorld: =>
|
||||
|
@ -207,6 +209,7 @@ class Angel
|
|||
if @worker
|
||||
worker = @worker
|
||||
_.defer -> worker.terminate
|
||||
@worker.removeEventListener 'message', @onWorkerMessage
|
||||
@worker = null
|
||||
@
|
||||
|
||||
|
@ -217,6 +220,7 @@ class Angel
|
|||
|
||||
terminate: =>
|
||||
@worker?.terminate()
|
||||
@worker?.removeEventListener 'message', @onWorkerMessage
|
||||
@worker = null
|
||||
return if @dead
|
||||
@free()
|
||||
|
@ -224,7 +228,12 @@ class Angel
|
|||
|
||||
destroy: ->
|
||||
@dead = true
|
||||
@finishBeholdingWorld = null
|
||||
@abort()
|
||||
@terminate = null
|
||||
@testWorker = null
|
||||
@condemnWorker = null
|
||||
@onWorkerMessage = null
|
||||
|
||||
testWorker: =>
|
||||
@worker.postMessage {func: 'reportIn'}
|
||||
|
@ -235,22 +244,24 @@ class Angel
|
|||
@abort()
|
||||
|
||||
listen: ->
|
||||
@worker.addEventListener 'message', (event) =>
|
||||
switch event.data.type
|
||||
when 'new-world'
|
||||
@god.beholdWorld @, event.data.serialized, event.data.goalStates
|
||||
when 'world-load-progress-changed'
|
||||
Backbone.Mediator.publish 'god:world-load-progress-changed', event.data unless @dead
|
||||
when 'console-log'
|
||||
console.log "|" + @god.id + "'s " + @id + "|", event.data.args...
|
||||
when 'user-code-problem'
|
||||
@god.angelUserCodeProblem @, event.data.problem
|
||||
when 'abort'
|
||||
#console.log @id, "aborted."
|
||||
clearTimeout @abortTimeout
|
||||
@free()
|
||||
@god.angelAborted @
|
||||
when 'reportIn'
|
||||
clearTimeout @condemnTimeout
|
||||
else
|
||||
console.log "Unsupported message:", event.data
|
||||
@worker.addEventListener 'message', @onWorkerMessage
|
||||
|
||||
onWorkerMessage: (event) =>
|
||||
switch event.data.type
|
||||
when 'new-world'
|
||||
@god.beholdWorld @, event.data.serialized, event.data.goalStates
|
||||
when 'world-load-progress-changed'
|
||||
Backbone.Mediator.publish 'god:world-load-progress-changed', event.data unless @dead
|
||||
when 'console-log'
|
||||
console.log "|" + @god.id + "'s " + @id + "|", event.data.args...
|
||||
when 'user-code-problem'
|
||||
@god.angelUserCodeProblem @, event.data.problem
|
||||
when 'abort'
|
||||
#console.log @id, "aborted."
|
||||
clearTimeout @abortTimeout
|
||||
@free()
|
||||
@god.angelAborted @
|
||||
when 'reportIn'
|
||||
clearTimeout @condemnTimeout
|
||||
else
|
||||
console.log "Unsupported message:", event.data
|
||||
|
|
|
@ -28,7 +28,7 @@ module.exports = class LevelLoader extends CocoClass
|
|||
@loadLevelModels()
|
||||
@loadAudio()
|
||||
@playJingle()
|
||||
setTimeout (=> @update()), 1 # lets everything else resolve first
|
||||
_.defer @update # Lets everything else resolve first
|
||||
|
||||
playJingle: ->
|
||||
jingles = ["ident_1", "ident_2"]
|
||||
|
@ -41,9 +41,9 @@ module.exports = class LevelLoader extends CocoClass
|
|||
@session = new LevelSession()
|
||||
@session.url = -> url
|
||||
@session.fetch()
|
||||
@session.once 'sync', @onSessionLoaded
|
||||
@session.once 'sync', @onSessionLoaded, @
|
||||
|
||||
onSessionLoaded: =>
|
||||
onSessionLoaded: ->
|
||||
# TODO: maybe have all non versioned models do this? Or make it work to PUT/PATCH to relative urls
|
||||
@session.url = -> '/db/level.session/' + @id
|
||||
@update()
|
||||
|
@ -51,9 +51,9 @@ module.exports = class LevelLoader extends CocoClass
|
|||
# Supermodel (Level) Loading
|
||||
|
||||
loadLevelModels: ->
|
||||
@supermodel.once 'loaded-all', @onSupermodelLoadedAll
|
||||
@supermodel.on 'loaded-one', @onSupermodelLoadedOne
|
||||
@supermodel.once 'error', @onSupermodelError
|
||||
@supermodel.once 'loaded-all', @onSupermodelLoadedAll, @
|
||||
@supermodel.on 'loaded-one', @onSupermodelLoadedOne, @
|
||||
@supermodel.once 'error', @onSupermodelError, @
|
||||
@level = @supermodel.getModel(Level, @levelID) or new Level _id: @levelID
|
||||
levelID = @levelID
|
||||
|
||||
|
@ -65,12 +65,12 @@ module.exports = class LevelLoader extends CocoClass
|
|||
|
||||
@supermodel.populateModel @level
|
||||
|
||||
onSupermodelError: =>
|
||||
onSupermodelError: ->
|
||||
msg = $.i18n.t('play_level.level_load_error',
|
||||
defaultValue: "Level could not be loaded.")
|
||||
@$el.html('<div class="alert">' + msg + '</div>')
|
||||
|
||||
onSupermodelLoadedOne: (e) =>
|
||||
onSupermodelLoadedOne: (e) ->
|
||||
@notifyProgress()
|
||||
# if e.model.type() is 'ThangType'
|
||||
# thangType = e.model
|
||||
|
@ -80,18 +80,18 @@ module.exports = class LevelLoader extends CocoClass
|
|||
# building = thangType.buildSpriteSheet options
|
||||
# if building
|
||||
# @spriteSheetsToBuild += 1
|
||||
# thangType.on 'build-complete', =>
|
||||
# thangType.once 'build-complete', =>
|
||||
# @spriteSheetsBuilt += 1
|
||||
# @notifyProgress()
|
||||
|
||||
onSupermodelLoadedAll: =>
|
||||
onSupermodelLoadedAll: ->
|
||||
@trigger 'loaded-supermodel'
|
||||
@stopListening(@supermodel)
|
||||
@update()
|
||||
|
||||
# Things to do when either the Session or Supermodel load
|
||||
|
||||
update: ->
|
||||
update: =>
|
||||
@notifyProgress()
|
||||
|
||||
return if @updateCompleted
|
||||
|
@ -153,7 +153,7 @@ module.exports = class LevelLoader extends CocoClass
|
|||
return unless building
|
||||
console.log 'Building:', thangType.get('name'), options
|
||||
@spriteSheetsToBuild += 1
|
||||
thangType.on 'build-complete', =>
|
||||
thangType.once 'build-complete', =>
|
||||
@spriteSheetsBuilt += 1
|
||||
@notifyProgress()
|
||||
|
||||
|
@ -208,6 +208,8 @@ module.exports = class LevelLoader extends CocoClass
|
|||
@trigger 'loaded-all' if @progress() is 1
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@world = null # don't hold onto garbage
|
||||
@supermodel.off 'loaded-one', @onSupermodelLoadedOne
|
||||
super()
|
||||
@onSupermodelLoadedOne = null
|
||||
@notifyProgress = null
|
||||
|
|
|
@ -186,7 +186,7 @@ module.exports = class Camera extends CocoClass
|
|||
# Target is either just a {x, y} pos or a display object with {x, y} that might change; surface coordinates.
|
||||
time = 0 if @instant
|
||||
newTarget ?= {x:0, y:0}
|
||||
newTarget = (@newTarget or @target) if @locked
|
||||
newTarget = (@newTarget or @target) if @locked
|
||||
newZoom = Math.min((Math.max @minZoom, newZoom), MAX_ZOOM)
|
||||
return if @zoom is newZoom and newTarget is newTarget.x and newTarget.y is newTarget.y
|
||||
|
||||
|
@ -199,15 +199,13 @@ module.exports = class Camera extends CocoClass
|
|||
@tweenProgress = 0.01
|
||||
createjs.Tween.get(@)
|
||||
.to({tweenProgress: 1.0}, time, createjs.Ease.getPowInOut(3))
|
||||
.call @onTweenEnd
|
||||
.call @finishTween
|
||||
|
||||
else
|
||||
@target = newTarget
|
||||
@zoom = newZoom
|
||||
@updateZoom true
|
||||
|
||||
onTweenEnd: => @finishTween()
|
||||
|
||||
finishTween: (abort=false) =>
|
||||
createjs.Tween.removeTweens(@)
|
||||
return unless @newTarget
|
||||
|
@ -263,4 +261,5 @@ module.exports = class Camera extends CocoClass
|
|||
|
||||
destroy: ->
|
||||
super()
|
||||
@onTweenEnd = null
|
||||
createjs.Tween.removeTweens @
|
||||
@finishTween = null
|
||||
|
|
|
@ -80,6 +80,9 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
super()
|
||||
mark.destroy() for name, mark of @marks
|
||||
label.destroy() for name, label of @labels
|
||||
@imageObject?.off 'animationend', @playNextAction
|
||||
@playNextAction = null
|
||||
@displayObject?.off()
|
||||
|
||||
toString: -> "<CocoSprite: #{@thang?.id}>"
|
||||
|
||||
|
@ -108,7 +111,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@displayObject.sprite = @
|
||||
@displayObject.layerPriority = @thangType.get 'layerPriority'
|
||||
@displayObject.name = @thang?.spriteName or @thangType.get 'name'
|
||||
@imageObject.on 'animationend', @onActionEnd
|
||||
@imageObject.on 'animationend', @playNextAction
|
||||
|
||||
##################################################
|
||||
# QUEUEING AND PLAYING ACTIONS
|
||||
|
@ -126,10 +129,9 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@currentRootAction = action
|
||||
@playNextAction()
|
||||
|
||||
onActionEnd: (e) => @playNextAction()
|
||||
onSurfaceTicked: (e) -> @age += e.dt
|
||||
|
||||
playNextAction: ->
|
||||
playNextAction: =>
|
||||
@playAction(@actionQueue.splice(0,1)[0]) if @actionQueue.length
|
||||
|
||||
playAction: (action) ->
|
||||
|
@ -411,7 +413,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
sound = e.sound ? AudioPlayer.soundForDialogue e.message, @thangType.get 'soundTriggers'
|
||||
@instance?.stop()
|
||||
if @instance = @playSound sound, false
|
||||
@instance.addEventListener "complete", => Backbone.Mediator.publish 'dialogue-sound-completed'
|
||||
@instance.addEventListener "complete", -> Backbone.Mediator.publish 'dialogue-sound-completed'
|
||||
@notifySpeechUpdated e
|
||||
|
||||
onClearDialogue: (e) ->
|
||||
|
|
|
@ -7,14 +7,14 @@ CROSSFADE_LENGTH = 1500
|
|||
module.exports = class MusicPlayer extends CocoClass
|
||||
currentMusic: null
|
||||
standingBy: null
|
||||
|
||||
|
||||
subscriptions:
|
||||
'level-play-music': 'onPlayMusic'
|
||||
'audio-player:loaded': 'onAudioLoaded'
|
||||
|
||||
|
||||
constructor: ->
|
||||
super(arguments...)
|
||||
me.on('change:music', @onMusicSettingChanged, @)
|
||||
super arguments...
|
||||
me.on 'change:music', @onMusicSettingChanged, @
|
||||
|
||||
onAudioLoaded: ->
|
||||
@onPlayMusic(@standingBy) if @standingBy
|
||||
|
@ -29,12 +29,12 @@ module.exports = class MusicPlayer extends CocoClass
|
|||
AudioPlayer.preloadSound(src)
|
||||
@standingBy = e
|
||||
return
|
||||
|
||||
|
||||
@standingBy = null
|
||||
if @currentMusic
|
||||
f = -> @stop()
|
||||
createjs.Tween.get(@currentMusic).to({volume:0.0}, CROSSFADE_LENGTH).call(f)
|
||||
|
||||
|
||||
@currentMusic = createjs.Sound.play(src, 'none', 0, 0, -1, 0.3) if src and e.play
|
||||
return unless @currentMusic
|
||||
@currentMusic.volume = 0.0
|
||||
|
@ -48,4 +48,7 @@ module.exports = class MusicPlayer extends CocoClass
|
|||
return unless @currentMusic
|
||||
createjs.Tween.removeTweens(@currentMusic)
|
||||
@currentMusic.volume = if me.get('music') then 1.0 else 0.0
|
||||
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
me.off 'change:music', @onMusicSettingChanged, @
|
||||
|
|
|
@ -90,14 +90,19 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@dimmer?.destroy()
|
||||
@stage.clear()
|
||||
@musicPlayer?.destroy()
|
||||
@stage.removeAllChildren()
|
||||
@stage.removeEventListener 'stagemousemove', @onMouseMove
|
||||
@stage.removeEventListener 'stagemousedown', @onMouseDown
|
||||
@stage.removeAllEventListeners()
|
||||
@stage.enableDOMEvents false
|
||||
@stage.enableMouseOver 0
|
||||
@playScrubbedSounds = null
|
||||
@onMouseMove = null
|
||||
@onMouseDown = null
|
||||
@tick = null
|
||||
|
||||
@canvas.off 'mousewheel', @onMouseWheel
|
||||
@onMouseWheel = null
|
||||
|
||||
setWorld: (@world) ->
|
||||
@worldLoaded = true
|
||||
@world.getFrame(Math.min(@getCurrentFrame(), @world.totalFrames - 1)).restoreState() unless @options.choosing
|
||||
|
@ -337,7 +342,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@stage.enableMouseOver(10)
|
||||
@stage.addEventListener 'stagemousemove', @onMouseMove
|
||||
@stage.addEventListener 'stagemousedown', @onMouseDown
|
||||
@hookUpZoomControls()
|
||||
@canvas.on 'mousewheel', @onMouseWheel
|
||||
@hookUpChooseControls() if @options.choosing
|
||||
console.log "Setting fps", @world.frameRate unless @world.frameRate is 30
|
||||
createjs.Ticker.setFPS @world.frameRate
|
||||
|
@ -436,12 +441,11 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
onBackground = not @stage.hitTest e.stageX, e.stageY
|
||||
Backbone.Mediator.publish 'surface:stage-mouse-down', onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e
|
||||
|
||||
hookUpZoomControls: ->
|
||||
@canvas.bind 'mousewheel', (e) =>
|
||||
# https://github.com/brandonaaron/jquery-mousewheel
|
||||
e.preventDefault()
|
||||
return if @disabled
|
||||
Backbone.Mediator.publish 'surface:mouse-scrolled', deltaX: e.deltaX, deltaY: e.deltaY unless @disabled
|
||||
onMouseWheel: (e) =>
|
||||
# https://github.com/brandonaaron/jquery-mousewheel
|
||||
e.preventDefault()
|
||||
return if @disabled
|
||||
Backbone.Mediator.publish 'surface:mouse-scrolled', deltaX: e.deltaX, deltaY: e.deltaY unless @disabled
|
||||
|
||||
hookUpChooseControls: ->
|
||||
chooserOptions = stage: @stage, surfaceLayer: @surfaceLayer, camera: @camera, restrictRatio: @options.choosing is 'ratio-region'
|
||||
|
|
|
@ -247,7 +247,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription:
|
|||
and: "e"
|
||||
or: "ou"
|
||||
name: "Nome"
|
||||
# body: "Body"
|
||||
body: "Principal"
|
||||
version: "Versão"
|
||||
commit_msg: "Mensagem do Commit"
|
||||
version_history_for: "Histórico de Versão para: "
|
||||
|
@ -260,182 +260,183 @@ module.exports = nativeDescription: "português do Brasil", englishDescription:
|
|||
who_is_codecombat: "Quem é CodeCombat?"
|
||||
why_codecombat: "Por que CodeCombat?"
|
||||
who_description_prefix: "juntos começamos o CodeCombat em 2013. Noós também criamos "
|
||||
# who_description_suffix: "in 2008, growing it to the #1 web and iOS application for learning to write Chinese and Japanese characters."
|
||||
# who_description_ending: "Now it's time to teach people to write code."
|
||||
# why_paragraph_1: "When making Skritter, George didn't know how to program and was constantly frustrated by his inability to implement his ideas. Afterwards, he tried learning, but the lessons were too slow. His housemate, wanting to reskill and stop teaching, tried Codecademy, but \"got bored.\" Each week another friend started Codecademy, then dropped off. We realized it was the same problem we'd solved with Skritter: people learning a skill via slow, intensive lessons when what they need is fast, extensive practice. We know how to fix that."
|
||||
# why_paragraph_2: "Need to learn to code? You don't need lessons. You need to write a lot of code and have a great time doing it."
|
||||
# why_paragraph_3_prefix: "That's what programming is about. It's gotta be fun. Not fun like"
|
||||
# why_paragraph_3_italic: "yay a badge"
|
||||
# why_paragraph_3_center: "but fun like"
|
||||
# why_paragraph_3_italic_caps: "NO MOM I HAVE TO FINISH THE LEVEL!"
|
||||
# why_paragraph_3_suffix: "That's why CodeCombat is a multiplayer game, not a gamified lesson course. We won't stop until you can't stop--but this time, that's a good thing."
|
||||
# why_paragraph_4: "If you're going to get addicted to some game, get addicted to this one and become one of the wizards of the tech age."
|
||||
# why_ending: "And hey, it's free. "
|
||||
# why_ending_url: "Start wizarding now!"
|
||||
# george_description: "CEO, business guy, web designer, game designer, and champion of beginning programmers everywhere."
|
||||
# scott_description: "Programmer extraordinaire, software architect, kitchen wizard, and master of finances. Scott is the reasonable one."
|
||||
# nick_description: "Programming wizard, eccentric motivation mage, and upside-down experimenter. Nick can do anything and chooses to build CodeCombat."
|
||||
# jeremy_description: "Customer support mage, usability tester, and community organizer; you've probably already spoken with Jeremy."
|
||||
# michael_description: "Programmer, sys-admin, and undergrad technical wunderkind, Michael is the person keeping our servers online."
|
||||
who_description_suffix: "em 2008, subindo até o 1º lugar entre aplicativos web e para iOS para aprender caracteres chineses e japoneses."
|
||||
who_description_ending: "Agora é a hora de ensinar as pessoas a escreverem código."
|
||||
why_paragraph_1: " Quando estava desenvolvendo o Skritter, George não sabia como programar e ficava constantemente frustrado por causa de sua falta de habilidade para implementar suas idéias. Depois, ele tentou aprender, mas as aulas eram muito lentas. Seu colega de quarto, tentando inovar e parar de dar aulas, tentou o Codecademy, mas \"ficou entediado.\" A cada semana um novo amigo começava no Codecademy, e desistia em seguida. Nós percebemos que era o mesmo problema que havíamos resolvido com o Skritter: pessoas aprendendo uma habilidade através de aulas lentas e intensivas quando o que elas precisavam era de prática, rápida e extensa. Nós sabemos como consertar isso."
|
||||
why_paragraph_2: "Precisa aprender a codificar? Você não precisa de aulas. Você precisa escrever muito código e se divertir fazendo isso."
|
||||
why_paragraph_3_prefix: "É disso que se trata a programação. Tem que ser divertido. Não divertido como"
|
||||
why_paragraph_3_italic: "oba uma insígnia"
|
||||
why_paragraph_3_center: "mas divertido como"
|
||||
why_paragraph_3_italic_caps: "NÃO MÃE EU PRECISO TERMINAR ESSE NÍVEL!"
|
||||
why_paragraph_3_suffix: "É por isso que o CodeCombat é um jogo multiplayer, não uma aula que imita um jogo. Nós não iremos parar até você não conseguir parar--mas agora, isso é uma coisa boa."
|
||||
why_paragraph_4: "Se você vai se viciar em algum jogo, fique viciado nesse e se torne um dos magos da era da tecnologia."
|
||||
why_ending: "E é de graça. "
|
||||
why_ending_url: "Comece a feitiçaria agora!"
|
||||
george_description: "CEO, um cara de negócios, web designer, designer de jogos, e campeão em iniciar programadores em qualquer lugar."
|
||||
scott_description: "Programador extraordinário, arquiteto de software, mago da cozinha e mestre de finanças. Scott é o racional."
|
||||
nick_description: "Mago da programação, feiticeiro da motivação excêntrica e experimentador doido. Nick pode fazer qualquer coisa e escolheu desenvolver o CodeCombat."
|
||||
jeremy_description: "Mago em suporte ao consumidor, testador de usabilidade, e organizador da comunidade; você provavelmente já falou com o Jeremy."
|
||||
michael_description: "Programador, administrador de sistemas, e um técnico prodígio não graduado, Michael é a pessoa que mantém os servidores funcionando."
|
||||
|
||||
# legal:
|
||||
# page_title: "Legal"
|
||||
# opensource_intro: "CodeCombat is free to play and completely open source."
|
||||
# opensource_description_prefix: "Check out "
|
||||
# github_url: "our GitHub"
|
||||
# opensource_description_center: "and help out if you like! CodeCombat is built on dozens of open source projects, and we love them. See "
|
||||
# archmage_wiki_url: "our Archmage wiki"
|
||||
# opensource_description_suffix: "for a list of the software that makes this game possible."
|
||||
# practices_title: "Respectful Best Practices"
|
||||
# practices_description: "These are our promises to you, the player, in slightly less legalese."
|
||||
# privacy_title: "Privacy"
|
||||
# privacy_description: "We will not sell any of your personal information. We intend to make money through recruitment eventually, but rest assured we will not distribute your personal information to interested companies without your explicit consent."
|
||||
# security_title: "Security"
|
||||
# security_description: "We strive to keep your personal information safe. As an open source project, our site is freely open to anyone to review and improve our security systems."
|
||||
# email_title: "Email"
|
||||
# email_description_prefix: "We will not inundate you with spam. Through"
|
||||
# email_settings_url: "your email settings"
|
||||
# email_description_suffix: "or through links in the emails we send, you can change your preferences and easily unsubscribe at any time."
|
||||
# cost_title: "Cost"
|
||||
# cost_description: "Currently, CodeCombat is 100% free! One of our main goals is to keep it that way, so that as many people can play as possible, regardless of place in life. If the sky darkens, we might have to charge subscriptions or for some content, but we'd rather not. With any luck, we'll be able to sustain the company with:"
|
||||
# recruitment_title: "Recruitment"
|
||||
# recruitment_description_prefix: "Here on CodeCombat, you're going to become a powerful wizard–not just in the game, but also in real life."
|
||||
# url_hire_programmers: "No one can hire programmers fast enough"
|
||||
# recruitment_description_suffix: "so once you've sharpened your skills and if you agree, we will demo your best coding accomplishments to the thousands of employers who are drooling for the chance to hire you. They pay us a little, they pay you"
|
||||
# recruitment_description_italic: "a lot"
|
||||
# recruitment_description_ending: "the site remains free and everybody's happy. That's the plan."
|
||||
# copyrights_title: "Copyrights and Licenses"
|
||||
# contributor_title: "Contributor License Agreement"
|
||||
# contributor_description_prefix: "All contributions, both on the site and on our GitHub repository, are subject to our"
|
||||
# cla_url: "CLA"
|
||||
# contributor_description_suffix: "to which you should agree before contributing."
|
||||
# code_title: "Code - MIT"
|
||||
# code_description_prefix: "All code owned by CodeCombat or hosted on codecombat.com, both in the GitHub repository or in the codecombat.com database, is licensed under the"
|
||||
# mit_license_url: "MIT license"
|
||||
# code_description_suffix: "This includes all code in Systems and Components that are made available by CodeCombat for the purpose of creating levels."
|
||||
# art_title: "Art/Music - Creative Commons "
|
||||
# art_description_prefix: "All common content is available under the"
|
||||
# cc_license_url: "Creative Commons Attribution 4.0 International License"
|
||||
# art_description_suffix: "Common content is anything made generally available by CodeCombat for the purpose of creating Levels. This includes:"
|
||||
# art_music: "Music"
|
||||
# art_sound: "Sound"
|
||||
# art_artwork: "Artwork"
|
||||
# art_sprites: "Sprites"
|
||||
# art_other: "Any and all other non-code creative works that are made available when creating Levels."
|
||||
# art_access: "Currently there is no universal, easy system for fetching these assets. In general, fetch them from the URLs as used by the site, contact us for assistance, or help us in extending the site to make these assets more easily accessible."
|
||||
# art_paragraph_1: "For attribution, please name and link to codecombat.com near where the source is used or where appropriate for the medium. For example:"
|
||||
# use_list_1: "If used in a movie or another game, include codecombat.com in the credits."
|
||||
# use_list_2: "If used on a website, include a link near the usage, for example underneath an image, or in a general attributions page where you might also mention other Creative Commons works and open source software being used on the site. Something that's already clearly referencing CodeCombat, such as a blog post mentioning CodeCombat, does not need some separate attribution."
|
||||
# art_paragraph_2: "If the content being used is created not by CodeCombat but instead by a user of codecombat.com, attribute them instead, and follow attribution directions provided in that resource's description if there are any."
|
||||
# rights_title: "Rights Reserved"
|
||||
# rights_desc: "All rights are reserved for Levels themselves. This includes"
|
||||
# rights_scripts: "Scripts"
|
||||
# rights_unit: "Unit configuration"
|
||||
# rights_description: "Description"
|
||||
# rights_writings: "Writings"
|
||||
# rights_media: "Media (sounds, music) and any other creative content made specifically for that Level and not made generally available when creating Levels."
|
||||
# rights_clarification: "To clarify, anything that is made available in the Level Editor for the purpose of making levels is under CC, whereas the content created with the Level Editor or uploaded in the course of creation of Levels is not."
|
||||
# nutshell_title: "In a Nutshell"
|
||||
# nutshell_description: "Any resources we provide in the Level Editor are free to use as you like for creating Levels. But we reserve the right to restrict distribution of the Levels themselves (that are created on codecombat.com) so that they may be charged for in the future, if that's what ends up happening."
|
||||
# canonical: "The English version of this document is the definitive, canonical version. If there are any discrepencies between translations, the English document takes precedence."
|
||||
|
||||
# contribute:
|
||||
# page_title: "Contributing"
|
||||
# character_classes_title: "Character Classes"
|
||||
# introduction_desc_intro: "We have high hopes for CodeCombat."
|
||||
# introduction_desc_pref: "We want to be where programmers of all stripes come to learn and play together, introduce others to the wonderful world of coding, and reflect the best parts of the community. We can't and don't want to do that alone; what makes projects like GitHub, Stack Overflow and Linux great are the people who use them and build on them. To that end, "
|
||||
# introduction_desc_github_url: "CodeCombat is totally open source"
|
||||
# introduction_desc_suf: ", and we aim to provide as many ways as possible for you to take part and make this project as much yours as ours."
|
||||
# introduction_desc_ending: "We hope you'll join our party!"
|
||||
# introduction_desc_signature: "- Nick, George, Scott, Michael, and Jeremy"
|
||||
# alert_account_message_intro: "Hey there!"
|
||||
# alert_account_message_pref: "To subscribe for class emails, you'll need to "
|
||||
# alert_account_message_suf: "first."
|
||||
# alert_account_message_create_url: "create an account"
|
||||
# archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever."
|
||||
# class_attributes: "Class Attributes"
|
||||
# archmage_attribute_1_pref: "Knowledge in "
|
||||
# archmage_attribute_1_suf: ", or a desire to learn. Most of our code is in this language. If you're a fan of Ruby or Python, you'll feel right at home. It's JavaScript, but with a nicer syntax."
|
||||
# archmage_attribute_2: "Some experience in programming and personal initiative. We'll help you get oriented, but we can't spend much time training you."
|
||||
# how_to_join: "How To Join"
|
||||
# join_desc_1: "Anyone can help out! Just check out our "
|
||||
# join_desc_2: "to get started, and check the box below to mark yourself as a brave Archmage and get the latest news by email. Want to chat about what to do or how to get more deeply involved? "
|
||||
# join_desc_3: ", or find us in our "
|
||||
# join_desc_4: "and we'll go from there!"
|
||||
# join_url_email: "Email us"
|
||||
# join_url_hipchat: "public HipChat room"
|
||||
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_introduction_suf: "to then this class might be for you."
|
||||
# artisan_attribute_1: "Any experience in building content like this would be nice, such as using Blizzard's level editors. But not required!"
|
||||
# artisan_attribute_2: "A hankering to do a whole lot of testing and iteration. To make good levels, you need to take it to others and watch them play it, and be prepared to find a lot of things to fix."
|
||||
# artisan_attribute_3: "For the time being, endurance en par with an Adventurer. Our Level Editor is super preliminary and frustrating to use. You have been warned!"
|
||||
# artisan_join_desc: "Use the Level Editor in these steps, give or take:"
|
||||
# artisan_join_step1: "Read the documentation."
|
||||
# artisan_join_step2: "Create a new level and explore existing levels."
|
||||
# artisan_join_step3: "Find us in our public HipChat room for help."
|
||||
# artisan_join_step4: "Post your levels on the forum for feedback."
|
||||
# more_about_artisan: "Learn More About Becoming A Creative Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you."
|
||||
# adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though."
|
||||
# adventurer_attribute_2: "Charismatic. Be gentle but articulate about what needs improving, and offer suggestions on how to improve."
|
||||
# adventurer_join_pref: "Either get together with (or recruit!) an Artisan and work with them, or check the box below to receive emails when there are new levels to test. We'll also be posting about levels to review on our networks like"
|
||||
# adventurer_forum_url: "our forum"
|
||||
# adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!"
|
||||
# more_about_adventurer: "Learn More About Becoming A Brave Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# 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 can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the "
|
||||
# scribe_introduction_url_mozilla: "Mozilla Developer Network"
|
||||
# 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."
|
||||
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
|
||||
# contact_us_url: "Contact us"
|
||||
# scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!"
|
||||
# more_about_scribe: "Learn More About Becoming A Diligent Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_introduction_pref: "So, if there's one thing we learned from the "
|
||||
# diplomat_launch_url: "launch in October"
|
||||
# diplomat_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries, particularly Brazil! We're building a corps of translators eager to turn one set of words into another set of words to get CodeCombat as accessible across the world as possible. If you like getting sneak peeks at upcoming content and getting these levels to your fellow nationals ASAP, then this class might be for you."
|
||||
# diplomat_attribute_1: "Fluency in English and the language you would like to translate to. When conveying complicated ideas, it's important to have a strong grasp in both!"
|
||||
# diplomat_join_pref: "We've started a lot of initial translations at "
|
||||
# diplomat_doc_url: "this forum post"
|
||||
# diplomat_join_suf: "so check it out and add things for your language. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming A Great Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you."
|
||||
# ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!"
|
||||
# ambassador_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll go from there!"
|
||||
# ambassador_join_note_strong: "Note"
|
||||
# ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!"
|
||||
# more_about_ambassador: "Learn More About Becoming A Helpful Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_introduction_1: "Do you have life experience? A different perspective on things that can help us decide how to shape CodeCombat? Of all these roles, this will probably take the least time, but individually you may make the most difference. We're on the lookout for wisened sages, particularly in areas like: teaching, game development, open source project management, technical recruiting, entrepreneurship, or design."
|
||||
# counselor_introduction_2: "Or really anything that is relevant to the development of CodeCombat. If you have knowledge and want to share it to help grow this project, then this class might be for you."
|
||||
# counselor_attribute_1: "Experience, in any of the areas above or something you think might be helpful."
|
||||
# counselor_attribute_2: "A little bit of free time!"
|
||||
# counselor_join_desc: "tell us a little about yourself, what you've done and what you'd be interested in doing. We'll put you in our contact list and be in touch when we could use advice (not too often)."
|
||||
# more_about_counselor: "Learn More About Becoming A Valuable Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
# creative_artisans: "Our Creative Artisans:"
|
||||
# brave_adventurers: "Our Brave Adventurers:"
|
||||
# translating_diplomats: "Our Translating Diplomats:"
|
||||
# helpful_ambassadors: "Our Helpful Ambassadors:"
|
||||
legal:
|
||||
page_title: "Jurídico"
|
||||
opensource_intro: "CodeCombat é grátis para jogar e de código completamente aberto."
|
||||
opensource_description_prefix: "Confira "
|
||||
github_url: "nosso GitHub"
|
||||
opensource_description_center: "e ajude-nos se você gostar! CodeCombat é construído a partir de dúzias de projetos de código aberto, e nós amamos eles. Veja "
|
||||
archmage_wiki_url: "nossa wiki mágica"
|
||||
opensource_description_suffix: "para uma lista dos softwares que fazem esse jogo possível."
|
||||
practices_title: "Respeitáveis Boas Práticas"
|
||||
practices_description: "Essas são nossas promessas para você, o jogador, de uma maneira menos jurídica."
|
||||
privacy_title: "Privacidade"
|
||||
privacy_description: "Nós não venderemos nenhuma de suas informações pessoais. Nós pretendemos ganhar dinheiro através de recrutamento eventualmente, mas fiquem tranquilos que nós não distribuiremos suas informações pessoais para companhias interessadas sem a sua aprovação explícita."
|
||||
security_title: "Segurança"
|
||||
security_description: "Nós lutamos para manter suas informações pessoais a salvo.Como um projeto de código aberto, nosso site é aberto para qualquer um rever e melhorar nossos sistemas de segurança."
|
||||
email_title: "Email"
|
||||
email_description_prefix: "Nós não iremos te encher de spam. Através"
|
||||
email_settings_url: "das suas configurações de email"
|
||||
email_description_suffix: "ou através de links nos emails que enviarmos, você pode trocar as preferências e facilmente se desinscrever a qualquer hora."
|
||||
cost_title: "Custo"
|
||||
cost_description: "Atualmente o CodeCombat é 100% grátis. Um dos nossos principais objetivos é mantê-lo dessa forma, para que, o maior número possível de pessoas possa jogar, independente de seu lugar na vida. Se o céu escurecer, nós poderemos ter que cobrar uma assinatura, ou por algum conteúdo, mas preferimos que não. Com alguma sorte, nós seremos capazes de manter a empresa com:"
|
||||
recruitment_title: "Recrutamento"
|
||||
recruitment_description_prefix: "Aqui no CodeCombat, você vai se tornar um poderoso feiticeiro, não apenas no jogo, mas também na vida real."
|
||||
url_hire_programmers: "Ninguém pode contratar programadores rápido o bastante"
|
||||
recruitment_description_suffix: "então quando você aumentar suas habilidade e, se concordar, vamos demonstrar suas melhores realizações em codificação para os milhares de empregadores que estão babando para ter a chance de contratá-lo. Eles nos pagam um pouco, eles te pagam"
|
||||
recruitment_description_italic: "muito"
|
||||
recruitment_description_ending: "o site continua grátis e todo mundo fica feliz. Esse é o plano."
|
||||
copyrights_title: "Direitos Autorais e Licenças"
|
||||
contributor_title: "Contrato de Licença de Colaborador"
|
||||
contributor_description_prefix: "Todos os colaboradores, tanto no nosso site quando no nosso repositório no GitHub estão sujeitos ao nosso"
|
||||
cla_url: "CLA"
|
||||
contributor_description_suffix: " para o qual você deve estar de acordo antes de contribuir."
|
||||
code_title: "Código - MIT"
|
||||
code_description_prefix: "Todo o código possuído pelo CodeCombat ou hospedado no codecombat.com, tanto no nosso repositório no GitHub como no banco de dados do codecombat.com, é licenciado sob"
|
||||
mit_license_url: "Licença do MIT"
|
||||
code_description_suffix: "Isso inclui todo o código nos sistemas e componentes que são disponibilizados pelo CodeCombat para o propósito de criar níveis."
|
||||
art_title: "Arte/Música - Creative Commons "
|
||||
art_description_prefix: "Todo o conteúdo comum está disponível sob a"
|
||||
cc_license_url: "Creative Commons Attribution 4.0 International License"
|
||||
art_description_suffix: "Conteúdo comum é qualquer coisa disponível pelo CodeCombat com o propósito de criar níveis. Isto inclui:"
|
||||
art_music: "Música"
|
||||
art_sound: "Som"
|
||||
art_artwork: "Obra de arte"
|
||||
art_sprites: "Sprites"
|
||||
art_other: "Todo e qualquer outros trabalho criativo não relacionados a código que são disponibilizados para criar níveis."
|
||||
art_access: "Atualmente não existe um sistema universal e fácil para buscar por essas obras. Em geral, busque-os através das URLs utilizadas pelo site, entre em contato conosco para obter auxílio, ou nos ajude a estender o site para tornar as obras acessíveis mais facilmente."
|
||||
art_paragraph_1: "Para atribuição, por favor, nomeie e referencie o codecombat.com perto de onde a fonte é utilizada, ou onde for apropriado para o meio. Por exemplo:"
|
||||
use_list_1: "Se usado em um filme ou outro jogo, inclua codecombat.com nos créditos."
|
||||
use_list_2: "Se usado em um site, incluir um link perto do local de uso, por exemplo, em baixo de uma imagem, ou em uma página de atribuições gerais onde você pode também mencionar outros trabalhos em Creative Commons e softwares de código aberto que estão sendo usados no site.Algo que já está referenciando claramente o CodeCombat, como um post no blog mencionando o CodeCombat, não precisa de atribuição separada."
|
||||
art_paragraph_2: "Se o conteúdo que está sendo usado não é criado pelo CodeCombat mas por algum usuário do codecombat.com, você deve referenciá-los seguindo as normas contidas neste documento caso haja alguma."
|
||||
rights_title: "Direitos Reservados"
|
||||
rights_desc: "Todos os direitos são reservados para os Níveis em si. Isto inclui"
|
||||
rights_scripts: "Scripts"
|
||||
rights_unit: "Configurações de unidades"
|
||||
rights_description: "Descrição"
|
||||
rights_writings: "Escritos"
|
||||
rights_media: "Mídia (sons, música) e qualquer outro conteúdo criativo feito especificamente para esse nível e que não estão disponíveis quando se está criando níveis."
|
||||
rights_clarification: "Para esclarecer, tudo o que é disponibilizado no Editor de Níveis com o objetivo de criar os níveis está sob CC, enquanto que o conteúdo criado através do Editor de Níveis ou inserido durante o processo de criação dos níveis não é."
|
||||
nutshell_title: "Em poucas palavras"
|
||||
nutshell_description: "Todos os recursos que oferecemos no Editor de Níveis é livre para usar como quiser para a criação de níveis. Mas nós nos reservamos o direito de restringir a distribuição dos próprios níveis (que são criados em codecombat.com) para que possam ser cobrados no futuro, se é que isso precise acontecer."
|
||||
canonical: "A versão em inglês deste documento é a versão canônica definitiva. Se houver discrepâncias entre traduções, o documento em inglês tem precedência."
|
||||
|
||||
# classes:
|
||||
# archmage_title: "Archmage"
|
||||
# archmage_title_description: "(Coder)"
|
||||
# artisan_title: "Artisan"
|
||||
# artisan_title_description: "(Level Builder)"
|
||||
# adventurer_title: "Adventurer"
|
||||
# adventurer_title_description: "(Level Playtester)"
|
||||
# scribe_title: "Scribe"
|
||||
# scribe_title_description: "(Article Editor)"
|
||||
# diplomat_title: "Diplomat"
|
||||
# diplomat_title_description: "(Translator)"
|
||||
# ambassador_title: "Ambassador"
|
||||
# ambassador_title_description: "(Support)"
|
||||
# counselor_title: "Counselor"
|
||||
# counselor_title_description: "(Expert/Teacher)"
|
||||
contribute:
|
||||
page_title: "Contribuindo"
|
||||
character_classes_title: "Classes de Personagem"
|
||||
introduction_desc_intro: "Nós temos grandes expectativas para o CodeCombat."
|
||||
introduction_desc_pref: "Queremos ser o lugar onde os programadores de todos os tipos vêm para aprender e brincarem juntos, introduzir outros ao maravilhoso mundo da codificação, e refletir as melhores partes da comunidade. Não podemos e não queremos fazer isso sozinhos, o que faz de projetos como o GitHub, Stack Overflow e Linux ótimos são as pessoas que os utilizam e constróem sobre eles. Para esse fim, "
|
||||
introduction_desc_github_url: "CodeCombat é totalmente código aberto"
|
||||
introduction_desc_suf: ", e nosso objetivo é oferecer quantas maneiras forem possíveis para você participar e fazer deste projeto tanto seu como nosso."
|
||||
introduction_desc_ending: "Nós esperamos que você se junte a nossa festa!"
|
||||
introduction_desc_signature: "- Nick, George, Scott, Michael, and Jeremy"
|
||||
alert_account_message_intro: "Ei!"
|
||||
alert_account_message_pref: "Para se inscrever para os emails de classe, você vai precisar, "
|
||||
alert_account_message_suf: "primeiro."
|
||||
alert_account_message_create_url: "criar uma conta"
|
||||
archmage_introduction: "Uma das melhores partes sobre a construção de jogos é que eles sintetizam diversas coisas diferentes. Gráficos, som, interação em tempo real, redes sociais, e, claro, muitos dos aspectos mais comuns da programação, desde a gestão em baixo nível de banco de dados, e administração do servidor até interação com o usuário e desenvolvimento da interface. Há muito a fazer, e se você é um programador experiente com um desejo ardente de realmente mergulhar no âmago da questão do CodeCombat, esta classe pode ser para você. Nós gostaríamos de ter sua ajuda para construir o melhor jogo de programação de todos os tempos."
|
||||
class_attributes: "Atributos da Classe"
|
||||
archmage_attribute_1_pref: "Conhecimento em "
|
||||
archmage_attribute_1_suf: ", ou um desejo de aprender. A maioria do nosso código é escrito nessa lingua. Se você é um fã de Ruby ou Python, você vai se sentir em casa. É JavaScript, mas com uma sintaxe mais agradável."
|
||||
archmage_attribute_2: "Alguma experiência em programação e iniciativa pessoal. Nós vamos ajudá-lo a se orientar, mas não podemos passar muito tempo treinando você."
|
||||
how_to_join: "Como Participar"
|
||||
join_desc_1: "Qualquer um pode ajudar! Confira nosso "
|
||||
join_desc_2: "para começar, e marque a caixa abaixo para marcar-se como um arquimago corajoso e receba as últimas notícias por email. Quer conversar sobre o que fazer ou como se envolver mais profundamente? "
|
||||
join_desc_3: ", ou encontre-nos em nosso "
|
||||
join_desc_4: "e começaremos a partir de lá!"
|
||||
join_url_email: "Envie-nos um email"
|
||||
join_url_hipchat: "Sala de bate-papo pública no HipChat"
|
||||
more_about_archmage: "Saiba Mais Sobre Como Se Tornar Um Poderoso Arquimago"
|
||||
archmage_subscribe_desc: "Receba email sobre novas oportunidades para codificar e anúncios."
|
||||
artisan_introduction_pref: "Nós devemos contruir níveis adicionais! Pessoas estão clamando por mais conteúdo, e só podemos contruir tantos de nós mesmos. Agora sua estação de trabalho é o nível um; nosso Editor de Níveis é pouco utilizável até mesmo para seus criadores, então fique esperto. Se você tem visões de campanhas abrangendo for-loops para"
|
||||
artisan_introduction_suf: "para, em seguida, esta classe pode ser para você."
|
||||
artisan_attribute_1: "Qualquer experiência em construir conteúdo como esse seria legal, como usando os editores de nível da Blizzard. Mas não é obrigatório!"
|
||||
artisan_attribute_2: "Um desejo ardente de fazer um monte de testes e iteração. Para fazer bons níveis, você precisa levá-lo para os outros e vê-los jogar, e estar preparado para encontrar muitas coisas para consertar."
|
||||
artisan_attribute_3: "Por enquanto, a resistência em par com um Aventureiro. Nosso Editor de Níveis é super preliminar e frustrante para usar. Você foi avisado!"
|
||||
artisan_join_desc: "Use o Editor de Níveis nestas etapas, mais ou menos:"
|
||||
artisan_join_step1: "Leia a documentação."
|
||||
artisan_join_step2: "Crie um novo nível e explore os níveis existentes."
|
||||
artisan_join_step3: "Encontre-nos na nossa sala pública no HipChat para ajuda."
|
||||
artisan_join_step4: "Publique seus níveis no fórum para avaliação."
|
||||
more_about_artisan: "Saiba Mais Sobre Como Se Tornar Um Artesão Criativo"
|
||||
artisan_subscribe_desc: "Receba emails com novidades sobre o editor de níveis e anúncios."
|
||||
adventurer_introduction: "Vamos ser claros sobre o seu papel: você é o tanque. Você vai tomar dano pesado. Precisamos de pessoas para experimentar níveis inéditos e ajudar a identificar como fazer as coisas melhorarem. A dor será enorme, fazer bons jogos é um processo longo e ninguém acerta na primeira vez. Se você pode suportar e ter uma alta pontuação de constituição, então esta classe pode ser para você."
|
||||
adventurer_attribute_1: "Sede de aprendizado. Você quer aprender a codificar e nós queremos ensiná-lo a codificar. Você provavelmente vai fazer a maior parte do ensino neste caso."
|
||||
adventurer_attribute_2: "Carismático. Seja gentil, mas articulado sobre o que precisa melhorar, e ofereça sugestões sobre como melhorar."
|
||||
adventurer_join_pref: "Se reuna (ou recrute!) um Artesão e trabalhe com ele, ou marque a caixa abaixo para receber emails quando houver novos níveis para testar. Também estaremos postando sobre níveis que precisam de revisão em nossas redes como"
|
||||
adventurer_forum_url: "nosso fórum"
|
||||
adventurer_join_suf: "então se você prefere ser notificado dessas formas, inscreva-se lá!"
|
||||
more_about_adventurer: "Saiba Mais Sobre Como Se Tornar Um Valente Aventureiro"
|
||||
adventurer_subscribe_desc: "Receba emails quando houver novos níveis para testar."
|
||||
scribe_introduction_pref: "O CodeCombat não será apenas um monte de níveis. Ele também irá incluir uma fonte de conhecimento, um wiki de conceitos de programação que os níveis podem se basear. Dessa forma, em vez de cada Artesão ter que descrever em detalhes o que é um operador de comparação, eles podem simplesmente criar um link para o artigo que o descreve. Algo na linha do que a "
|
||||
scribe_introduction_url_mozilla: "Mozilla Developer Network"
|
||||
scribe_introduction_suf: " construiu. Se a sua idéia de diversão é articular os conceitos de programação em Markdown, então esta classe pode ser para você."
|
||||
scribe_attribute_1: "Habilidade com palavras é praticamente tudo o que você precisa. Não só a gramática e ortografica, mas a capacidade de transmitir idéias muito complicadas para os outros."
|
||||
contact_us_url: "Contate-nos"
|
||||
scribe_join_description: "conte-nos um pouco sobre você, sua experiência com programação e que tipo de coisas você gostaria de escrever sobre. Nós começaremos a partir disso!"
|
||||
more_about_scribe: "Saiba Mais Sobre Como Se Tornar Um Escriba Aplicado"
|
||||
scribe_subscribe_desc: "Receba email sobre anúncios de escrita de artigos."
|
||||
diplomat_introduction_pref: "Então, se há uma coisa que aprendemos com o "
|
||||
diplomat_launch_url: "lançamento em Outubro"
|
||||
diplomat_introduction_suf: "é que há um interesse considerável no CodeCombat em outros países, especialmente no Brasil! Estamos construindo um corpo de tradutores ansiosos para transformar um conjunto de palavras em outro conjunto de palavras para tornar o CodeCombat tão acessível em todo o mundo quanto for possível. Se você gosta de obter cenas inéditas do próximo conteúdo e obter esses níveis para os seus compatriotas o mais rápido possível, então esta classe pode ser para você."
|
||||
diplomat_attribute_1: "Fluência no inglês e na língua para a qual você gostaria de traduzir. Ao transmitir idéias complicadas, é importante ter um forte domínio em ambos!"
|
||||
diplomat_join_pref: "Nós começamos várias traduções iniciais "
|
||||
diplomat_doc_url: "nesta publicação no fórum"
|
||||
diplomat_join_suf: "então confira a publicação e comece a adicionar coisas para o seu idioma. Além disso, marque a caixa abaixo para se manter atualizado sobre os novos desenvolvimentos da internacionalização!"
|
||||
more_about_diplomat: "Saiba Mais Sobre Como Se Tornar Um Ótimo Diplomata"
|
||||
diplomat_subscribe_desc: "Receba emails sobre o desenvolvimento da i18n e níveis para traduzir."
|
||||
ambassador_introduction: "Esta é uma comunidade que estamos construindo, e vocês são as conexões. Temos chats Olark, emails e redes sociais com muitas pessoas para conversar e ajudar a se familiarizar com o jogo e aprender. Se você quer ajudar as pessoas a se envolver e se divertir, e ter uma boa noção da pulsação do CodeCombat e para onde estamos indo em seguida, esta classe pode ser para você."
|
||||
ambassador_attribute_1: "Habilidades de comunicação. Ser capaz de identificar os problemas que os jogadores estão tendo e ajudar a resolvê-los, Além disso, manter o resto de nós informados sobre o que os jogadores estão dizendo, o que gostam e não gostam e do que querem mais!"
|
||||
ambassador_join_desc: "conte-nos um pouco sobre você, o que você fez e o que você estaria interessado em fazer. Nós começaremos a partir disso!"
|
||||
ambassador_join_note_strong: "Nota"
|
||||
ambassador_join_note_desc: "Uma das nossas principais prioridades é a construção de um multiplayer onde os jogadores que estão com dificuldade para resolver um nível podem invocar feitiçeiros com nível mais alto para ajudá-los. Esta será uma ótima maneira para os embaixadores fazerem suas tarefas. Vamos mantê-lo informado!"
|
||||
more_about_ambassador: "Saiba Mais Sobre Como Se Tornar Um Embaixador Prestativo"
|
||||
ambassador_subscribe_desc: "Receba emails sobre atualização do suporte e desenvolvimento do multiplayer."
|
||||
counselor_introduction_1: "Você tem experiência de vida? Uma perspectiva diferente sobre as coisas podem nos ajudar a decidir como moldar o CodeCombat? De todos os papéis, este provavelmente vai demorar menos tempo, mas individualmente você pode fazer mais diferença. Estamos à procura de sábios, particularmente em áreas como: ensino, desenvolvimento de jogos, gerenciamente de projetos de código aberto, recrutamento técnico, empreendedorismo ou design."
|
||||
counselor_introduction_2: "Ou realmente tudo o que é relevante para o desenvolvimento do CodeCombat. Se você tem conhecimento e quer compartilhá-lo para ajudar este projeto a crescer, esta classe pode ser para você."
|
||||
counselor_attribute_1: "Experiência, em qualquer uma das áreas acima ou alguma coisa que você pense ser útil."
|
||||
counselor_attribute_2: "Um pouco de tempo livre!"
|
||||
counselor_join_desc: "conte-nos um pouco sobre você, o que você fez e o que você estaria interessado em fazer. Vamos colocá-lo em nossa lista de contatos e entraremos em contato quando precisarmos de um conselho (não muitas vezes)."
|
||||
more_about_counselor: "Saiba Mais Sobre Como Se Tornar Um Conselheiro Valioso"
|
||||
changes_auto_save: "As alterações são salvas automaticamente quando você marcar as caixas de seleção."
|
||||
diligent_scribes: "Nossos Aplicados Escribas:"
|
||||
powerful_archmages: "Nossos Poderosos Arquimagos:"
|
||||
creative_artisans: "Nossos Criativos Artesãos:"
|
||||
brave_adventurers: "Nossos Valentes Aventureiros:"
|
||||
translating_diplomats: "Nossos Diplomatas Tradutores:"
|
||||
helpful_ambassadors: "Nossos Prestativos Embaixadores:"
|
||||
|
||||
classes:
|
||||
archmage_title: "Arquimago"
|
||||
archmage_title_description: "(Codificador)"
|
||||
artisan_title: "Artesão"
|
||||
artisan_title_description: "(Construtor de Nível)"
|
||||
adventurer_title: "Aventureiro"
|
||||
adventurer_title_description: "(Testador de Nível)"
|
||||
scribe_title: "Escriba"
|
||||
scribe_title_description: "(Escritor de Artigos)"
|
||||
diplomat_title: "Diplomata"
|
||||
diplomat_title_description: "(Tradutor)"
|
||||
ambassador_title: "Embaixador"
|
||||
ambassador_title_description: "(Suporte)"
|
||||
counselor_title: "Conselheiro"
|
||||
counselor_title_description: "(Especialista/Professor)"
|
||||
|
|
|
@ -25,7 +25,7 @@ class CocoModel extends Backbone.Model
|
|||
@loadSchema()
|
||||
@once 'sync', @onLoaded, @
|
||||
@saveBackup = _.debounce(@saveBackup, 500)
|
||||
|
||||
|
||||
type: ->
|
||||
@constructor.className
|
||||
|
||||
|
@ -36,18 +36,18 @@ class CocoModel extends Backbone.Model
|
|||
if @saveBackups
|
||||
existing = storage.load @id
|
||||
if existing
|
||||
@set(existing, {silent:true})
|
||||
@set(existing, {silent:true})
|
||||
CocoModel.backedUp[@id] = @
|
||||
|
||||
|
||||
set: ->
|
||||
res = super(arguments...)
|
||||
@saveBackup() if @saveBackups and @loaded and @hasLocalChanges()
|
||||
res
|
||||
|
||||
|
||||
saveBackup: ->
|
||||
storage.save(@id, @attributes)
|
||||
CocoModel.backedUp[@id] = @
|
||||
|
||||
|
||||
@backedUp = {}
|
||||
|
||||
loadSchema: ->
|
||||
|
@ -55,7 +55,7 @@ class CocoModel extends Backbone.Model
|
|||
@constructor.schema = new CocoSchema(@urlRoot)
|
||||
@constructor.schema.fetch()
|
||||
|
||||
@constructor.schema.on 'sync', =>
|
||||
@constructor.schema.once 'sync', =>
|
||||
@constructor.schema.loaded = true
|
||||
@addSchemaDefaults()
|
||||
@trigger 'schema-loaded'
|
||||
|
@ -90,7 +90,7 @@ class CocoModel extends Backbone.Model
|
|||
revert: ->
|
||||
@set(@_revertAttributes, {silent: true}) if @_revertAttributes
|
||||
@clearBackup()
|
||||
|
||||
|
||||
clearBackup: ->
|
||||
storage.remove @id
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ module.exports = class LevelComponent extends CocoModel
|
|||
attrs.js = @compile attrs.code
|
||||
super attrs, options
|
||||
|
||||
onLoaded: =>
|
||||
onLoaded: ->
|
||||
super()
|
||||
@set 'js', @compile(@get 'code') unless @get 'js'
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ module.exports = class LevelSystem extends CocoModel
|
|||
attrs.js = @compile attrs.code
|
||||
super attrs, options
|
||||
|
||||
onLoaded: =>
|
||||
onLoaded: ->
|
||||
super()
|
||||
@set 'js', @compile(@get 'code') unless @get 'js'
|
||||
|
||||
|
|
|
@ -8,22 +8,23 @@ class SuperModel
|
|||
@mustPopulate = model
|
||||
model.saveBackups = @shouldSaveBackups(model)
|
||||
model.fetch() unless model.loaded or model.loading
|
||||
model.on('sync', @modelLoaded) unless model.loaded
|
||||
model.once('error', @modelErrored) unless model.loaded
|
||||
model.once('sync', @modelLoaded, @) unless model.loaded
|
||||
model.once('error', @modelErrored, @) unless model.loaded
|
||||
url = model.url()
|
||||
@models[url] = model unless @models[url]?
|
||||
@modelLoaded(model) if model.loaded
|
||||
|
||||
# replace or overwrite
|
||||
shouldPopulate: (url) -> return true
|
||||
shouldPopulate: (url) -> return true
|
||||
shouldSaveBackups: (model) -> return false
|
||||
|
||||
modelErrored: (model) =>
|
||||
modelErrored: (model) ->
|
||||
@trigger 'error'
|
||||
@removeEventsFromModel(model)
|
||||
|
||||
modelLoaded: (model) =>
|
||||
modelLoaded: (model) ->
|
||||
schema = model.schema()
|
||||
return schema.on('sync', => @modelLoaded(model)) unless schema.loaded
|
||||
return schema.once('sync', => @modelLoaded(model)) unless schema.loaded
|
||||
refs = model.getReferencedModels(model.attributes, schema.attributes)
|
||||
refs = [] unless @mustPopulate is model or @shouldPopulate(model)
|
||||
# console.log 'Loaded', model.get('name')
|
||||
|
@ -33,10 +34,15 @@ class SuperModel
|
|||
continue if @models[refURL]
|
||||
@models[refURL] = ref
|
||||
ref.fetch()
|
||||
ref.on 'sync', @modelLoaded
|
||||
ref.once 'sync', @modelLoaded, @
|
||||
|
||||
@trigger 'loaded-one', model: model
|
||||
@trigger 'loaded-all' if @finished()
|
||||
@removeEventsFromModel(model)
|
||||
|
||||
removeEventsFromModel: (model) ->
|
||||
model.off 'sync', @modelLoaded, @
|
||||
model.off 'error', @modelErrored, @
|
||||
|
||||
getModel: (ModelClass_or_url, id) ->
|
||||
return @getModelByURL(ModelClass_or_url) if _.isString(ModelClass_or_url)
|
||||
|
|
|
@ -28,7 +28,6 @@ module.exports = class User extends CocoModel
|
|||
profileUrl = "#{GRAVATAR_URL}#{emailHash}.json?callback=#{functionName}"
|
||||
script = $("<script src='#{profileUrl}' type='text/javascript'></script>")
|
||||
$('head').append(script)
|
||||
$('body').on('load',(e)->console.log('we did it!', e))
|
||||
window[functionName] = (profile) =>
|
||||
@gravatarProfile = profile
|
||||
@trigger('change', @)
|
||||
|
|
|
@ -81,9 +81,7 @@ module.exports = class ScriptsTabView extends View
|
|||
@selectedScriptPath = newPath
|
||||
|
||||
getThangIDs: ->
|
||||
ids = (t.id for t in @level.get('thangs') when t.id isnt 'Interface')
|
||||
ids = ['My Wizard', 'Captain Anya'].concat(ids)
|
||||
ids
|
||||
(t.id for t in @level.get('thangs') when t.id isnt 'Interface')
|
||||
|
||||
onScriptChanged: =>
|
||||
@scriptsTreema.set(@selectedScriptPath, @scriptTreema.data)
|
||||
|
|
|
@ -2,12 +2,13 @@ View = require 'views/kinds/CocoView'
|
|||
template = require 'templates/editor/level/settings_tab'
|
||||
Level = require 'models/Level'
|
||||
Surface = require 'lib/surface/Surface'
|
||||
nodes = require './treema_nodes'
|
||||
|
||||
module.exports = class SettingsTabView extends View
|
||||
id: 'editor-level-settings-tab-view'
|
||||
className: 'tab-pane'
|
||||
template: template
|
||||
editableSettings: ['name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon'] # not thangs or scripts or the backend stuff
|
||||
editableSettings: ['name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon', 'goals'] # not thangs or scripts or the backend stuff
|
||||
|
||||
subscriptions:
|
||||
'level-loaded': 'onLevelLoaded'
|
||||
|
@ -22,16 +23,24 @@ module.exports = class SettingsTabView extends View
|
|||
schema = _.cloneDeep Level.schema.attributes
|
||||
schema.properties = _.pick schema.properties, (value, key) => key in @editableSettings
|
||||
schema.required = _.intersection schema.required, @editableSettings
|
||||
thangIDs = @getThangIDs()
|
||||
treemaOptions =
|
||||
filePath: "db/level/#{@level.get('original')}"
|
||||
supermodel: @supermodel
|
||||
schema: schema
|
||||
data: data
|
||||
callbacks: {change: @onSettingsChanged}
|
||||
thangIDs: thangIDs
|
||||
nodeClasses:
|
||||
thang: nodes.ThangNode
|
||||
|
||||
@settingsTreema = @$el.find('#settings-treema').treema treemaOptions
|
||||
@settingsTreema.build()
|
||||
@settingsTreema.open()
|
||||
|
||||
getThangIDs: ->
|
||||
(t.id for t in @level.get('thangs') when t.id isnt 'Interface')
|
||||
|
||||
onSettingsChanged: (e) =>
|
||||
$('.level-title').text @settingsTreema.data.name
|
||||
for key in @editableSettings
|
||||
|
|
|
@ -42,6 +42,7 @@ module.exports = class CocoView extends Backbone.View
|
|||
@undelegateEvents() # removes both events and subs
|
||||
view.destroy() for id, view of @subviews
|
||||
@modalClosed = null
|
||||
$('#modal-wrapper .modal').off 'hidden.bs.modal', @modalClosed
|
||||
|
||||
afterInsert: ->
|
||||
|
||||
|
@ -85,14 +86,14 @@ module.exports = class CocoView extends Backbone.View
|
|||
|
||||
# Modals
|
||||
|
||||
toggleModal: (e) ->
|
||||
toggleModal: (e) ->
|
||||
if $(e.currentTarget).prop('target') is '_blank'
|
||||
return true
|
||||
# special handler for opening modals that are dynamically loaded, rather than static in the page. It works (or should work) like Bootstrap's modals, except use coco-modal for the data-toggle value.
|
||||
# special handler for opening modals that are dynamically loaded, rather than static in the page. It works (or should work) like Bootstrap's modals, except use coco-modal for the data-toggle value.
|
||||
elem = $(e.target)
|
||||
return unless elem.data('toggle') is 'coco-modal'
|
||||
target = elem.data('target')
|
||||
view = application.router.getView(target, '_modal') # could set up a system for loading cached modals, if told to
|
||||
view = application.router.getView(target, '_modal') # could set up a system for loading cached modals, if told to
|
||||
@openModalView(view)
|
||||
|
||||
openModalView: (modalView) ->
|
||||
|
@ -101,12 +102,12 @@ module.exports = class CocoView extends Backbone.View
|
|||
waitingModal = modalView
|
||||
visibleModal.hide()
|
||||
return
|
||||
modalView.render()
|
||||
modalView.render()
|
||||
$('#modal-wrapper').empty().append modalView.el
|
||||
modalView.afterInsert()
|
||||
visibleModal = modalView
|
||||
modalOptions = {show: true, backdrop: if modalView.closesOnClickOutside then true else 'static'}
|
||||
$('#modal-wrapper .modal').modal(modalOptions).on('hidden.bs.modal', @modalClosed)
|
||||
$('#modal-wrapper .modal').modal(modalOptions).on 'hidden.bs.modal', @modalClosed
|
||||
window.currentModal = modalView
|
||||
@getRootView().stopListeningToShortcuts(true)
|
||||
|
||||
|
@ -114,7 +115,8 @@ module.exports = class CocoView extends Backbone.View
|
|||
visibleModal.willDisappear() if visibleModal
|
||||
visibleModal.destroy()
|
||||
visibleModal = null
|
||||
if waitingModal
|
||||
$('#modal-wrapper .modal').off 'hidden.bs.modal', @modalClosed
|
||||
if waitingModal
|
||||
wm = waitingModal
|
||||
waitingModal = null
|
||||
@openModalView(wm)
|
||||
|
@ -212,8 +214,8 @@ module.exports = class CocoView extends Backbone.View
|
|||
slider.on('slide',changeCallback)
|
||||
slider.on('slidechange',changeCallback)
|
||||
slider
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mobileRELong = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i
|
||||
mobileREShort = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i
|
||||
|
|
|
@ -37,6 +37,7 @@ module.exports = class ControlBarView extends View
|
|||
setBus: (@bus) ->
|
||||
|
||||
onPlayerStatesChanged: (e) ->
|
||||
# TODO: this doesn't fire any more. Replacement?
|
||||
return unless @bus is e.bus
|
||||
numPlayers = _.keys(e.players).length
|
||||
return if numPlayers is @numPlayers
|
||||
|
|
|
@ -11,6 +11,8 @@ module.exports = class CastButtonView extends View
|
|||
'tome:cast-spells': 'onCastSpells'
|
||||
'god:world-load-progress-changed': 'onWorldLoadProgressChanged'
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
'click .cast-button': -> Backbone.Mediator.publish 'tome:manual-cast', {}
|
||||
'click .cast-options a': 'onCastOptionsClick'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
|
@ -26,8 +28,10 @@ module.exports = class CastButtonView extends View
|
|||
|
||||
afterRender: ->
|
||||
super()
|
||||
@castButton = $('.cast-button', @$el)
|
||||
@castButtonGroup = $('.cast-button-group', @$el)
|
||||
@castOptions = $('.autocast-delays', @$el)
|
||||
# TODO: use a User setting instead of localStorage
|
||||
@hookUpButtons()
|
||||
delay = localStorage.getItem 'autocastDelay'
|
||||
delay ?= 5000
|
||||
@setAutocastDelay delay
|
||||
|
@ -35,19 +39,11 @@ module.exports = class CastButtonView extends View
|
|||
attachTo: (spellView) ->
|
||||
@$el.detach().prependTo(spellView.toolbarView.$el).show()
|
||||
|
||||
hookUpButtons: ->
|
||||
# hook up cast button callbacks
|
||||
@castButton = $('.cast-button', @$el)
|
||||
@castButtonGroup = $('.cast-button-group', @$el)
|
||||
@castOptions = $('.autocast-delays', @$el)
|
||||
|
||||
@castButton.click (e) =>
|
||||
Backbone.Mediator.publish 'tome:manual-cast', {}
|
||||
@castOptions.find('a').click (e) =>
|
||||
Backbone.Mediator.publish 'focus-editor'
|
||||
@castButtonGroup.removeClass 'open'
|
||||
@setAutocastDelay $(e.target).attr 'data-delay'
|
||||
false
|
||||
onCastOptionsClick: (e) ->
|
||||
Backbone.Mediator.publish 'focus-editor'
|
||||
@castButtonGroup.removeClass 'open'
|
||||
@setAutocastDelay $(e.target).attr 'data-delay'
|
||||
false
|
||||
|
||||
onSpellChanged: (e) ->
|
||||
@updateCastButton()
|
||||
|
|
|
@ -60,7 +60,7 @@ module.exports = class DebugView extends View
|
|||
@variableChain = @markerRange = null
|
||||
@update()
|
||||
|
||||
onMouseOut: (e) =>
|
||||
onMouseOut: (e) ->
|
||||
@variableChain = @markerRange = null
|
||||
@update()
|
||||
|
||||
|
@ -138,3 +138,4 @@ module.exports = class DebugView extends View
|
|||
destroy: ->
|
||||
super()
|
||||
@ace?.removeEventListener "mousemove", @onMouseMove
|
||||
@onMouseMove = null
|
||||
|
|
|
@ -60,3 +60,4 @@ module.exports = class SpellPaletteView extends View
|
|||
destroy: ->
|
||||
super()
|
||||
entry.destroy() for entry in @entries
|
||||
@toggleBackground = null
|
||||
|
|
|
@ -74,47 +74,52 @@ module.exports = class SpellView extends View
|
|||
$(@ace.container).find('.ace_gutter').on 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
|
||||
|
||||
createACEShortcuts: ->
|
||||
@ace.commands.addCommand
|
||||
@aceCommands = aceCommands = []
|
||||
ace = @ace
|
||||
addCommand = (c) ->
|
||||
ace.commands.addCommand c
|
||||
aceCommands.push c.name
|
||||
addCommand
|
||||
name: 'run-code'
|
||||
bindKey: {win: 'Shift-Enter|Ctrl-Enter|Ctrl-S', mac: 'Shift-Enter|Command-Enter|Ctrl-Enter|Command-S|Ctrl-S'}
|
||||
exec: (e) => @recompile()
|
||||
@ace.commands.addCommand
|
||||
exec: -> Backbone.Mediator.publish 'tome:manual-cast', {}
|
||||
addCommand
|
||||
name: 'toggle-playing'
|
||||
bindKey: {win: 'Ctrl-P', mac: 'Command-P|Ctrl-P'}
|
||||
exec: -> Backbone.Mediator.publish 'level-toggle-playing'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'end-current-script'
|
||||
bindKey: {win: 'Shift-Space', mac: 'Shift-Space'}
|
||||
exec: -> Backbone.Mediator.publish 'level:shift-space-pressed'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'end-all-scripts'
|
||||
bindKey: {win: 'Escape', mac: 'Escape'}
|
||||
exec: -> Backbone.Mediator.publish 'level:escape-pressed'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'toggle-grid'
|
||||
bindKey: {win: 'Ctrl-G', mac: 'Command-G|Ctrl-G'}
|
||||
exec: -> Backbone.Mediator.publish 'level-toggle-grid'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'toggle-debug'
|
||||
bindKey: {win: 'Ctrl-\\', mac: 'Command-\\|Ctrl-\\'}
|
||||
exec: -> Backbone.Mediator.publish 'level-toggle-debug'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'toggle-pathfinding'
|
||||
bindKey: {win: 'Ctrl-O', mac: 'Command-O|Ctrl-O'}
|
||||
exec: -> Backbone.Mediator.publish 'level-toggle-pathfinding'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'level-scrub-forward'
|
||||
bindKey: {win: 'Ctrl-]', mac: 'Command-]|Ctrl-]'}
|
||||
exec: -> Backbone.Mediator.publish 'level-scrub-forward'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'level-scrub-back'
|
||||
bindKey: {win: 'Ctrl-[', mac: 'Command-[|Ctrl-]'}
|
||||
exec: -> Backbone.Mediator.publish 'level-scrub-back'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'spell-step-forward'
|
||||
bindKey: {win: 'Ctrl-Alt-]', mac: 'Command-Alt-]|Ctrl-Alt-]'}
|
||||
exec: -> Backbone.Mediator.publish 'spell-step-forward'
|
||||
@ace.commands.addCommand
|
||||
addCommand
|
||||
name: 'spell-step-backward'
|
||||
bindKey: {win: 'Ctrl-Alt-[', mac: 'Command-Alt-[|Ctrl-Alt-]'}
|
||||
exec: -> Backbone.Mediator.publish 'spell-step-backward'
|
||||
|
@ -212,7 +217,10 @@ module.exports = class SpellView extends View
|
|||
@updateACEText @spell.originalSource
|
||||
@recompile cast
|
||||
|
||||
recompile: (cast=true) =>
|
||||
recompileIfNeeded: =>
|
||||
@recompile() if @recompileNeeded
|
||||
|
||||
recompile: (cast=true) ->
|
||||
@setRecompileNeeded false
|
||||
return if @spell.source is @getSource()
|
||||
@spell.transpile @getSource()
|
||||
|
@ -238,7 +246,7 @@ module.exports = class SpellView extends View
|
|||
autocastDelay = @autocastDelay ? 3000
|
||||
onSignificantChange = [
|
||||
_.debounce @setRecompileNeeded, autocastDelay - 100
|
||||
@currentAutocastHandler = _.debounce (=> @recompile() if @recompileNeeded), autocastDelay
|
||||
@currentAutocastHandler = _.debounce @recompileIfNeeded, autocastDelay
|
||||
]
|
||||
onAnyChange = [
|
||||
_.debounce @updateAether, 500
|
||||
|
@ -500,9 +508,17 @@ module.exports = class SpellView extends View
|
|||
|
||||
destroy: ->
|
||||
super()
|
||||
$(@ace?.container).find('.ace_gutter').off 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
|
||||
@firepad?.dispose()
|
||||
@ace.destroy()
|
||||
@ace?.commands.removeCommand command for command in @aceCommands
|
||||
@ace?.destroy()
|
||||
@ace = null
|
||||
@aceDoc?.off 'change', @onCodeChangeMetaHandler
|
||||
@aceDoc = null
|
||||
@aceSession?.selection.off 'changeCursor', @onCursorActivity
|
||||
@aceSession = null
|
||||
@debugView?.destroy()
|
||||
@spell = null
|
||||
@session.off 'change:multiplayer', @onMultiplayerChanged, @
|
||||
for fat in ['notifySpellChanged', 'notifyEditingEnded', 'notifyEditingBegan', 'onFirepadLoaded', 'onLoaded', 'toggleBackground', 'setRecompileNeeded', 'onCursorActivity', 'highlightCurrentLine', 'updateAether', 'onCodeChangeMetaHandler', 'recompileIfNeeded', 'currentAutocastHandler']
|
||||
@[fat] = null
|
||||
|
|
|
@ -97,12 +97,12 @@ module.exports = class ThangListEntryView extends View
|
|||
@$el.popover('setContent').popover('show')
|
||||
@$el.parent().parent().parent().i18n()
|
||||
clearTimeout @hideSpellsTimeout if @hideSpellsTimeout
|
||||
popover = @$el.parent().parent().parent().find('.popover')
|
||||
popover.off 'mouseenter mouseleave'
|
||||
popover.mouseenter (e) => @onMouseEnter()
|
||||
popover.mouseleave (e) => @onMouseLeave()
|
||||
@popover = @$el.parent().parent().parent().find('.popover')
|
||||
@popover.off 'mouseenter mouseleave'
|
||||
@popover.mouseenter (e) => @onMouseEnter()
|
||||
@popover.mouseleave (e) => @onMouseLeave()
|
||||
thangID = @thang.id
|
||||
popover.find('code').click (e) ->
|
||||
@popover.find('code').click (e) ->
|
||||
Backbone.Mediator.publish "level-select-sprite", thangID: thangID, spellName: $(@).data 'spell-name'
|
||||
|
||||
hideSpells: =>
|
||||
|
@ -139,3 +139,5 @@ module.exports = class ThangListEntryView extends View
|
|||
destroy: ->
|
||||
super()
|
||||
@avatar?.destroy()
|
||||
@popover?.off 'mouseenter mouseleave'
|
||||
@popover?.find('code').off 'click'
|
||||
|
|
|
@ -76,9 +76,7 @@ module.exports = class PlayLevelView extends View
|
|||
@sessionID = @getQueryVariable 'session'
|
||||
|
||||
$(window).on('resize', @onWindowResize)
|
||||
@supermodel.once 'error', =>
|
||||
msg = $.i18n.t('play_level.level_load_error', defaultValue: "Level could not be loaded.")
|
||||
@$el.html('<div class="alert">' + msg + '</div>')
|
||||
@supermodel.once 'error', @onLevelLoadError
|
||||
@saveScreenshot = _.throttle @saveScreenshot, 30000
|
||||
|
||||
if @isEditorPreview
|
||||
|
@ -94,6 +92,10 @@ module.exports = class PlayLevelView extends View
|
|||
if localStorage?
|
||||
localStorage["lastLevel"] = @levelID
|
||||
|
||||
onLevelLoadError: (e) =>
|
||||
msg = $.i18n.t('play_level.level_load_error', defaultValue: "Level could not be loaded.")
|
||||
@$el.html('<div class="alert">' + msg + '</div>')
|
||||
|
||||
setLevel: (@level, @supermodel) ->
|
||||
@god?.level = @level.serialize @supermodel
|
||||
if @world
|
||||
|
@ -181,21 +183,21 @@ module.exports = class PlayLevelView extends View
|
|||
onWindowResize: (s...) ->
|
||||
$('#pointer').css('opacity', 0.0)
|
||||
|
||||
onDisableControls: (e) =>
|
||||
onDisableControls: (e) ->
|
||||
return if e.controls and not ('level' in e.controls)
|
||||
@shortcutsEnabled = false
|
||||
@wasFocusedOn = document.activeElement
|
||||
$('body').focus()
|
||||
|
||||
onEnableControls: (e) =>
|
||||
onEnableControls: (e) ->
|
||||
return if e.controls? and not ('level' in e.controls)
|
||||
@shortcutsEnabled = true
|
||||
$(@wasFocusedOn).focus() if @wasFocusedOn
|
||||
@wasFocusedOn = null
|
||||
|
||||
onDonePressed: => @showVictory()
|
||||
onDonePressed: -> @showVictory()
|
||||
|
||||
onShowVictory: (e) =>
|
||||
onShowVictory: (e) ->
|
||||
console.log 'show vict', e
|
||||
$('#level-done-button').show()
|
||||
@showVictory() if e.showModal
|
||||
|
@ -221,7 +223,7 @@ module.exports = class PlayLevelView extends View
|
|||
@openModalView new InfiniteLoopModal()
|
||||
window.tracker?.trackEvent 'Saw Initial Infinite Loop', level: @world.name, label: @world.name
|
||||
|
||||
onPlayNextLevel: =>
|
||||
onPlayNextLevel: ->
|
||||
nextLevel = @getNextLevel()
|
||||
nextLevelID = nextLevel.get('slug') or nextLevel.id
|
||||
url = "/play/level/#{nextLevelID}"
|
||||
|
@ -235,7 +237,7 @@ module.exports = class PlayLevelView extends View
|
|||
levels = @supermodel.getModels(Level)
|
||||
return l for l in levels when l.get('original') is nextLevelOriginal
|
||||
|
||||
onHighlightDom: (e) =>
|
||||
onHighlightDom: (e) ->
|
||||
if e.delay
|
||||
delay = e.delay
|
||||
delete e.delay
|
||||
|
@ -289,16 +291,16 @@ module.exports = class PlayLevelView extends View
|
|||
), 1)
|
||||
|
||||
|
||||
animatePointer: =>
|
||||
animatePointer: ->
|
||||
pointer = $('#pointer')
|
||||
pointer.css('transition', 'all 0.6s ease-out')
|
||||
pointer.css('transform', "rotate(#{@pointerRotation}rad) translate(-3px, #{@pointerRadialDistance-50}px)")
|
||||
setTimeout((=>
|
||||
pointer.css('transform', "rotate(#{@pointerRotation}rad) translate(-3px, #{@pointerRadialDistance}px)").css('transition', 'all 0.4s ease-in')), 800)
|
||||
|
||||
onFocusDom: (e) => $(e.selector).focus()
|
||||
onFocusDom: (e) -> $(e.selector).focus()
|
||||
|
||||
onEndHighlight: =>
|
||||
onEndHighlight: ->
|
||||
$('#pointer').css('opacity', 0.0)
|
||||
clearInterval(@pointerInterval)
|
||||
|
||||
|
@ -380,6 +382,8 @@ module.exports = class PlayLevelView extends View
|
|||
|
||||
destroy: ->
|
||||
super()
|
||||
@supermodel.off 'error', @onLevelLoadError
|
||||
@levelLoader?.off 'loaded-all', @onLevelLoaderLoaded
|
||||
@levelLoader?.destroy()
|
||||
@surface?.destroy()
|
||||
@god?.destroy()
|
||||
|
@ -393,3 +397,8 @@ module.exports = class PlayLevelView extends View
|
|||
#@instance.save() unless @instance.loading
|
||||
console.profileEnd?() if PROFILE_ME
|
||||
@session.off 'change:multiplayer', @onMultiplayerChanged, @
|
||||
@onLevelLoadError = null
|
||||
@onLevelLoaderLoaded = null
|
||||
@onSupermodelLoadedOne = null
|
||||
@preloadNextLevel = null
|
||||
@saveScreenshot = null
|
||||
|
|
|
@ -44,7 +44,9 @@ function checkNodeVersion {
|
|||
|
||||
checkDependencies deps[@] basicDependenciesErrorHandling
|
||||
#check for node
|
||||
checkNodeVersion
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
checkNodeVersion
|
||||
fi
|
||||
#install git repository
|
||||
git clone $repositoryUrl coco
|
||||
#python ./coco/scripts/devSetup/setup.py
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
from __future__ import print_function
|
||||
__author__ = 'schmatz'
|
||||
from configuration import Configuration
|
||||
import urllib
|
||||
import sys
|
||||
if sys.version_info.major < 3:
|
||||
import urllib
|
||||
else:
|
||||
import urllib.request as urllib
|
||||
from dependency import Dependency
|
||||
class Downloader:
|
||||
def __init__(self,dependency):
|
||||
|
@ -27,10 +32,10 @@ class Downloader:
|
|||
progress_fraction = float(amount_of_data_downloaded_so_far) / float(totalsize)
|
||||
progress_percentage = progress_fraction * 1e2
|
||||
stringToDisplay = '\r[{0}] {1:.1f}%'.format('#'*int(bars_to_display*progress_fraction),progress_percentage)
|
||||
print stringToDisplay,
|
||||
print(stringToDisplay,end=' ')
|
||||
if amount_of_data_downloaded_so_far >= totalsize:
|
||||
print "\n",
|
||||
print("\n",end=' ')
|
||||
else:
|
||||
stringToDisplay = '\r File size unknown. Read {0} bytes.'.format(amount_of_data_downloaded_so_far)
|
||||
print stringToDisplay,
|
||||
print(stringToDisplay,end=' ')
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import print_function
|
||||
__author__ = u'schmatz'
|
||||
from downloader import Downloader
|
||||
import tarfile
|
||||
|
@ -6,6 +7,8 @@ import warnings
|
|||
import os
|
||||
from configuration import Configuration
|
||||
from dependency import Dependency
|
||||
import sys
|
||||
|
||||
|
||||
class MongoDB(Dependency):
|
||||
def __init__(self,configuration):
|
||||
|
@ -39,7 +42,7 @@ class MongoDB(Dependency):
|
|||
|
||||
def findUnzippedMongoBinPath(self):
|
||||
return self.downloader.download_directory + os.sep + \
|
||||
(os.walk(self.downloader.download_directory).next()[1])[0] + os.sep + u"bin"
|
||||
(next(os.walk(self.downloader.download_directory))[1])[0] + os.sep + u"bin"
|
||||
|
||||
|
||||
|
||||
|
@ -55,15 +58,15 @@ class MongoDBDownloader(Downloader):
|
|||
def downloaded_file_path(self):
|
||||
return self.download_directory + os.sep + u"mongodb.tgz"
|
||||
def download(self):
|
||||
print u"Downloading MongoDB from URL " + self.download_url
|
||||
print(u"Downloading MongoDB from URL " + self.download_url)
|
||||
self.download_file(self.download_url,self.downloaded_file_path)
|
||||
self.check_download()
|
||||
def decompress(self):
|
||||
print u"Decompressing MongoDB..."
|
||||
print(u"Decompressing MongoDB...")
|
||||
tfile = tarfile.open(self.downloaded_file_path)
|
||||
#TODO: make directory handler class
|
||||
tfile.extractall(self.download_directory)
|
||||
print u"Decompressed MongoDB into " + self.download_directory
|
||||
print(u"Decompressed MongoDB into " + self.download_directory)
|
||||
|
||||
def check_download(self):
|
||||
isFileValid = tarfile.is_tarfile(self.downloaded_file_path)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import print_function
|
||||
__author__ = u'schmatz'
|
||||
from downloader import Downloader
|
||||
import tarfile
|
||||
|
@ -10,6 +11,12 @@ from dependency import Dependency
|
|||
import shutil
|
||||
from which import which
|
||||
import subprocess
|
||||
from stat import S_IRWXU,S_IRWXG,S_IRWXO
|
||||
import sys
|
||||
|
||||
if sys.version_info.major >= 3:
|
||||
raw_input = input
|
||||
|
||||
class Node(Dependency):
|
||||
def __init__(self,configuration):
|
||||
super(self.__class__, self).__init__(configuration)
|
||||
|
@ -39,39 +46,42 @@ class Node(Dependency):
|
|||
#check for node here
|
||||
unzipped_node_path = self.findUnzippedNodePath()
|
||||
if self.config.system.operating_system in ["mac","linux"] and not which("node"):
|
||||
print "Copying node into /usr/local/bin/..."
|
||||
print("Copying node into /usr/local/bin/...")
|
||||
shutil.copy(unzipped_node_path + os.sep + "bin" + os.sep + "node","/usr/local/bin/")
|
||||
os.chmod("/usr/local/bin/node",0777)
|
||||
os.chmod("/usr/local/bin/node",S_IRWXG|S_IRWXO|S_IRWXU)
|
||||
shutil.copytree(self.findUnzippedNodePath(),install_directory)
|
||||
wants_to_upgrade = True
|
||||
if self.check_if_executable_installed(u"npm"):
|
||||
warning_string = u"A previous version of npm has been found. \nYou may experience problems if you have a version of npm that's too old.Would you like to upgrade?(y/n) "
|
||||
from distutils.util import strtobool
|
||||
print warning_string
|
||||
print(warning_string)
|
||||
#for bash script, you have to somehow redirect stdin to raw_input()
|
||||
user_input = raw_input()
|
||||
while True:
|
||||
try:
|
||||
wants_to_upgrade = strtobool(user_input)
|
||||
except:
|
||||
print u"Please enter y or n. "
|
||||
print(u"Please enter y or n. ")
|
||||
user_input = raw_input()
|
||||
continue
|
||||
break
|
||||
if wants_to_upgrade:
|
||||
import urllib2, urllib
|
||||
print u"Retrieving npm update script..."
|
||||
if sys.version_info.major < 3:
|
||||
import urllib2, urllib
|
||||
else:
|
||||
import urllib.request as urllib
|
||||
print(u"Retrieving npm update script...")
|
||||
npm_install_script_path = install_directory + os.sep + u"install.sh"
|
||||
urllib.urlretrieve(u"https://npmjs.org/install.sh",filename=npm_install_script_path)
|
||||
print u"Retrieved npm install script. Executing..."
|
||||
print(u"Retrieved npm install script. Executing...")
|
||||
subprocess.call([u"sh", npm_install_script_path])
|
||||
print u"Updated npm version installed"
|
||||
print(u"Updated npm version installed")
|
||||
|
||||
|
||||
|
||||
def findUnzippedNodePath(self):
|
||||
return self.downloader.download_directory + os.sep + \
|
||||
(os.walk(self.downloader.download_directory).next()[1])[0]
|
||||
(next(os.walk(self.downloader.download_directory))[1])[0]
|
||||
def check_if_executable_installed(self,name):
|
||||
executable_path = which(name)
|
||||
if executable_path:
|
||||
|
@ -98,15 +108,15 @@ class NodeDownloader(Downloader):
|
|||
def downloaded_file_path(self):
|
||||
return self.download_directory + os.sep + u"node.tgz"
|
||||
def download(self):
|
||||
print u"Downloading Node from URL " + self.download_url
|
||||
print(u"Downloading Node from URL " + self.download_url)
|
||||
self.download_file(self.download_url,self.downloaded_file_path)
|
||||
self.check_download()
|
||||
def decompress(self):
|
||||
print u"Decompressing Node..."
|
||||
print(u"Decompressing Node...")
|
||||
tfile = tarfile.open(self.downloaded_file_path)
|
||||
#TODO: make directory handler class
|
||||
tfile.extractall(self.download_directory)
|
||||
print u"Decompressed Node into " + self.download_directory
|
||||
print(u"Decompressed Node into " + self.download_directory)
|
||||
|
||||
def check_download(self):
|
||||
isFileValid = tarfile.is_tarfile(self.downloaded_file_path)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import print_function
|
||||
__author__ = u'schmatz'
|
||||
import configuration
|
||||
import errors
|
||||
|
@ -36,11 +37,11 @@ class RepositoryInstaller():
|
|||
else:
|
||||
return False
|
||||
def cloneRepository(self):
|
||||
print u"Cloning repository..."
|
||||
print(u"Cloning repository...")
|
||||
#TODO: CHANGE THIS BEFORE LAUNCH
|
||||
return_code = True
|
||||
git_folder = self.config.directory.root_install_directory + os.sep + "coco"
|
||||
print "Installing into " + git_folder
|
||||
print("Installing into " + git_folder)
|
||||
return_code = subprocess.call("git clone " + self.config.repository_url +" coco",cwd=self.config.directory.root_install_directory,shell=True)
|
||||
#TODO: remove this on windos
|
||||
subprocess.call("chown -R " +git_folder + " 0777",shell=True)
|
||||
|
@ -51,15 +52,15 @@ class RepositoryInstaller():
|
|||
#sys.stdout.flush()
|
||||
raw_input(u"Copy it now")
|
||||
#shutil.copytree(u"/Users/schmatz/coco",self.config.directory.root_install_directory + os.sep + u"coco")
|
||||
print u"Copied tree just for you"
|
||||
print(u"Copied tree just for you")
|
||||
#print("FAILED TO CLONE GIT REPOSITORY")
|
||||
#input("Clone the repository and click any button to continue")
|
||||
elif self.config.system.operating_system == u"windows":
|
||||
raise errors.CoCoError(u"Windows doesn't support automated installations of npm at this point.")
|
||||
else:
|
||||
print u"Cloned git repository"
|
||||
print(u"Cloned git repository")
|
||||
def install_node_packages(self):
|
||||
print u"Installing node packages..."
|
||||
print(u"Installing node packages...")
|
||||
#TODO: "Replace npm with more robust package
|
||||
#npm_location = self.config.directory.bin_directory + os.sep + "node" + os.sep + "bin" + os.sep + "npm"
|
||||
npm_location = u"npm"
|
||||
|
@ -67,4 +68,4 @@ class RepositoryInstaller():
|
|||
if return_code:
|
||||
raise errors.CoCoError(u"Failed to install node packages")
|
||||
else:
|
||||
print u"Installed node packages!"
|
||||
print(u"Installed node packages!")
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import print_function
|
||||
__author__ = u'root'
|
||||
|
||||
import dependency
|
||||
|
@ -18,7 +19,7 @@ class Ruby(dependency.Dependency):
|
|||
elif not is_ruby_installed:
|
||||
self.install_ruby()
|
||||
elif is_ruby_installed and is_gem_installed:
|
||||
print u"Ruby found."
|
||||
print(u"Ruby found.")
|
||||
def check_if_ruby_exists(self):
|
||||
ruby_path = which(u"ruby")
|
||||
return bool(ruby_path)
|
||||
|
@ -38,4 +39,4 @@ class Ruby(dependency.Dependency):
|
|||
raise NotImplementedError
|
||||
|
||||
def install_gems(self):
|
||||
gem_install_status = subprocess.call([u"gem",u"install",u"sass"])
|
||||
gem_install_status = subprocess.call([u"gem",u"install",u"sass"])
|
||||
|
|
|
@ -22,7 +22,10 @@ class SystemConfiguration(object):
|
|||
raise NotSupportedError(u"Your platform," + sys.platform + u",isn't supported.")
|
||||
|
||||
def get_current_working_directory(self):
|
||||
return os.getcwdu()
|
||||
if sys.version_info.major < 3:
|
||||
return os.getcwdu()
|
||||
else:
|
||||
return os.getcwd()
|
||||
|
||||
def get_virtual_memory_address_width(self):
|
||||
is64Bit = sys.maxsize/3 > 2**32
|
||||
|
|
|
@ -223,6 +223,7 @@ _.extend LevelSchema.properties,
|
|||
victory: c.object {title: "Victory Screen", default: {}, properties: {'body': {type: 'string', format: 'markdown', title: 'Body Text', description: 'Inserted into the Victory Modal once this level is complete. Tell the player they did a good job and what they accomplished!'}, i18n: {type: "object", format: 'i18n', props: ['body'], description: "Help translate this victory message"}}}
|
||||
i18n: {type: "object", format: 'i18n', props: ['name', 'description'], description: "Help translate this level"}
|
||||
icon: { type: 'string', format: 'image-file', title: 'Icon' }
|
||||
goals: c.array {title: 'Goals', description: 'An array of goals which are visible to the player and can trigger scripts.'}, GoalSchema
|
||||
|
||||
|
||||
c.extendBasicProperties LevelSchema, 'level'
|
||||
|
|
Loading…
Reference in a new issue