|
@ -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).
|
||||
|
|
36
README.md
|
@ -19,3 +19,39 @@ Whether you're novice or pro, the CodeCombat team is ready to help you implement
|
|||
### [License](https://github.com/codecombat/codecombat/blob/master/LICENSE)
|
||||
|
||||
[MIT](https://github.com/codecombat/codecombat/blob/master/LICENSE) for the code, and [CC-BY](http://codecombat.com/legal) for the art and music. Please also [sign the CodeCombat contributor license agreement](http://codecombat.com/cla) so we can accept your pull requests. It is easy.
|
||||
|
||||
### [Join Us!](http://blog.codecombat.com/why-you-should-open-source-your-startup)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
----------
|
||||
|
||||
[](http://codecombat.challengepost.com/?utm_source-github&utm_medium-oswidget&utm_campaign-codecombat)
|
||||
|
||||
[](http://www.google-melange.com/gsoc/homepage/google/gsoc2014)
|
|
@ -20,7 +20,7 @@ elementAcceptsKeystrokes = (el) ->
|
|||
# not radio, checkbox, range, or color
|
||||
return (tag is 'textarea' or (tag is 'input' and type in textInputTypes) or el.contentEditable in ["", "true"]) and not (el.readOnly or el.disabled)
|
||||
|
||||
COMMON_FILES = ['/images/modal_background.png', '/images/level/code_palette_background.png']
|
||||
COMMON_FILES = ['/images/pages/base/modal_background.png', '/images/level/code_palette_background.png']
|
||||
preload = (arrayOfImages) ->
|
||||
$(arrayOfImages).each ->
|
||||
$('<img/>')[0].src = @
|
||||
|
|
BIN
app/assets/images/level/prop_gold.png
Normal file
After ![]() (image error) Size: 5.2 KiB |
BIN
app/assets/images/level/victory.png
Normal file
After ![]() (image error) Size: 138 KiB |
Before ![]() (image error) Size: 8.2 KiB |
BIN
app/assets/images/pages/about/george_small.png
Normal file
After ![]() (image error) Size: 10 KiB |
Before ![]() (image error) Size: 3.4 KiB |
BIN
app/assets/images/pages/about/jeremy_small.png
Normal file
After ![]() (image error) Size: 12 KiB |
Before ![]() (image error) Size: 2.7 KiB |
BIN
app/assets/images/pages/about/michael_small.png
Normal file
After ![]() (image error) Size: 9.2 KiB |
Before ![]() (image error) Size: 7.8 KiB |
BIN
app/assets/images/pages/about/nick_small.png
Normal file
After ![]() (image error) Size: 11 KiB |
Before ![]() (image error) Size: 7.2 KiB |
BIN
app/assets/images/pages/about/scott_small.png
Normal file
After ![]() (image error) Size: 12 KiB |
BIN
app/assets/images/pages/contribute/archmage/alex_small.png
Normal file
After ![]() (image error) Size: 7.9 KiB |
BIN
app/assets/images/pages/contribute/archmage/becca_small.png
Normal file
After ![]() (image error) Size: 7.7 KiB |
BIN
app/assets/images/pages/contribute/archmage/ben_small.png
Normal file
After ![]() (image error) Size: 8.9 KiB |
BIN
app/assets/images/pages/contribute/archmage/brad_small.png
Normal file
After ![]() (image error) Size: 9.6 KiB |
BIN
app/assets/images/pages/contribute/archmage/chloe_small.png
Normal file
After ![]() (image error) Size: 6.6 KiB |
BIN
app/assets/images/pages/contribute/archmage/dan_small.png
Normal file
After ![]() (image error) Size: 8.6 KiB |
BIN
app/assets/images/pages/contribute/archmage/deepak_small.png
Normal file
After ![]() (image error) Size: 7.6 KiB |
BIN
app/assets/images/pages/contribute/archmage/glen_small.png
Normal file
After ![]() (image error) Size: 12 KiB |
BIN
app/assets/images/pages/contribute/archmage/ken_small.png
Normal file
After ![]() (image error) Size: 10 KiB |
BIN
app/assets/images/pages/contribute/archmage/laura_small.png
Normal file
After ![]() (image error) Size: 8.3 KiB |
BIN
app/assets/images/pages/contribute/archmage/mischa_small.png
Normal file
After ![]() (image error) Size: 6.6 KiB |
BIN
app/assets/images/pages/contribute/archmage/paul_small.png
Normal file
After ![]() (image error) Size: 8.4 KiB |
BIN
app/assets/images/pages/contribute/archmage/rachel_small.png
Normal file
After ![]() (image error) Size: 8.6 KiB |
BIN
app/assets/images/pages/contribute/archmage/ronald_small.png
Normal file
After ![]() (image error) Size: 9.2 KiB |
BIN
app/assets/images/pages/contribute/archmage/sebastien_small.png
Normal file
After ![]() (image error) Size: 8.1 KiB |
BIN
app/assets/images/pages/contribute/archmage/shiying_small.png
Normal file
After ![]() (image error) Size: 8.7 KiB |
BIN
app/assets/images/pages/contribute/archmage/tom_small.png
Normal file
After ![]() (image error) Size: 9.4 KiB |
BIN
app/assets/images/pages/contribute/artisan/andrew_small.png
Normal file
After ![]() (image error) Size: 8.6 KiB |
BIN
app/assets/images/pages/contribute/artisan/axandre_small.png
Normal file
After ![]() (image error) Size: 8.9 KiB |
BIN
app/assets/images/pages/contribute/artisan/derek_small.png
Normal file
After ![]() (image error) Size: 9.7 KiB |
BIN
app/assets/images/pages/contribute/artisan/katharine_small.png
Normal file
After ![]() (image error) Size: 9.2 KiB |
BIN
app/assets/images/pages/contribute/artisan/rob_small.png
Normal file
After ![]() (image error) Size: 7.1 KiB |
BIN
app/assets/images/pages/not_found/404_1.png
Normal file
After ![]() (image error) Size: 48 KiB |
BIN
app/assets/images/pages/not_found/404_2.png
Normal file
After ![]() (image error) Size: 54 KiB |
BIN
app/assets/images/pages/not_found/404_3.png
Normal file
After ![]() (image error) Size: 99 KiB |
2
app/assets/javascripts/workers/catiline_worker_shim.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
self._noTransferable = true;
|
||||
self.onmessage = function(e) { eval(e.data); };
|
|
@ -1,140 +0,0 @@
|
|||
|
||||
throw "Attempt to load worker_world into main window instead of web worker." if not self.importScripts or not window?
|
||||
|
||||
self.window = self
|
||||
self.workerID = "Worker"
|
||||
|
||||
self.logLimit = 200
|
||||
self.logsLogged = 0
|
||||
console =
|
||||
log: ->
|
||||
self.logsLogged += 1
|
||||
if self.logsLogged is self.logLimit
|
||||
self.postMessage
|
||||
type: 'console-log'
|
||||
args: ["Log limit " + self.logLimit + " reached; shutting up."]
|
||||
id: self.workerID
|
||||
else if self.logsLogged < self.logLimit
|
||||
args = [].slice.call arguments
|
||||
for arg in args
|
||||
if arg and arg.constructor and (arg.constructor.className is "Thang" or arg.isComponent)
|
||||
arg = arg.toString()
|
||||
|
||||
try
|
||||
self.postMessage
|
||||
type: 'console-log'
|
||||
args: args
|
||||
id: self.workerID
|
||||
|
||||
catch error
|
||||
self.postMessage
|
||||
type: 'console-log'
|
||||
args: ["Could not post log: " + args, error.toString(), error.stack, error.stackTrace]
|
||||
id: self.workerID
|
||||
|
||||
|
||||
console.error = console.info = console.log
|
||||
self.console = console
|
||||
|
||||
importScripts '/javascripts/world.js'
|
||||
|
||||
|
||||
self.transferableSupported = transferableSupported = ->
|
||||
try
|
||||
ab = new ArrayBuffer 1
|
||||
worker.postMessage ab, [ab]
|
||||
return ab.byteLength is 0
|
||||
catch error
|
||||
return false
|
||||
return false
|
||||
|
||||
|
||||
World = self.require 'lib/world/world'
|
||||
GoalManager = self.require 'lib/world/GoalManager'
|
||||
|
||||
self.runWorld = runWorld = (args) ->
|
||||
self.postedErrors = {}
|
||||
self.t0 = new Date()
|
||||
self.firstWorld = args.firstWorld
|
||||
self.postedErrors = false
|
||||
self.logsLogged = 0
|
||||
|
||||
try
|
||||
self.world = new World args.worldName, args.userCodeMap
|
||||
if args.level
|
||||
self.world.loadFromLevel args.level, true
|
||||
self.goalManager = new GoalManager self.world
|
||||
self.goalManager.setGoals args.goals
|
||||
self.goalManager.setCode args.userCodeMap
|
||||
self.goalManager.worldGenerationWillBegin()
|
||||
self.world.setGoalManager self.goalManager
|
||||
catch error
|
||||
self.onWorldError error
|
||||
return
|
||||
Math.random = self.world.rand.randf
|
||||
self.world.loadFrames self.onWorldLoaded, self.onWorldError, self.onWorldLoadProgress
|
||||
|
||||
self.onWorldLoaded = onWorldLoaded = () ->
|
||||
self.goalManager.worldGenerationEnded()
|
||||
t1 = new Date()
|
||||
diff = t1 - self.t0
|
||||
transferableSupported = self.transferableSupported()
|
||||
try
|
||||
serialized = self.world.serialize()
|
||||
catch error
|
||||
console.log "World serialization error:", error.toString() + "\n" + error.stack or error.stackTrace
|
||||
|
||||
|
||||
t2 = new Date()
|
||||
|
||||
try
|
||||
if transferableSupported
|
||||
self.postMessage(
|
||||
type: 'new-world'
|
||||
serialized: serialized.serializedWorld
|
||||
goalStates: self.goalManager.getGoalStates()
|
||||
, serialized.transferableObjects)
|
||||
else
|
||||
self.postMessage
|
||||
type: 'new-world'
|
||||
serialized: serialized.serializedWorld
|
||||
goalStates: self.goalManager.getGoalStates()
|
||||
catch error
|
||||
console.log "World delivery error:", error.toString + "\n" + error.stack or error.stackTrace
|
||||
t3 = new Date()
|
||||
console.log "And it was so: (" + (diff / self.world.totalFrames).toFixed(3) + "ms per frame,", self.world.totalFrames, "frames)\nSimulation :"
|
||||
self.world = null
|
||||
|
||||
self.onWorldError = onWorldError = (error) ->
|
||||
if error instanceof Aether.problems.UserCodeProblem
|
||||
unless self.postedErrors[error.key]
|
||||
problem = error.serialize()
|
||||
self.postMessage
|
||||
type: 'user-code-problem'
|
||||
problem: problem
|
||||
self.postedErrors[error.key] = problem
|
||||
|
||||
else
|
||||
console.log "Non-UserCodeError:", error.toString() + "\n" + error.stack or error.stackTrace
|
||||
return true
|
||||
|
||||
self.onWorldLoadProgress = onWorldLoadProgress = (progress) ->
|
||||
self.postMessage
|
||||
type: 'world-load-progress-changed'
|
||||
progress: progress
|
||||
|
||||
self.abort = abort = ->
|
||||
if self.world and self.world.name
|
||||
console.log "About to abort:", self.world.name, typeof self.world.abort
|
||||
self.world?.abort()
|
||||
self.world = null
|
||||
|
||||
self.postMessage
|
||||
type: 'abort'
|
||||
|
||||
self.reportIn = reportIn = ->
|
||||
self.postMessage
|
||||
type: 'reportIn'
|
||||
|
||||
self.addEventListener 'message', (event) ->
|
||||
self[event.data.func](event.data.args)
|
|
@ -35,13 +35,6 @@ console.error = console.info = console.log;
|
|||
self.console = console;
|
||||
|
||||
importScripts('/javascripts/world.js');
|
||||
// Since this is run synchronously on the main thread, we might consider splitting it up and sending "ready":
|
||||
//xhr.onload = function() {
|
||||
// eval(this.responseText);
|
||||
// postMessage("ready");
|
||||
//};
|
||||
//xhr.open("get", "script.js");
|
||||
//xhr.send();
|
||||
|
||||
// We could do way more from this: http://stackoverflow.com/questions/10653809/making-webworkers-a-safe-environment
|
||||
Object.defineProperty(self, "XMLHttpRequest", {
|
||||
|
@ -158,3 +151,4 @@ self.addEventListener('message', function(event) {
|
|||
self[event.data.func](event.data.args);
|
||||
});
|
||||
|
||||
self.postMessage({type: 'worker-initialized'});
|
||||
|
|
11
app/collections/LeaderboardCollection.coffee
Normal file
|
@ -0,0 +1,11 @@
|
|||
CocoCollection = require 'models/CocoCollection'
|
||||
LevelSession = require 'models/LevelSession'
|
||||
|
||||
module.exports = class LeaderboardCollection extends CocoCollection
|
||||
url: ''
|
||||
model: LevelSession
|
||||
|
||||
constructor: (level, options) ->
|
||||
super()
|
||||
options ?= {}
|
||||
@url = "/db/level/#{level.get('original')}.#{level.get('version').major}/leaderboard?#{$.param(options)}"
|
|
@ -1,14 +1,24 @@
|
|||
app = require 'application'
|
||||
auth = require 'lib/auth'
|
||||
|
||||
$ ->
|
||||
init = ->
|
||||
app.initialize()
|
||||
Backbone.history.start({ pushState: true })
|
||||
handleNormalUrls()
|
||||
|
||||
|
||||
treemaExt = require 'treema-ext'
|
||||
treemaExt.setup()
|
||||
filepicker.setKey('AvlkNoldcTOU4PvKi2Xm7z')
|
||||
|
||||
$ ->
|
||||
# Make sure we're "logged in" first.
|
||||
if auth.me.id
|
||||
init()
|
||||
else
|
||||
Backbone.Mediator.subscribeOnce 'me:synced', init
|
||||
|
||||
window.init = init
|
||||
|
||||
handleNormalUrls = ->
|
||||
# http://artsy.github.com/blog/2012/06/25/replacing-hashbang-routes-with-pushstate/
|
||||
$(document).on "click", "a[href^='/']", (event) ->
|
||||
|
|
|
@ -33,7 +33,7 @@ class Media
|
|||
|
||||
class AudioPlayer extends CocoClass
|
||||
subscriptions:
|
||||
'play-sound': (e) -> @playInterfaceSound e.trigger
|
||||
'play-sound': (e) -> @playInterfaceSound e.trigger, e.volume
|
||||
|
||||
constructor: () ->
|
||||
super()
|
||||
|
@ -70,17 +70,17 @@ class AudioPlayer extends CocoClass
|
|||
filename = "/file/interface/#{name}#{@ext}"
|
||||
@preloadSound filename, name
|
||||
|
||||
playInterfaceSound: (name) ->
|
||||
playInterfaceSound: (name, volume=1) ->
|
||||
filename = "/file/interface/#{name}#{@ext}"
|
||||
if filename of cache and createjs.Sound.loadComplete filename
|
||||
@playSound name
|
||||
createjs.Sound.play name
|
||||
@playSound name, volume
|
||||
else
|
||||
@preloadInterfaceSounds [name] unless filename of cache
|
||||
@soundsToPlayWhenLoaded[name] = true
|
||||
|
||||
playSound: (name) ->
|
||||
createjs.Sound.play name, {volume: me.get('volume')}
|
||||
@soundsToPlayWhenLoaded[name] = volume
|
||||
|
||||
playSound: (name, volume=1, delay=0) ->
|
||||
instance = createjs.Sound.play name, {volume: (me.get('volume') ? 1) * volume, delay: delay}
|
||||
instance
|
||||
|
||||
# # TODO: load Interface sounds somehow, somewhere, somewhen
|
||||
|
||||
|
@ -108,8 +108,8 @@ class AudioPlayer extends CocoClass
|
|||
return if not media
|
||||
media.loaded = true
|
||||
media.progress = 1.0
|
||||
if @soundsToPlayWhenLoaded[media.name]
|
||||
@playSound media.name
|
||||
if volume = @soundsToPlayWhenLoaded[media.name]
|
||||
@playSound media.name, volume
|
||||
@soundsToPlayWhenLoaded[media.name] = false
|
||||
@notifyProgressChanged()
|
||||
|
||||
|
@ -124,9 +124,3 @@ class AudioPlayer extends CocoClass
|
|||
|
||||
|
||||
module.exports = new AudioPlayer()
|
||||
|
||||
average = (numbers) ->
|
||||
return 0 if numbers.length is 0
|
||||
sum = 0
|
||||
sum += num for num in numbers
|
||||
return sum / numbers.length
|
||||
|
|
|
@ -6,7 +6,7 @@ makeScopeName = -> "class-scope-#{classCount++}"
|
|||
module.exports = class CocoClass
|
||||
subscriptions: {}
|
||||
shortcuts: {}
|
||||
|
||||
|
||||
# setup/teardown
|
||||
|
||||
constructor: ->
|
||||
|
@ -19,13 +19,15 @@ module.exports = class CocoClass
|
|||
|
||||
destroy: ->
|
||||
# teardown subscriptions, prevent new ones
|
||||
@destroyed = true
|
||||
@stopListening?()
|
||||
@unsubscribeAll()
|
||||
@stopListeningToShortcuts()
|
||||
@[key] = undefined for key of @
|
||||
@destroyed = true
|
||||
@destroy = ->
|
||||
|
||||
# subscriptions
|
||||
|
||||
|
||||
listenToSubscriptions: ->
|
||||
# for initting subscriptions
|
||||
return unless Backbone?.Mediator?
|
||||
|
@ -46,7 +48,7 @@ module.exports = class CocoClass
|
|||
for channel, func of @subscriptions
|
||||
func = utils.normalizeFunc(func, @)
|
||||
Backbone.Mediator.unsubscribe(channel, func, @)
|
||||
|
||||
|
||||
# keymaster shortcuts
|
||||
|
||||
listenToShortcuts: ->
|
||||
|
@ -54,7 +56,7 @@ module.exports = class CocoClass
|
|||
for shortcut, func of @shortcuts
|
||||
func = utils.normalizeFunc(func, @)
|
||||
key(shortcut, @scope, _.bind(func, @))
|
||||
|
||||
|
||||
stopListeningToShortcuts: ->
|
||||
return unless key?
|
||||
key.deleteScope(@scope)
|
||||
key.deleteScope(@scope)
|
||||
|
|
|
@ -76,6 +76,3 @@ module.exports = GPlusHandler = class GPlusHandler extends CocoClass
|
|||
storage.save(CURRENT_USER_KEY, model.attributes)
|
||||
window.location.reload()
|
||||
})
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
{now} = require './world/world_utils'
|
||||
{now} = require 'lib/world/world_utils'
|
||||
World = require 'lib/world/world'
|
||||
|
||||
## Uncomment to imitate IE9 (and in world_utils.coffee)
|
||||
#window.Worker = null
|
||||
#window.Float32Array = null
|
||||
# (except that we won't have included vendor_with_box2d.js, so Collision won't run, things won't move, etc.)
|
||||
# Also uncomment vendor_with_box2d.js in index.html if you want Collision to run and things to move.
|
||||
|
||||
module.exports = class God
|
||||
@ids: ['Athena', 'Baldr', 'Crom', 'Dagr', 'Eris', 'Freyja', 'Great Gish', 'Hades', 'Ishtar', 'Janus', 'Khronos', 'Loki', 'Marduk', 'Negafook', 'Odin', 'Poseidon', 'Quetzalcoatl', 'Ra', 'Shiva', 'Thor', 'Umvelinqangi', 'Týr', 'Vishnu', 'Wepwawet', 'Xipe Totec', 'Yahweh', 'Zeus', '上帝', 'Tiamat', '盘古', 'Phoebe', 'Artemis', 'Osiris', "嫦娥", 'Anhur', 'Teshub', 'Enlil', 'Perkele', 'Aether', 'Chaos', 'Hera', 'Iris', 'Theia', 'Uranus', 'Stribog', 'Sabazios', 'Izanagi', 'Ao', 'Tāwhirimātea', 'Tengri', 'Inmar', 'Torngarsuk', 'Centzonhuitznahua', 'Hunab Ku', 'Apollo', 'Helios', 'Thoth', 'Hyperion', 'Alectrona', 'Eos', 'Mitra', 'Saranyu', 'Freyr', 'Koyash', 'Atropos', 'Clotho', 'Lachesis', 'Tyche', 'Skuld', 'Urðr', 'Verðandi', 'Camaxtli', 'Huhetotl', 'Set', 'Anu', 'Allah', 'Anshar', 'Hermes', 'Lugh', 'Brigit', 'Manannan Mac Lir', 'Persephone', 'Mercury', 'Venus', 'Mars', 'Azrael', 'He-Man', 'Anansi', 'Issek', 'Mog', 'Kos', 'Amaterasu Omikami', 'Raijin', 'Susanowo', 'Blind Io', 'The Lady', 'Offler', 'Ptah', 'Anubis', 'Ereshkigal', 'Nergal', 'Thanatos', 'Macaria', 'Angelos', 'Erebus', 'Hecate', 'Hel', 'Orcus', 'Ishtar-Deela Nakh', 'Prometheus', 'Hephaestos', 'Sekhmet', 'Ares', 'Enyo', 'Otrera', 'Pele', 'Hadúr', 'Hachiman', 'Dayisun Tngri', 'Ullr', 'Lua', 'Minerva']
|
||||
|
@ -11,31 +12,63 @@ module.exports = class God
|
|||
@lastID = (if @lastID? then @lastID + 1 else Math.floor(@ids.length * Math.random())) % @ids.length
|
||||
@ids[@lastID]
|
||||
|
||||
maxAngels: 2 # how many concurrent web workers to use; if set past 8, make up more names
|
||||
worldWaiting: false # whether we're waiting for a worker to free up and run the world
|
||||
constructor: (@world, @level) ->
|
||||
constructor: (options) ->
|
||||
@id = God.nextID()
|
||||
options ?= {}
|
||||
@maxAngels = options.maxAngels ? 2 # How many concurrent web workers to use; if set past 8, make up more names
|
||||
@maxWorkerPoolSize = options.maxWorkerPoolSize ? 2 # ~20MB per idle worker
|
||||
@angels = []
|
||||
@firstWorld = true
|
||||
Backbone.Mediator.subscribe 'tome:cast-spells', @onTomeCast, @
|
||||
@fillWorkerPool = _.throttle @fillWorkerPool, 3000, leading: false
|
||||
@fillWorkerPool()
|
||||
|
||||
onTomeCast: (e) ->
|
||||
return if @dead
|
||||
@spells = e.spells
|
||||
@createWorld()
|
||||
|
||||
fillWorkerPool: =>
|
||||
return unless Worker
|
||||
@workerPool ?= []
|
||||
if @workerPool.length < @maxWorkerPoolSize
|
||||
@workerPool.push @createWorker()
|
||||
if @workerPool.length < @maxWorkerPoolSize
|
||||
@fillWorkerPool()
|
||||
|
||||
getWorker: ->
|
||||
@fillWorkerPool()
|
||||
worker = @workerPool?.shift()
|
||||
return worker if worker
|
||||
@createWorker()
|
||||
|
||||
createWorker: ->
|
||||
worker = new Worker '/javascripts/workers/worker_world.js'
|
||||
worker.creationTime = new Date()
|
||||
worker.addEventListener 'message', @onWorkerMessage
|
||||
worker
|
||||
|
||||
onWorkerMessage: (event) =>
|
||||
worker = event.target
|
||||
if event.data.type is 'worker-initialized'
|
||||
#console.log "Worker initialized after", ((new Date()) - worker.creationTime), "ms (before it was needed)"
|
||||
worker.initialized = true
|
||||
worker.removeEventListener 'message', @onWorkerMessage
|
||||
|
||||
getAngel: ->
|
||||
freeAngel = null
|
||||
for angel in @angels
|
||||
return angel.enslave() unless angel.busy
|
||||
if angel.busy
|
||||
angel.abort()
|
||||
else
|
||||
freeAngel ?= angel
|
||||
return freeAngel.enslave() if freeAngel
|
||||
maxedOut = @angels.length is @maxAngels
|
||||
if not maxedOut
|
||||
angel = new Angel @
|
||||
@angels.push angel
|
||||
return angel.enslave()
|
||||
oldestAngel = {started: new Date(2099, 1, 1)}
|
||||
for angel in @angels
|
||||
oldestAngel = angel if angel.started < oldestAngel.started
|
||||
oldestAngel.abort()
|
||||
null
|
||||
|
||||
angelInfinitelyLooped: (angel) ->
|
||||
|
@ -65,8 +98,9 @@ module.exports = class God
|
|||
else
|
||||
@worldWaiting = true
|
||||
return
|
||||
#console.log "going to run world with code", @getUserCodeMap()
|
||||
angel.worker.postMessage {func: 'runWorld', args: {
|
||||
worldName: @world.name
|
||||
worldName: @level.name
|
||||
userCodeMap: @getUserCodeMap()
|
||||
level: @level
|
||||
firstWorld: @firstWorld
|
||||
|
@ -80,7 +114,7 @@ module.exports = class God
|
|||
@latestWorldCreation = worldCreation
|
||||
@latestGoalStates = goalStates
|
||||
window.BOX2D_ENABLED = false # Flip this off so that if we have box2d in the namespace, the Collides Components still don't try to create bodies for deserialized Thangs upon attachment
|
||||
@world.constructor.deserialize serialized, @world.classMap, @lastSerializedWorldFrames, worldCreation, @finishBeholdingWorld
|
||||
World.deserialize serialized, @worldClassMap, @lastSerializedWorldFrames, worldCreation, @finishBeholdingWorld
|
||||
window.BOX2D_ENABLED = true
|
||||
@lastSerializedWorldFrames = serialized.frames
|
||||
|
||||
|
@ -88,11 +122,14 @@ module.exports = class God
|
|||
newWorld.findFirstChangedFrame @world
|
||||
@world = newWorld
|
||||
errorCount = (t for t in @world.thangs when t.errorsOut).length
|
||||
Backbone.Mediator.publish('god:new-world-created', world: @world, firstWorld: @firstWorld, errorCount: errorCount, goalStates: @latestGoalStates)
|
||||
Backbone.Mediator.publish('god:new-world-created', world: @world, firstWorld: @firstWorld, errorCount: errorCount, goalStates: @latestGoalStates, team: me.team)
|
||||
for scriptNote in @world.scriptNotes
|
||||
Backbone.Mediator.publish scriptNote.channel, scriptNote.event
|
||||
@goalManager?.world = newWorld
|
||||
@firstWorld = false
|
||||
@testWorld = null
|
||||
unless _.find @angels, 'busy'
|
||||
@spells = null # Don't hold onto old spells; memory leaks
|
||||
|
||||
getUserCodeMap: ->
|
||||
userCodeMap = {}
|
||||
|
@ -102,10 +139,15 @@ module.exports = class God
|
|||
userCodeMap
|
||||
|
||||
destroy: ->
|
||||
worker.removeEventListener 'message', @onWorkerMessage for worker in @workerPool ? []
|
||||
angel.destroy() for angel in @angels
|
||||
@dead = true
|
||||
Backbone.Mediator.unsubscribe('tome:cast-spells', @onTomeCast, @)
|
||||
@goalManager?.destroy()
|
||||
@goalManager = null
|
||||
@fillWorkerPool = null
|
||||
@simulateWorld = null
|
||||
@onWorkerMessage = null
|
||||
|
||||
#### Bad code for running worlds on main thread (profiling / IE9) ####
|
||||
simulateWorld: =>
|
||||
|
@ -129,7 +171,7 @@ module.exports = class God
|
|||
@latestGoalStates = @testGM?.getGoalStates()
|
||||
serialized = @testWorld.serialize().serializedWorld
|
||||
window.BOX2D_ENABLED = false
|
||||
@testWorld.constructor.deserialize serialized, @world.classMap, @lastSerializedWorldFrames, @t0, @finishBeholdingWorld
|
||||
World.deserialize serialized, @worldClassMap, @lastSerializedWorldFrames, @t0, @finishBeholdingWorld
|
||||
window.BOX2D_ENABLED = true
|
||||
@lastSerializedWorldFrames = serialized.frames
|
||||
|
||||
|
@ -152,8 +194,8 @@ class Angel
|
|||
@ids[@lastID]
|
||||
|
||||
# https://github.com/codecombat/codecombat/issues/81 -- TODO: we need to wait for worker initialization first
|
||||
infiniteLoopIntervalDuration: 1500000 # check this often (must be more than the others added)
|
||||
infiniteLoopTimeoutDuration: 1500 # wait this long when we check
|
||||
infiniteLoopIntervalDuration: 7500 # check this often (must be more than the others added)
|
||||
infiniteLoopTimeoutDuration: 2500 # wait this long when we check
|
||||
abortTimeoutDuration: 500 # give in-process or dying workers this long to give up
|
||||
constructor: (@god) ->
|
||||
@id = Angel.nextID()
|
||||
|
@ -164,13 +206,14 @@ class Angel
|
|||
@spawnWorker()
|
||||
|
||||
spawnWorker: ->
|
||||
@worker = new Worker '/javascripts/workers/worker_world.js'
|
||||
@worker = @god.getWorker()
|
||||
@listen()
|
||||
|
||||
enslave: ->
|
||||
@busy = true
|
||||
@started = new Date()
|
||||
@purgatoryTimer = setInterval @testWorker, @infiniteLoopIntervalDuration
|
||||
@spawnWorker() unless @worker
|
||||
@
|
||||
|
||||
free: ->
|
||||
|
@ -178,24 +221,42 @@ class Angel
|
|||
@started = null
|
||||
clearInterval @purgatoryTimer
|
||||
@purgatoryTimer = null
|
||||
if @worker
|
||||
worker = @worker
|
||||
onWorkerMessage = @onWorkerMessage
|
||||
_.delay ->
|
||||
worker.terminate()
|
||||
worker.removeEventListener 'message', onWorkerMessage
|
||||
, 2000
|
||||
@worker = null
|
||||
@
|
||||
|
||||
abort: ->
|
||||
return unless @worker
|
||||
@abortTimeout = _.delay @terminate, @abortTimeoutDuration
|
||||
@worker.postMessage {func: 'abort'}
|
||||
|
||||
terminate: =>
|
||||
@worker.terminate()
|
||||
@worker?.terminate()
|
||||
@worker?.removeEventListener 'message', @onWorkerMessage
|
||||
@worker = null
|
||||
return if @dead
|
||||
@spawnWorker()
|
||||
@free()
|
||||
@god.angelAborted @
|
||||
|
||||
destroy: ->
|
||||
@dead = true
|
||||
@finishBeholdingWorld = null
|
||||
@abort()
|
||||
@terminate = null
|
||||
@testWorker = null
|
||||
@condemnWorker = null
|
||||
@onWorkerMessage = null
|
||||
|
||||
testWorker: =>
|
||||
unless @worker.initialized
|
||||
console.warn "Worker", @id, "hadn't even loaded the scripts yet after", @infiniteLoopIntervalDuration, "ms."
|
||||
return
|
||||
@worker.postMessage {func: 'reportIn'}
|
||||
@condemnTimeout = _.delay @condemnWorker, @infiniteLoopTimeoutDuration
|
||||
|
||||
|
@ -204,23 +265,26 @@ 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 @
|
||||
@worker.terminate() if @god.dead
|
||||
when 'reportIn'
|
||||
clearTimeout @condemnTimeout
|
||||
else
|
||||
console.log "Unsupported message:", event.data
|
||||
@worker.addEventListener 'message', @onWorkerMessage
|
||||
|
||||
onWorkerMessage: (event) =>
|
||||
switch event.data.type
|
||||
when 'worker-initialized'
|
||||
console.log "Worker", @id, "initialized after", ((new Date()) - @worker.creationTime), "ms (we had been waiting for it)"
|
||||
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
|
||||
|
|
|
@ -21,18 +21,19 @@ module.exports = class LevelBus extends Bus
|
|||
'thang-code-ran': 'onCodeRan'
|
||||
'level-show-victory': 'onVictory'
|
||||
'tome:spell-changed': 'onSpellChanged'
|
||||
'tome:spell-created': 'onSpellCreated'
|
||||
|
||||
constructor: ->
|
||||
super(arguments...)
|
||||
@changedSessionProperties = {}
|
||||
@saveSession = _.debounce(@saveSession, 1000, {maxWait: 5000})
|
||||
|
||||
|
||||
init: ->
|
||||
super()
|
||||
@fireScriptsRef = @fireRef?.child('scripts')
|
||||
|
||||
setSession: (@session) ->
|
||||
@session.on('change:multiplayer', @onMultiplayerChanged)
|
||||
@session.on 'change:multiplayer', @onMultiplayerChanged, @
|
||||
|
||||
onPoint: ->
|
||||
return true unless @session?.get('multiplayer')
|
||||
|
@ -54,14 +55,14 @@ module.exports = class LevelBus extends Bus
|
|||
@wizardRef?.child('targetPos').set(wizardSprite?.targetPos or null)
|
||||
@wizardRef?.child('targetSprite').set(wizardSprite?.targetSprite?.thang.id or null)
|
||||
@wizardRef?.child('wizardColor1').set(me.get('wizardColor1') or 0.0)
|
||||
|
||||
|
||||
disconnect: ->
|
||||
@wizardRef?.off()
|
||||
@wizardRef = null
|
||||
@fireScriptsRef?.off()
|
||||
@fireScriptsRef = null
|
||||
super()
|
||||
|
||||
|
||||
removeFirebaseData: (callback) ->
|
||||
return callback?() unless @myConnection
|
||||
@myConnection.child('connected')
|
||||
|
@ -77,26 +78,44 @@ module.exports = class LevelBus extends Bus
|
|||
|
||||
onEditingBegan: -> @wizardRef?.child('editing').set(true)
|
||||
onEditingEnded: -> @wizardRef?.child('editing').set(false)
|
||||
|
||||
|
||||
# HACK: Backbone does not work with nested documents, but we want to
|
||||
# patch only those props that have changed. Look into plugins to
|
||||
# give Backbone support for nested docs and update the code here.
|
||||
|
||||
|
||||
# TODO: The LevelBus doesn't need to be in charge of updating the
|
||||
# LevelSession object. Either break this off into a separate class
|
||||
# or have the LevelSession object listen for all these events itself.
|
||||
|
||||
setSpells: (spells) ->
|
||||
@onSpellCreated spell: spell for spellKey, spell of spells
|
||||
|
||||
onSpellChanged: (e) ->
|
||||
return unless @onPoint()
|
||||
code = @session.get('code')
|
||||
code ?= {}
|
||||
parts = e.spell.spellKey.split('/')
|
||||
|
||||
code[parts[0]] ?= {}
|
||||
code[parts[0]][parts[1]] = e.spell.getSource()
|
||||
@changedSessionProperties.code = true
|
||||
@session.set({'code': code})
|
||||
@saveSession()
|
||||
|
||||
onSpellCreated: (e) ->
|
||||
return unless @onPoint()
|
||||
spellTeam = e.spell.team
|
||||
@teamSpellMap ?= {}
|
||||
@teamSpellMap[spellTeam] ?= []
|
||||
|
||||
unless e.spell.spellKey in @teamSpellMap[spellTeam]
|
||||
@teamSpellMap[spellTeam].push e.spell.spellKey
|
||||
@changedSessionProperties.teamSpells = true
|
||||
@session.set({'teamSpells': @teamSpellMap})
|
||||
@saveSession()
|
||||
if spellTeam is me.team
|
||||
@onSpellChanged e # Save the new spell to the session, too.
|
||||
|
||||
onScriptStateChanged: (e) ->
|
||||
return unless @onPoint()
|
||||
@fireScriptsRef?.update(e)
|
||||
|
@ -198,7 +217,7 @@ module.exports = class LevelBus extends Bus
|
|||
@changedSessionProperties.chat = true
|
||||
@saveSession()
|
||||
|
||||
onMultiplayerChanged: =>
|
||||
onMultiplayerChanged: ->
|
||||
@changedSessionProperties.multiplayer = true
|
||||
@session.updatePermissions()
|
||||
@changedSessionProperties.permissions = true
|
||||
|
@ -212,8 +231,12 @@ module.exports = class LevelBus extends Bus
|
|||
patch = {}
|
||||
patch[prop] = @session.get(prop) for prop of @changedSessionProperties
|
||||
@changedSessionProperties = {}
|
||||
|
||||
|
||||
# since updates are coming fast and loose for session objects
|
||||
# don't let what the server returns overwrite changes since the save began
|
||||
tempSession = new LevelSession _id:@session.id
|
||||
tempSession.save(patch, {patch: true})
|
||||
|
||||
destroy: ->
|
||||
@session.off 'change:multiplayer', @onMultiplayerChanged, @
|
||||
super()
|
||||
|
|
|
@ -19,148 +19,179 @@ module.exports = class LevelLoader extends CocoClass
|
|||
spriteSheetsBuilt: 0
|
||||
spriteSheetsToBuild: 0
|
||||
|
||||
subscriptions:
|
||||
'god:new-world-created': 'loadSoundsForWorld'
|
||||
|
||||
constructor: (@levelID, @supermodel, @sessionID) ->
|
||||
constructor: (options) ->
|
||||
super()
|
||||
@supermodel = options.supermodel
|
||||
@levelID = options.levelID
|
||||
@sessionID = options.sessionID
|
||||
@opponentSessionID = options.opponentSessionID
|
||||
@team = options.team
|
||||
@headless = options.headless
|
||||
|
||||
@loadSession()
|
||||
@loadLevelModels()
|
||||
@loadAudio()
|
||||
@playJingle()
|
||||
setTimeout (=> @update()), 1 # lets everything else resolve first
|
||||
_.defer @update # Lets everything else resolve first
|
||||
|
||||
playJingle: ->
|
||||
jingles = ["ident_1", "ident_2"]
|
||||
AudioPlayer.playInterfaceSound jingles[Math.floor Math.random() * jingles.length]
|
||||
return if @headless
|
||||
# Apparently the jingle, when it tries to play immediately during all this loading, you can't hear it.
|
||||
# Add the timeout to fix this weird behavior.
|
||||
f = ->
|
||||
jingles = ["ident_1", "ident_2"]
|
||||
AudioPlayer.playInterfaceSound jingles[Math.floor Math.random() * jingles.length]
|
||||
setTimeout f, 500
|
||||
|
||||
# Session Loading
|
||||
|
||||
loadSession: ->
|
||||
url = if @sessionID then "/db/level_session/#{@sessionID}" else "/db/level/#{@levelID}/session"
|
||||
if @sessionID
|
||||
url = "/db/level_session/#{@sessionID}"
|
||||
else
|
||||
url = "/db/level/#{@levelID}/session"
|
||||
url += "?team=#{@team}" if @team
|
||||
|
||||
@session = new LevelSession()
|
||||
@session.url = -> url
|
||||
@session.fetch()
|
||||
@session.once 'sync', @onSessionLoaded
|
||||
|
||||
onSessionLoaded: =>
|
||||
# Unless you specify cache:false, sometimes the browser will use a cached session
|
||||
# and players will 'lose' code
|
||||
@session.fetch({cache:false})
|
||||
@session.once 'sync', @onSessionLoaded, @
|
||||
|
||||
if @opponentSessionID
|
||||
@opponentSession = new LevelSession()
|
||||
@opponentSession.url = "/db/level_session/#{@opponentSessionID}"
|
||||
@opponentSession.fetch()
|
||||
@opponentSession.once 'sync', @onSessionLoaded, @
|
||||
|
||||
sessionsLoaded: ->
|
||||
@session.loaded and ((not @opponentSession) or @opponentSession.loaded)
|
||||
|
||||
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()
|
||||
if @session.loaded
|
||||
@session.url = -> '/db/level.session/' + @id
|
||||
@update() if @sessionsLoaded()
|
||||
|
||||
# Supermodel (Level) Loading
|
||||
|
||||
loadLevelModels: ->
|
||||
@supermodel.once 'loaded-all', @onSupermodelLoadedAll
|
||||
@supermodel.on 'loaded-one', @onSupermodelLoadedOne
|
||||
@supermodel.once 'error', @onSupermodelError
|
||||
@supermodel.on 'loaded-one', @onSupermodelLoadedOne, @
|
||||
@supermodel.once 'error', @onSupermodelError, @
|
||||
@level = @supermodel.getModel(Level, @levelID) or new Level _id: @levelID
|
||||
levelID = @levelID
|
||||
headless = @headless
|
||||
|
||||
@supermodel.shouldPopulate = (model) =>
|
||||
@supermodel.shouldPopulate = (model) ->
|
||||
# if left unchecked, the supermodel would load this level
|
||||
# and every level next on the chain. This limits the population
|
||||
handles = [model.id, model.get 'slug']
|
||||
return model.constructor.className isnt "Level" or @levelID in handles
|
||||
return model.constructor.className isnt "Level" or levelID in handles
|
||||
|
||||
@supermodel.shouldLoadProjection = (model) ->
|
||||
return true if headless and model.constructor.className is 'ThangType'
|
||||
false
|
||||
|
||||
@supermodel.populateModel @level
|
||||
|
||||
onSupermodelError: =>
|
||||
msg = $.i18n.t('play_level.level_load_error',
|
||||
defaultValue: "Level could not be loaded.")
|
||||
@$el.html('<div class="alert">' + msg + '</div>')
|
||||
onSupermodelError: ->
|
||||
|
||||
onSupermodelLoadedOne: (e) =>
|
||||
@notifyProgress()
|
||||
# if e.model.type() is 'ThangType'
|
||||
# thangType = e.model
|
||||
# options = {async: true}
|
||||
# if thangType.get('name') is 'Wizard'
|
||||
# options.colorConfig = me.get('wizard')?.colorConfig or {}
|
||||
# building = thangType.buildSpriteSheet options
|
||||
# if building
|
||||
# @spriteSheetsToBuild += 1
|
||||
# thangType.on 'build-complete', =>
|
||||
# @spriteSheetsBuilt += 1
|
||||
# @notifyProgress()
|
||||
|
||||
onSupermodelLoadedAll: =>
|
||||
@trigger 'loaded-supermodel'
|
||||
@stopListening(@supermodel)
|
||||
onSupermodelLoadedOne: (e) ->
|
||||
@buildSpriteSheetsForThangType e.model if not @headless and e.model instanceof ThangType
|
||||
@update()
|
||||
|
||||
# Things to do when either the Session or Supermodel load
|
||||
|
||||
update: ->
|
||||
update: =>
|
||||
@notifyProgress()
|
||||
|
||||
return if @updateCompleted
|
||||
return unless @supermodel.finished() and @session.loaded
|
||||
return unless @supermodel?.finished() and @sessionsLoaded()
|
||||
@denormalizeSession()
|
||||
@loadLevelSounds()
|
||||
app.tracker.updatePlayState(@level, @session)
|
||||
@updateCompleted = true
|
||||
|
||||
denormalizeSession: ->
|
||||
return if @session.get 'levelName'
|
||||
return if @sessionDenormalized
|
||||
patch =
|
||||
'levelName': @level.get('name')
|
||||
'levelID': @level.get('slug') or @level.id
|
||||
if me.id is @session.get 'creator'
|
||||
patch.creatorName = me.get('name')
|
||||
|
||||
@session.set key, value for key, value of patch
|
||||
tempSession = new LevelSession _id: @session.id
|
||||
tempSession.save(patch, {patch: true})
|
||||
for key, value of patch
|
||||
if @session.get(key) is value
|
||||
delete patch[key]
|
||||
unless _.isEmpty patch
|
||||
@session.set key, value for key, value of patch
|
||||
tempSession = new LevelSession _id: @session.id
|
||||
tempSession.save(patch, {patch: true})
|
||||
@sessionDenormalized = true
|
||||
|
||||
# World init
|
||||
# Building sprite sheets
|
||||
|
||||
initWorld: ->
|
||||
return if @world
|
||||
@world = new World @level.get('name')
|
||||
serializedLevel = @level.serialize(@supermodel)
|
||||
@world.loadFromLevel serializedLevel, false
|
||||
@buildSpriteSheets()
|
||||
grabThangTypeTeams: ->
|
||||
@grabTeamConfigs()
|
||||
@thangTypeTeams = {}
|
||||
for thang in @level.get('thangs')
|
||||
for component in thang.components
|
||||
if team = component.config?.team
|
||||
@thangTypeTeams[thang.thangType] ?= []
|
||||
@thangTypeTeams[thang.thangType].push team unless team in @thangTypeTeams[thang.thangType]
|
||||
break
|
||||
@thangTypeTeams
|
||||
|
||||
buildSpriteSheets: ->
|
||||
thangTypes = {}
|
||||
thangTypes[tt.get('name')] = tt for tt in @supermodel.getModels(ThangType)
|
||||
grabTeamConfigs: ->
|
||||
for system in @level.get('systems')
|
||||
if @teamConfigs = system.config?.teamConfigs
|
||||
break
|
||||
unless @teamConfigs
|
||||
# Hack: pulled from Alliance System code. TODO: put in just one place.
|
||||
@teamConfigs = {"humans":{"superteam":"humans","color":{"hue":0,"saturation":0.75,"lightness":0.5},"playable":true},"ogres":{"superteam":"ogres","color":{"hue":0.66,"saturation":0.75,"lightness":0.5},"playable":false},"neutral":{"superteam":"neutral","color":{"hue":0.33,"saturation":0.75,"lightness":0.5}}}
|
||||
@teamConfigs
|
||||
|
||||
colorConfigs = @world.getTeamColors()
|
||||
|
||||
thangsProduced = {}
|
||||
baseOptions = {resolutionFactor: 4, async: true}
|
||||
|
||||
for thang in @world.thangs
|
||||
continue unless thang.spriteName
|
||||
thangType = thangTypes[thang.spriteName]
|
||||
options = thang.getSpriteOptions(colorConfigs)
|
||||
options.async = true
|
||||
thangsProduced[thang.spriteName] = true
|
||||
@buildSpriteSheet(thangType, options)
|
||||
|
||||
for thangName, thangType of thangTypes
|
||||
continue if thangsProduced[thangName]
|
||||
thangType.spriteOptions = {resolutionFactor: 4, async: true}
|
||||
@buildSpriteSheet(thangType, thangType.spriteOptions)
|
||||
buildSpriteSheetsForThangType: (thangType) ->
|
||||
@grabThangTypeTeams() unless @thangTypeTeams
|
||||
for team in @thangTypeTeams[thangType.get('original')] ? [null]
|
||||
spriteOptions = {resolutionFactor: 4, async: true}
|
||||
if thangType.get('kind') is 'Floor'
|
||||
spriteOptions.resolutionFactor = 2
|
||||
if team and color = @teamConfigs[team]?.color
|
||||
spriteOptions.colorConfig = team: color
|
||||
@buildSpriteSheet thangType, spriteOptions
|
||||
|
||||
buildSpriteSheet: (thangType, options) ->
|
||||
if thangType.get('name') is 'Wizard'
|
||||
options.colorConfig = me.get('wizard')?.colorConfig or {}
|
||||
building = thangType.buildSpriteSheet options
|
||||
return unless building
|
||||
console.log 'Building:', thangType.get('name'), options
|
||||
#console.log 'Building:', thangType.get('name'), options
|
||||
t0 = new Date()
|
||||
@spriteSheetsToBuild += 1
|
||||
thangType.on 'build-complete', =>
|
||||
thangType.once 'build-complete', =>
|
||||
@spriteSheetsBuilt += 1
|
||||
@notifyProgress()
|
||||
console.log "Built", thangType.get('name'), 'after', ((new Date()) - t0), 'ms'
|
||||
|
||||
# World init
|
||||
|
||||
initWorld: ->
|
||||
return if @initialized
|
||||
@initialized = true
|
||||
@world = new World @level.get('name')
|
||||
serializedLevel = @level.serialize(@supermodel)
|
||||
@world.loadFromLevel serializedLevel, false
|
||||
|
||||
# Initial Sound Loading
|
||||
|
||||
loadAudio: ->
|
||||
return if @headless
|
||||
AudioPlayer.preloadInterfaceSounds ["victory"]
|
||||
|
||||
loadLevelSounds: ->
|
||||
return if @headless
|
||||
scripts = @level.get 'scripts'
|
||||
return unless scripts
|
||||
|
||||
|
@ -174,38 +205,32 @@ module.exports = class LevelLoader extends CocoClass
|
|||
for trigger, sounds of thangType.get('soundTriggers') or {} when trigger isnt 'say'
|
||||
AudioPlayer.preloadSoundReference sound for sound in sounds
|
||||
|
||||
# Dynamic sound loading
|
||||
|
||||
loadSoundsForWorld: (e) ->
|
||||
world = e.world
|
||||
thangTypes = @supermodel.getModels(ThangType)
|
||||
for [spriteName, message] in world.thangDialogueSounds()
|
||||
continue unless thangType = _.find thangTypes, (m) -> m.get('name') is spriteName
|
||||
continue unless sound = AudioPlayer.soundForDialogue message, thangType.get('soundTriggers')
|
||||
filename = AudioPlayer.preloadSoundReference sound
|
||||
|
||||
# everything else sound wise is loaded as needed as worlds are generated
|
||||
|
||||
allDone: ->
|
||||
@supermodel.finished() and @session.loaded and @spriteSheetsBuilt is @spriteSheetsToBuild
|
||||
@supermodel.finished() and @sessionsLoaded() and @spriteSheetsBuilt is @spriteSheetsToBuild
|
||||
|
||||
progress: ->
|
||||
return 0 unless @level.loaded
|
||||
overallProgress = 0
|
||||
supermodelProgress = @supermodel.progress()
|
||||
overallProgress += supermodelProgress * 0.7
|
||||
overallProgress += 0.1 if @session.loaded
|
||||
spriteMapProgress = if supermodelProgress is 1 then 0.2 else 0
|
||||
spriteMapProgress *= @spriteSheetsBuilt / @spriteSheetsToBuild if @spriteSheetsToBuild
|
||||
overallProgress += 0.1 if @sessionsLoaded()
|
||||
if @headless
|
||||
spriteMapProgress = 0.2
|
||||
else
|
||||
spriteMapProgress = if supermodelProgress is 1 then 0.2 else 0
|
||||
spriteMapProgress *= @spriteSheetsBuilt / @spriteSheetsToBuild if @spriteSheetsToBuild
|
||||
overallProgress += spriteMapProgress
|
||||
return overallProgress
|
||||
|
||||
notifyProgress: ->
|
||||
Backbone.Mediator.publish 'level-loader:progress-changed', progress: @progress()
|
||||
@initWorld() if @allDone()
|
||||
# @trigger 'ready-to-init-world' if @allDone()
|
||||
@trigger 'loaded-all' if @progress() is 1
|
||||
|
||||
destroy: ->
|
||||
@supermodel.off 'loaded-one', @onSupermodelLoadedOne
|
||||
@world = null # don't hold onto garbage
|
||||
@update = null
|
||||
super()
|
||||
|
|
|
@ -93,7 +93,12 @@ module.exports = class LoadingScreen extends CocoClass
|
|||
@text.text = "BUILDING" if @progress is 1
|
||||
@progressBar.scaleX = @progress
|
||||
@stage.update()
|
||||
|
||||
showReady: ->
|
||||
@text.text = 'READY'
|
||||
@text.regX = @text.getMeasuredWidth() / 2
|
||||
@stage.update()
|
||||
|
||||
destroy: ->
|
||||
@stage.canvas = null
|
||||
super()
|
||||
super()
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
gplusClientID = "800329290710-j9sivplv2gpcdgkrsis9rff3o417mlfa.apps.googleusercontent.com"
|
||||
|
||||
go = (path) -> -> @routeDirectly path, arguments
|
||||
|
||||
module.exports = class CocoRouter extends Backbone.Router
|
||||
subscribe: ->
|
||||
Backbone.Mediator.subscribe 'gapi-loaded', @onGPlusAPILoaded, @
|
||||
|
@ -15,6 +17,9 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
|
||||
# editor views tend to have the same general structure
|
||||
'editor/:model(/:slug_or_id)(/:subview)': 'editorModelView'
|
||||
|
||||
# Experimenting with direct links
|
||||
'play/ladder/:levelID/team/:team': go('play/ladder/team_view')
|
||||
|
||||
# db and file urls call the server directly
|
||||
'db/*path': 'routeToServer'
|
||||
|
@ -26,7 +31,7 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
home: -> @openRoute('home')
|
||||
general: (name) ->
|
||||
@openRoute(name)
|
||||
|
||||
|
||||
editorModelView: (modelName, slugOrId, subview) ->
|
||||
modulePrefix = "views/editor/#{modelName}/"
|
||||
suffix = subview or (if slugOrId then 'edit' else 'home')
|
||||
|
@ -87,6 +92,14 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
view = @getView(route)
|
||||
@cache[route] = view unless view and view.cache is false
|
||||
return view
|
||||
|
||||
routeDirectly: (path, args) ->
|
||||
path = "views/#{path}"
|
||||
ViewClass = @tryToLoadModule path
|
||||
return @showNotFound() if not ViewClass
|
||||
view = new ViewClass({}, args...) # options, then any path fragment args
|
||||
view.render()
|
||||
@openView(view)
|
||||
|
||||
getView: (route, suffix='_view') ->
|
||||
# iteratively breaks down the url pieces looking for the view
|
||||
|
@ -119,7 +132,7 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
view.render()
|
||||
|
||||
closeCurrentView: ->
|
||||
window.currentModal?.hide()
|
||||
window.currentModal?.hide?()
|
||||
return unless window.currentView?
|
||||
if window.currentView.cache
|
||||
window.currentView.scrollY = window.scrollY
|
||||
|
|
|
@ -22,17 +22,17 @@ module.exports = class Tracker
|
|||
return unless me and olark?
|
||||
olark 'api.chat.updateVisitorStatus', snippet: ["User ID: #{me.id}"]
|
||||
return if me.get("anonymous")
|
||||
olark 'api.visitor.updateEmailAddress', emailAddress: me.get("email")
|
||||
olark 'api.visitor.updateEmailAddress', emailAddress: me.get("email") if me.get('email')
|
||||
olark 'api.chat.updateVisitorNickname', snippet: me.displayName()
|
||||
|
||||
updatePlayState: (level, session) ->
|
||||
return unless olark?
|
||||
link = "codecombat.com/play/level/#{level.get('slug') or level.id}?session=#{session.id}"
|
||||
snippet = [
|
||||
"#{link}"
|
||||
"User ID: #{me.id}"
|
||||
"Session ID: #{session.id}"
|
||||
"Level: #{level.get('name')}"
|
||||
|
||||
]
|
||||
olark 'api.chat.updateVisitorStatus', snippet: snippet
|
||||
|
||||
|
|
|
@ -16,18 +16,18 @@ module.exports.genericFailure = (jqxhr) ->
|
|||
error = module.exports.parseServerError(jqxhr.responseText)
|
||||
message = error.message
|
||||
message = error.property + ' ' + message if error.property
|
||||
res = errorModalTemplate(
|
||||
status:jqxhr.status
|
||||
statusText:jqxhr.statusText
|
||||
message: message
|
||||
)
|
||||
console.warn(jqxhr.status, jqxhr.statusText, error)
|
||||
existingForm = $('.form-inline:visible:first')
|
||||
existingForm = $('.form:visible:first')
|
||||
if existingForm[0]
|
||||
missingErrors = applyErrorsToForm(existingForm, [error])
|
||||
for error in missingErrors
|
||||
existingForm.append($('<div class="alert"></div>').text(error.message))
|
||||
else
|
||||
res = errorModalTemplate(
|
||||
status:jqxhr.status
|
||||
statusText:jqxhr.statusText
|
||||
message: message
|
||||
)
|
||||
showErrorModal(res)
|
||||
|
||||
module.exports.backboneFailure = (model, jqxhr, options) ->
|
||||
|
|
|
@ -102,6 +102,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
|
|||
unless script
|
||||
console.warn "Couldn't find script for", scriptID, "from scripts", @scripts, "when restoring session scripts."
|
||||
continue
|
||||
continue if script.repeats # repeating scripts are not 'rerun'
|
||||
@triggered.push(scriptID)
|
||||
@ended.push(scriptID)
|
||||
noteChain = @processScript(script)
|
||||
|
@ -120,8 +121,8 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
|
|||
@run() unless @worldLoading
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@onEndAll()
|
||||
super()
|
||||
|
||||
# TRIGGERERING NOTES
|
||||
|
||||
|
@ -131,7 +132,17 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
|
|||
alreadyTriggered = script.id in @triggered
|
||||
continue unless script.channel is channel
|
||||
continue if alreadyTriggered and not script.repeats
|
||||
continue if script.lastTriggered? and script.repeats is 'session'
|
||||
continue if script.lastTriggered? and new Date().getTime() - script.lastTriggered < 1
|
||||
continue if script.neverRun
|
||||
|
||||
if script.notAfter
|
||||
for scriptID in script.notAfter
|
||||
if scriptID in @triggered
|
||||
script.neverRun = true
|
||||
break
|
||||
continue if script.neverRun
|
||||
|
||||
continue unless @scriptPrereqsSatisfied(script)
|
||||
continue unless scriptMatchesEventPrereqs(script, event)
|
||||
# everything passed!
|
||||
|
@ -182,7 +193,7 @@ module.exports = ScriptManager = class ScriptManager extends CocoClass
|
|||
|
||||
# STARTING NOTES
|
||||
|
||||
run: =>
|
||||
run: ->
|
||||
# catch all for analyzing the current state and doing whatever needs to happen next
|
||||
return if @scriptInProgress
|
||||
@skipAhead()
|
||||
|
|
|
@ -33,7 +33,7 @@ module.exports = class SpritesScriptModule extends ScriptModule
|
|||
spriteSayNote: (sprite, script) ->
|
||||
return if @speakingSprites[sprite.id]
|
||||
responses = sprite.say.responses
|
||||
responses = [] unless script.skippable
|
||||
responses = [] unless script.skippable or responses
|
||||
for response in responses ? []
|
||||
response.text = response.i18n?[me.lang()]?.text ? response.text
|
||||
text = sprite.say.i18n?[me.lang()]?.text or sprite.say.text
|
||||
|
|
|
@ -29,7 +29,7 @@ module.exports = class SurfaceScriptModule extends ScriptModule
|
|||
e = {}
|
||||
e.pos = focus.target if _.isPlainObject focus.target
|
||||
e.thangID = focus.target if _.isString focus.target
|
||||
e.zoom = focus.zoom or 2.0
|
||||
e.zoom = focus.zoom or 2.0 # TODO: test only doing this if e.pos, e.thangID, or focus.zoom?
|
||||
e.duration = if focus.duration? then focus.duration else 1500
|
||||
e.duration = 0 if instant
|
||||
e.bounds = focus.bounds if focus.bounds?
|
||||
|
|
274
app/lib/simulator/Simulator.coffee
Normal file
|
@ -0,0 +1,274 @@
|
|||
SuperModel = require 'models/SuperModel'
|
||||
LevelLoader = require 'lib/LevelLoader'
|
||||
GoalManager = require 'lib/world/GoalManager'
|
||||
God = require 'lib/God'
|
||||
|
||||
module.exports = class Simulator
|
||||
|
||||
constructor: ->
|
||||
_.extend @, Backbone.Events
|
||||
@trigger 'statusUpdate', 'Starting simulation!'
|
||||
@retryDelayInSeconds = 10
|
||||
@taskURL = '/queue/scoring'
|
||||
|
||||
fetchAndSimulateTask: =>
|
||||
@trigger 'statusUpdate', 'Fetching simulation data!'
|
||||
$.ajax
|
||||
url: @taskURL
|
||||
type: "GET"
|
||||
error: @handleFetchTaskError
|
||||
success: @setupSimulationAndLoadLevel
|
||||
|
||||
handleFetchTaskError: (errorData) =>
|
||||
console.log "There were no games to score. Error: #{JSON.stringify errorData}"
|
||||
console.log "Retrying in #{@retryDelayInSeconds}"
|
||||
@trigger 'statusUpdate', 'There were no games to simulate! Trying again in 10 seconds.'
|
||||
|
||||
@simulateAnotherTaskAfterDelay()
|
||||
|
||||
simulateAnotherTaskAfterDelay: =>
|
||||
retryDelayInMilliseconds = @retryDelayInSeconds * 1000
|
||||
_.delay @fetchAndSimulateTask, retryDelayInMilliseconds
|
||||
|
||||
setupSimulationAndLoadLevel: (taskData) =>
|
||||
@trigger 'statusUpdate', 'Setting up simulation!'
|
||||
@task = new SimulationTask(taskData)
|
||||
@supermodel = new SuperModel()
|
||||
@god = new God maxWorkerPoolSize: 1, maxAngels: 1 # Start loading worker.
|
||||
|
||||
@levelLoader = new LevelLoader supermodel: @supermodel, levelID: @task.getLevelName(), sessionID: @task.getFirstSessionID(), headless: true
|
||||
@levelLoader.once 'loaded-all', @simulateGame
|
||||
|
||||
simulateGame: =>
|
||||
@trigger 'statusUpdate', 'All resources loaded, simulating!', @task.getSessions()
|
||||
@assignWorldAndLevelFromLevelLoaderAndDestroyIt()
|
||||
@setupGod()
|
||||
|
||||
try
|
||||
@commenceSimulationAndSetupCallback()
|
||||
catch err
|
||||
console.log "There was an error in simulation(#{err}). Trying again in #{@retryDelayInSeconds} seconds"
|
||||
@simulateAnotherTaskAfterDelay()
|
||||
|
||||
assignWorldAndLevelFromLevelLoaderAndDestroyIt: ->
|
||||
@world = @levelLoader.world
|
||||
@level = @levelLoader.level
|
||||
@levelLoader.destroy()
|
||||
@levelLoader = null
|
||||
|
||||
setupGod: ->
|
||||
@god.level = @level.serialize @supermodel
|
||||
@god.worldClassMap = @world.classMap
|
||||
@setupGoalManager()
|
||||
@setupGodSpells()
|
||||
|
||||
setupGoalManager: ->
|
||||
@god.goalManager = new GoalManager @world
|
||||
@god.goalManager.goals = @god.level.goals
|
||||
@god.goalManager.goalStates = @manuallyGenerateGoalStates()
|
||||
|
||||
commenceSimulationAndSetupCallback: ->
|
||||
@god.createWorld()
|
||||
Backbone.Mediator.subscribeOnce 'god:new-world-created', @processResults, @
|
||||
|
||||
processResults: (simulationResults) ->
|
||||
taskResults = @formTaskResultsObject simulationResults
|
||||
@sendResultsBackToServer taskResults
|
||||
|
||||
sendResultsBackToServer: (results) =>
|
||||
@trigger 'statusUpdate', 'Simulation completed, sending results back to server!'
|
||||
console.log "Sending result back to server!"
|
||||
$.ajax
|
||||
url: "/queue/scoring"
|
||||
data: results
|
||||
type: "PUT"
|
||||
success: @handleTaskResultsTransferSuccess
|
||||
error: @handleTaskResultsTransferError
|
||||
complete: @cleanupAndSimulateAnotherTask
|
||||
|
||||
handleTaskResultsTransferSuccess: (result) =>
|
||||
console.log "Task registration result: #{JSON.stringify result}"
|
||||
@trigger 'statusUpdate', 'Results were successfully sent back to server!'
|
||||
|
||||
handleTaskResultsTransferError: (error) =>
|
||||
@trigger 'statusUpdate', 'There was an error sending the results back to the server.'
|
||||
console.log "Task registration error: #{JSON.stringify error}"
|
||||
|
||||
cleanupAndSimulateAnotherTask: =>
|
||||
@cleanupSimulation()
|
||||
@fetchAndSimulateTask()
|
||||
|
||||
cleanupSimulation: ->
|
||||
@god.destroy()
|
||||
@god = null
|
||||
@world = null
|
||||
@level = null
|
||||
|
||||
formTaskResultsObject: (simulationResults) ->
|
||||
taskResults =
|
||||
taskID: @task.getTaskID()
|
||||
receiptHandle: @task.getReceiptHandle()
|
||||
originalSessionID: @task.getFirstSessionID()
|
||||
originalSessionRank: -1
|
||||
calculationTime: 500
|
||||
sessions: []
|
||||
|
||||
for session in @task.getSessions()
|
||||
|
||||
sessionResult =
|
||||
sessionID: session.sessionID
|
||||
submitDate: session.submitDate
|
||||
creator: session.creator
|
||||
metrics:
|
||||
rank: @calculateSessionRank session.sessionID, simulationResults.goalStates, @task.generateTeamToSessionMap()
|
||||
if session.sessionID is taskResults.originalSessionID
|
||||
taskResults.originalSessionRank = sessionResult.metrics.rank
|
||||
taskResults.originalSessionTeam = session.team
|
||||
taskResults.sessions.push sessionResult
|
||||
|
||||
return taskResults
|
||||
|
||||
calculateSessionRank: (sessionID, goalStates, teamSessionMap) ->
|
||||
humansDestroyed = goalStates["destroy-humans"].status is "success"
|
||||
ogresDestroyed = goalStates["destroy-ogres"].status is "success"
|
||||
if humansDestroyed is ogresDestroyed
|
||||
return 0
|
||||
else if humansDestroyed and teamSessionMap["ogres"] is sessionID
|
||||
return 0
|
||||
else if humansDestroyed and teamSessionMap["ogres"] isnt sessionID
|
||||
return 1
|
||||
else if ogresDestroyed and teamSessionMap["humans"] is sessionID
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
manuallyGenerateGoalStates: ->
|
||||
goalStates =
|
||||
"destroy-humans":
|
||||
keyFrame: 0
|
||||
killed:
|
||||
"Human Base": false
|
||||
status: "incomplete"
|
||||
"destroy-ogres":
|
||||
keyFrame:0
|
||||
killed:
|
||||
"Ogre Base": false
|
||||
status: "incomplete"
|
||||
|
||||
setupGodSpells: ->
|
||||
@generateSpellsObject()
|
||||
@god.spells = @spells
|
||||
|
||||
generateSpellsObject: ->
|
||||
@currentUserCodeMap = @task.generateSpellKeyToSourceMap()
|
||||
@spells = {}
|
||||
for thang in @level.attributes.thangs
|
||||
continue if @thangIsATemplate thang
|
||||
@generateSpellKeyToSourceMapPropertiesFromThang thang
|
||||
|
||||
thangIsATemplate: (thang) ->
|
||||
for component in thang.components
|
||||
continue unless @componentHasProgrammableMethods component
|
||||
for methodName, method of component.config.programmableMethods
|
||||
return true if @methodBelongsToTemplateThang method
|
||||
|
||||
return false
|
||||
|
||||
componentHasProgrammableMethods: (component) -> component.config? and _.has component.config, 'programmableMethods'
|
||||
|
||||
methodBelongsToTemplateThang: (method) -> typeof method is 'string'
|
||||
|
||||
generateSpellKeyToSourceMapPropertiesFromThang: (thang) =>
|
||||
for component in thang.components
|
||||
continue unless @componentHasProgrammableMethods component
|
||||
for methodName, method of component.config.programmableMethods
|
||||
spellKey = @generateSpellKeyFromThangIDAndMethodName thang.id, methodName
|
||||
|
||||
@createSpellAndAssignName spellKey, methodName
|
||||
@createSpellThang thang, method, spellKey
|
||||
@transpileSpell thang, spellKey, methodName
|
||||
|
||||
generateSpellKeyFromThangIDAndMethodName: (thang, methodName) ->
|
||||
spellKeyComponents = [thang, methodName]
|
||||
spellKeyComponents[0] = _.string.slugify spellKeyComponents[0]
|
||||
spellKey = spellKeyComponents.join '/'
|
||||
spellKey
|
||||
|
||||
|
||||
createSpellAndAssignName: (spellKey, spellName) ->
|
||||
@spells[spellKey] ?= {}
|
||||
@spells[spellKey].name = spellName
|
||||
|
||||
createSpellThang: (thang, method, spellKey) ->
|
||||
@spells[spellKey].thangs ?= {}
|
||||
@spells[spellKey].thangs[thang.id] ?= {}
|
||||
@spells[spellKey].thangs[thang.id].aether = @createAether @spells[spellKey].name, method
|
||||
|
||||
transpileSpell: (thang, spellKey, methodName) ->
|
||||
slugifiedThangID = _.string.slugify thang.id
|
||||
source = @currentUserCodeMap[[slugifiedThangID,methodName].join '/'] ? ""
|
||||
@spells[spellKey].thangs[thang.id].aether.transpile source
|
||||
|
||||
createAether: (methodName, method) ->
|
||||
aetherOptions =
|
||||
functionName: methodName
|
||||
protectAPI: false
|
||||
includeFlow: false
|
||||
#includeFlow: true
|
||||
requiresThis: true
|
||||
yieldConditionally: false
|
||||
problems:
|
||||
jshint_W040: {level: "ignore"}
|
||||
jshint_W030: {level: "ignore"} # aether_NoEffect instead
|
||||
aether_MissingThis: {level: 'error'}
|
||||
#functionParameters: # TODOOOOO
|
||||
if methodName is 'hear'
|
||||
aetherOptions.functionParameters = ['speaker', 'message', 'data']
|
||||
#console.log "creating aether with options", aetherOptions
|
||||
return new Aether aetherOptions
|
||||
|
||||
class SimulationTask
|
||||
constructor: (@rawData) ->
|
||||
console.log 'Simulating sessions', (session for session in @getSessions())
|
||||
|
||||
getLevelName: ->
|
||||
levelName = @rawData.sessions?[0]?.levelID
|
||||
return levelName if levelName?
|
||||
@throwMalformedTaskError "The level name couldn't be deduced from the task."
|
||||
|
||||
generateTeamToSessionMap: ->
|
||||
teamSessionMap = {}
|
||||
for session in @rawData.sessions
|
||||
@throwMalformedTaskError "Two players share the same team" if teamSessionMap[session.team]?
|
||||
teamSessionMap[session.team] = session.sessionID
|
||||
|
||||
teamSessionMap
|
||||
|
||||
throwMalformedTaskError: (errorString) ->
|
||||
throw new Error "The task was malformed, reason: #{errorString}"
|
||||
|
||||
getFirstSessionID: -> @rawData.sessions[0].sessionID
|
||||
|
||||
getTaskID: -> @rawData.taskID
|
||||
|
||||
getReceiptHandle: -> @rawData.receiptHandle
|
||||
|
||||
getSessions: -> @rawData.sessions
|
||||
|
||||
generateSpellKeyToSourceMap: ->
|
||||
spellKeyToSourceMap = {}
|
||||
for session in @rawData.sessions
|
||||
teamSpells = session.teamSpells[session.team]
|
||||
teamCode = {}
|
||||
for thangName, thangSpells of session.code
|
||||
for spellName, spell of thangSpells
|
||||
fullSpellName = [thangName,spellName].join '/'
|
||||
if _.contains(teamSpells, fullSpellName)
|
||||
teamCode[fullSpellName]=spell
|
||||
|
||||
_.merge spellKeyToSourceMap, teamCode
|
||||
commonSpells = session.teamSpells["common"]
|
||||
_.merge spellKeyToSourceMap, _.pick(session.code, commonSpells) if commonSpells?
|
||||
|
||||
|
||||
spellKeyToSourceMap
|
|
@ -3,7 +3,7 @@
|
|||
module.exports = class SpriteBuilder
|
||||
constructor: (@thangType, @options) ->
|
||||
@options ?= {}
|
||||
raw = _.cloneDeep(@thangType.get('raw'))
|
||||
raw = @thangType.get('raw')
|
||||
@shapeStore = raw.shapes
|
||||
@containerStore = raw.containers
|
||||
@animationStore = raw.animations
|
||||
|
@ -124,7 +124,7 @@ module.exports = class SpriteBuilder
|
|||
cont.addChild(child)
|
||||
cont.bounds = new createjs.Rectangle(contData.b...)
|
||||
cont
|
||||
|
||||
|
||||
buildColorMaps: ->
|
||||
@colorMap = {}
|
||||
colorGroups = @thangType.get('colorGroups')
|
||||
|
@ -136,15 +136,15 @@ module.exports = class SpriteBuilder
|
|||
for group, config of colorConfig
|
||||
continue unless colorGroups[group] # color group not found...
|
||||
@buildColorMapForGroup(colorGroups[group], config)
|
||||
|
||||
|
||||
buildColorMapForGroup: (shapes, config) ->
|
||||
return unless shapes.length
|
||||
colors = @initColorMap(shapes)
|
||||
@adjustHuesForColorMap(colors, config.hue)
|
||||
@adjustValueForColorMap(colors, 1, config.lightness)
|
||||
@adjustValueForColorMap(colors, 2, config.saturation)
|
||||
@adjustValueForColorMap(colors, 1, config.saturation)
|
||||
@adjustValueForColorMap(colors, 2, config.lightness)
|
||||
@applyColorMap(shapes, colors)
|
||||
|
||||
|
||||
initColorMap: (shapes) ->
|
||||
colors = {}
|
||||
for shapeKey in shapes
|
||||
|
@ -156,18 +156,18 @@ module.exports = class SpriteBuilder
|
|||
|
||||
adjustHuesForColorMap: (colors, targetHue) ->
|
||||
hues = (hsl[0] for hex, hsl of colors)
|
||||
|
||||
|
||||
# 'rotate' the hue spectrum so averaging works
|
||||
if Math.max(hues) - Math.min(hues) > 0.5
|
||||
hues = (if h < 0.5 then h + 1.0 else h for h in hues)
|
||||
averageHue = sum(hues) / hues.length
|
||||
averageHue %= 1
|
||||
# end result should be something like a hue array of [0.9, 0.3] gets an average of 0.1
|
||||
|
||||
|
||||
targetHue ?= 0
|
||||
diff = targetHue - averageHue
|
||||
hsl[0] = (hsl[0] + diff + 1) % 1 for hex, hsl of colors
|
||||
|
||||
|
||||
adjustValueForColorMap: (colors, index, targetValue) ->
|
||||
values = (hsl[index] for hex, hsl of colors)
|
||||
averageValue = sum(values) / values.length
|
||||
|
@ -183,4 +183,4 @@ module.exports = class SpriteBuilder
|
|||
@colorMap[shapeKey] = hslToHex(colors[shape.fc])
|
||||
|
||||
|
||||
sum = (nums) -> _.reduce(nums, (s, num) -> s + num)
|
||||
sum = (nums) -> _.reduce(nums, (s, num) -> s + num)
|
||||
|
|
|
@ -11,5 +11,5 @@ module.exports.load = (key) ->
|
|||
module.exports.save = (key, value) ->
|
||||
s = JSON.stringify(value)
|
||||
localStorage.setItem(key, s)
|
||||
|
||||
module.exports.remove = (key) -> localStorage.removeItem key
|
||||
|
||||
module.exports.remove = (key) -> localStorage.removeItem key
|
||||
|
|
|
@ -40,10 +40,13 @@ module.exports = class Camera extends CocoClass
|
|||
'camera-zoom-out': 'onZoomOut'
|
||||
'surface:mouse-scrolled': 'onMouseScrolled'
|
||||
'level:restarted': 'onLevelRestarted'
|
||||
'sprite:mouse-down': 'onMouseDown'
|
||||
'sprite:dragged': 'onMouseDragged'
|
||||
|
||||
# TODO: Fix tests to not use mainLayer
|
||||
constructor: (@canvasWidth, @canvasHeight, angle=Math.asin(0.75), hFOV=d2r(30)) ->
|
||||
super()
|
||||
@offset = {x: 0, y:0}
|
||||
@calculateViewingAngle angle
|
||||
@calculateFieldOfView hFOV
|
||||
@calculateAxisConversionFactors()
|
||||
|
@ -148,19 +151,48 @@ module.exports = class Camera extends CocoClass
|
|||
onMouseScrolled: (e) ->
|
||||
ratio = 1 + 0.05 * Math.sqrt(Math.abs(e.deltaY))
|
||||
ratio = 1 / ratio if e.deltaY > 0
|
||||
@zoomTo @target, @zoom * ratio, 0
|
||||
newZoom = @zoom * ratio
|
||||
if e.surfacePos and not @focusedOnSprite()
|
||||
# zoom based on mouse position, adjusting the target so the point under the mouse stays the same
|
||||
mousePoint = @canvasToSurface(e.surfacePos)
|
||||
ratioPosX = (mousePoint.x - @surfaceViewport.x) / @surfaceViewport.width
|
||||
ratioPosY = (mousePoint.y - @surfaceViewport.y) / @surfaceViewport.height
|
||||
newWidth = @canvasWidth / newZoom
|
||||
newHeight = @canvasHeight / newZoom
|
||||
newTargetX = mousePoint.x - (newWidth * ratioPosX) + (newWidth / 2)
|
||||
newTargetY = mousePoint.y - (newHeight * ratioPosY) + (newHeight / 2)
|
||||
target = {x: newTargetX, y:newTargetY}
|
||||
else
|
||||
target = @target
|
||||
@zoomTo target, newZoom, 0
|
||||
|
||||
onMouseDown: (e) ->
|
||||
return if @dragDisabled
|
||||
@lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY}
|
||||
|
||||
onMouseDragged: (e) ->
|
||||
return if @dragDisabled
|
||||
target = @boundTarget(@target, @zoom)
|
||||
newPos = {
|
||||
x: target.x + (@lastPos.x - e.originalEvent.rawX) / @zoom
|
||||
y: target.y + (@lastPos.y - e.originalEvent.rawY) / @zoom
|
||||
}
|
||||
@zoomTo newPos, @zoom, 0
|
||||
@lastPos = {x: e.originalEvent.rawX, y: e.originalEvent.rawY}
|
||||
Backbone.Mediator.publish 'camera:dragged'
|
||||
|
||||
onLevelRestarted: ->
|
||||
@setBounds(@firstBounds)
|
||||
@setBounds(@firstBounds, false)
|
||||
|
||||
# COMMANDS
|
||||
|
||||
setBounds: (worldBounds) ->
|
||||
setBounds: (worldBounds, updateZoom=true) ->
|
||||
# receives an array of two world points. Normalize and apply them
|
||||
@firstBounds = worldBounds unless @firstBounds
|
||||
@bounds = @normalizeBounds(worldBounds)
|
||||
@calculateMinZoom()
|
||||
@updateZoom true
|
||||
@target = @currentTarget unless @target.name
|
||||
@updateZoom true if updateZoom
|
||||
@target = @currentTarget unless @focusedOnSprite()
|
||||
|
||||
normalizeBounds: (worldBounds) ->
|
||||
return null unless worldBounds
|
||||
|
@ -186,8 +218,18 @@ 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)
|
||||
|
||||
thangType = @target?.sprite?.thangType
|
||||
if thangType
|
||||
@offset = _.clone(thangType.get('positions')?.torso or {x: 0, y:0})
|
||||
scale = thangType.get('scale') or 1
|
||||
@offset.x *= scale
|
||||
@offset.y *= scale
|
||||
else
|
||||
@offset = {x: 0, y:0}
|
||||
|
||||
return if @zoom is newZoom and newTarget is newTarget.x and newTarget.y is newTarget.y
|
||||
|
||||
@finishTween(true)
|
||||
|
@ -199,19 +241,20 @@ 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()
|
||||
|
||||
focusedOnSprite: ->
|
||||
return @target?.name
|
||||
|
||||
finishTween: (abort=false) =>
|
||||
createjs.Tween.removeTweens(@)
|
||||
return unless @newTarget
|
||||
unless abort
|
||||
unless abort is true
|
||||
@target = @newTarget
|
||||
@zoom = @newZoom
|
||||
@newZoom = @oldZoom = @newTarget = @newTarget = @tweenProgress = null
|
||||
|
@ -219,7 +262,7 @@ module.exports = class Camera extends CocoClass
|
|||
|
||||
updateZoom: (force=false) ->
|
||||
# Update when we're focusing on a Thang, tweening, or forcing it, unless we're locked
|
||||
return if (not force) and (@locked or (not @newTarget and not @target?.name))
|
||||
return if (not force) and (@locked or (not @newTarget and not @focusedOnSprite()))
|
||||
if @newTarget
|
||||
t = @tweenProgress
|
||||
@zoom = @oldZoom + t * (@newZoom - @oldZoom)
|
||||
|
@ -237,8 +280,8 @@ module.exports = class Camera extends CocoClass
|
|||
return pos unless @bounds
|
||||
marginX = (@canvasWidth / zoom / 2)
|
||||
marginY = (@canvasHeight / zoom / 2)
|
||||
x = Math.min(Math.max(marginX + @bounds.x, pos.x), @bounds.x + @bounds.width - marginX)
|
||||
y = Math.min(Math.max(marginY + @bounds.y, pos.y), @bounds.y + @bounds.height - marginY)
|
||||
x = Math.min(Math.max(marginX + @bounds.x, pos.x + @offset.x), @bounds.x + @bounds.width - marginX)
|
||||
y = Math.min(Math.max(marginY + @bounds.y, pos.y + @offset.y), @bounds.y + @bounds.height - marginY)
|
||||
{x: x, y: y}
|
||||
|
||||
updateViewports: (target) ->
|
||||
|
@ -260,3 +303,8 @@ module.exports = class Camera extends CocoClass
|
|||
@locked = true
|
||||
unlock: ->
|
||||
@locked = false
|
||||
|
||||
destroy: ->
|
||||
createjs.Tween.removeTweens @
|
||||
@finishTween = null
|
||||
super()
|
||||
|
|
81
app/lib/surface/CastingScreen.coffee
Normal file
|
@ -0,0 +1,81 @@
|
|||
CocoClass = require 'lib/CocoClass'
|
||||
|
||||
module.exports = class CastingScreen extends CocoClass
|
||||
subscriptions:
|
||||
'tome:cast-spells': 'onCastingBegins'
|
||||
'god:new-world-created': 'onCastingEnds'
|
||||
'god:world-load-progress-changed': 'onWorldLoadProgressChanged'
|
||||
|
||||
constructor: (options) ->
|
||||
super()
|
||||
options ?= {}
|
||||
@camera = options.camera
|
||||
@layer = options.layer
|
||||
console.error @toString(), "needs a camera." unless @camera
|
||||
console.error @toString(), "needs a layer." unless @layer
|
||||
@build()
|
||||
|
||||
onCastingBegins: -> @show()
|
||||
onCastingEnds: -> @hide()
|
||||
|
||||
toString: -> "<CastingScreen>"
|
||||
|
||||
build: ->
|
||||
@dimLayer = new createjs.Container()
|
||||
@dimLayer.mouseEnabled = @dimLayer.mouseChildren = false
|
||||
@dimLayer.layerIndex = -11
|
||||
@dimLayer.addChild @dimScreen = new createjs.Shape()
|
||||
@dimScreen.graphics.beginFill("rgba(0,0,0,0.5)").rect 0, 0, @camera.canvasWidth, @camera.canvasHeight
|
||||
@dimLayer.alpha = 0
|
||||
@layer.addChild @dimLayer
|
||||
@dimLayer.addChild @makeProgressBar()
|
||||
@dimLayer.addChild @makeCastingText()
|
||||
|
||||
onWorldLoadProgressChanged: (e) ->
|
||||
if new Date().getTime() - @t0 > 500
|
||||
createjs.Tween.removeTweens @progressBar
|
||||
createjs.Tween.get(@progressBar).to({scaleX:e.progress}, 200)
|
||||
|
||||
makeProgressBar: ->
|
||||
BAR_PIXEL_HEIGHT = 3
|
||||
BAR_PCT_WIDTH = .75
|
||||
pixelWidth = parseInt(@camera.canvasWidth * BAR_PCT_WIDTH)
|
||||
pixelMargin = (@camera.canvasWidth - (@camera.canvasWidth * BAR_PCT_WIDTH)) / 2
|
||||
barY = 3 * (@camera.canvasHeight / 5)
|
||||
|
||||
g = new createjs.Graphics()
|
||||
g.beginFill(createjs.Graphics.getRGB(255,255, 255))
|
||||
g.drawRoundRect(0,0,pixelWidth, BAR_PIXEL_HEIGHT, 3)
|
||||
@progressBar = new createjs.Shape(g)
|
||||
@progressBar.x = pixelMargin
|
||||
@progressBar.y = barY
|
||||
@progressBar.scaleX = 0
|
||||
@dimLayer.addChild(@progressBar)
|
||||
|
||||
makeCastingText: ->
|
||||
size = @camera.canvasHeight / 15
|
||||
text = new createjs.Text("Casting", "#{size}px cursive", "#aaaaaa")
|
||||
text.regX = text.getMeasuredWidth() / 2
|
||||
text.regY = text.getMeasuredHeight() / 2
|
||||
text.x = @camera.canvasWidth / 2
|
||||
text.y = @camera.canvasHeight / 2
|
||||
@text = text
|
||||
return text
|
||||
|
||||
show: ->
|
||||
return if @showing
|
||||
@showing = true
|
||||
@t0 = new Date().getTime()
|
||||
|
||||
@progressBar.scaleX = 0
|
||||
@dimLayer.alpha = 0
|
||||
createjs.Tween.removeTweens @dimLayer
|
||||
createjs.Tween.get(@dimLayer).to({alpha:1}, 500)
|
||||
|
||||
hide: ->
|
||||
return unless @showing
|
||||
@showing = false
|
||||
|
||||
createjs.Tween.removeTweens @progressBar
|
||||
createjs.Tween.removeTweens @dimLayer
|
||||
createjs.Tween.get(@dimLayer).to({alpha:0}, 500)
|
|
@ -4,6 +4,7 @@ Camera = require './Camera'
|
|||
Mark = require './Mark'
|
||||
Label = require './Label'
|
||||
AudioPlayer = require 'lib/AudioPlayer'
|
||||
{me} = require 'lib/auth'
|
||||
|
||||
# We'll get rid of this once level's teams actually have colors
|
||||
healthColors =
|
||||
|
@ -64,26 +65,29 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@age = 0
|
||||
@displayObject = new createjs.Container()
|
||||
if @thangType.get('actions')
|
||||
@onThangTypeLoaded()
|
||||
@setupSprite()
|
||||
else
|
||||
@stillLoading = true
|
||||
@thangType.fetch()
|
||||
@thangType.once 'sync', @onThangTypeLoaded, @
|
||||
@thangType.once 'sync', @setupSprite, @
|
||||
|
||||
onThangTypeLoaded: ->
|
||||
setupSprite: ->
|
||||
@stillLoading = false
|
||||
@actions = @thangType.getActions()
|
||||
@buildFromSpriteSheet @buildSpriteSheet()
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
mark.destroy() for name, mark of @marks
|
||||
label.destroy() for name, label of @labels
|
||||
@imageObject?.off 'animationend', @playNextAction
|
||||
@playNextAction = null
|
||||
@displayObject?.off()
|
||||
super()
|
||||
|
||||
toString: -> "<CocoSprite: #{@thang?.id}>"
|
||||
|
||||
buildSpriteSheet: ->
|
||||
options = @thang?.getSpriteOptions?() or {}
|
||||
options = _.extend @options, @thang?.getSpriteOptions?() ? {}
|
||||
options.colorConfig = @options.colorConfig if @options.colorConfig
|
||||
options.async = false
|
||||
@thangType.getSpriteSheet options
|
||||
|
@ -97,6 +101,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
# temp, until these are re-exported with perspective
|
||||
if @options.camera and @thangType.get('name') in ['Dungeon Floor', 'Indoor Floor', 'Grass', 'Goal Trigger', 'Obstacle']
|
||||
sprite.scaleY *= @options.camera.y2x
|
||||
@displayObject.removeChild(@imageObject) if @imageObject
|
||||
@imageObject = sprite
|
||||
@displayObject.addChild(sprite)
|
||||
@addHealthBar()
|
||||
|
@ -107,7 +112,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
|
||||
|
@ -120,21 +125,24 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@actionQueue.push @currentRootAction.relatedActions.end if @currentRootAction?.relatedActions?.end
|
||||
@actionQueue.push action.relatedActions.begin if action.relatedActions?.begin
|
||||
@actionQueue.push action
|
||||
if action.goesTo and nextAction = @actions[action.goesTo]
|
||||
@actionQueue.push nextAction if nextAction
|
||||
@currentRootAction = action
|
||||
@playNextAction()
|
||||
|
||||
onActionEnd: (e) => @playNextAction()
|
||||
onSurfaceTicked: (e) -> @age += e.dt
|
||||
|
||||
playNextAction: ->
|
||||
playNextAction: =>
|
||||
@playAction(@actionQueue.splice(0,1)[0]) if @actionQueue.length
|
||||
|
||||
playAction: (action) ->
|
||||
@currentAction = action
|
||||
return @hide() unless action.animation or action.container or action.relatedActions
|
||||
@show()
|
||||
return @updateActionDirection() unless action.animation or action.container
|
||||
m = if action.container then "gotoAndStop" else "gotoAndPlay"
|
||||
@imageObject[m] action.name
|
||||
@imageObject.framerate = action.framerate or 20
|
||||
@imageObject[m] action.name
|
||||
reg = @getOffset 'registration'
|
||||
@imageObject.regX = -reg.x
|
||||
@imageObject.regY = -reg.y
|
||||
|
@ -142,6 +150,22 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
start = Math.floor(Math.random() * action.frames.length)
|
||||
@imageObject.currentAnimationFrame = start
|
||||
|
||||
hide: ->
|
||||
@hiding = true
|
||||
@updateAlpha()
|
||||
|
||||
show: ->
|
||||
@hiding = false
|
||||
@updateAlpha()
|
||||
|
||||
stop: ->
|
||||
@imageObject?.stop?()
|
||||
mark.stop() for name, mark of @marks
|
||||
|
||||
play: ->
|
||||
@imageObject?.play?()
|
||||
mark.play() for name, mark of @marks
|
||||
|
||||
update: ->
|
||||
# Gets the sprite to reflect what the current state of the thangs and surface are
|
||||
return if @stillLoading
|
||||
|
@ -153,6 +177,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@updateStats()
|
||||
@updateMarks()
|
||||
@updateLabels()
|
||||
@updateGold()
|
||||
|
||||
cache: ->
|
||||
bounds = @imageObject.getBounds()
|
||||
|
@ -181,16 +206,22 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
if @thang.width isnt @lastThangWidth or @thang.height isnt @lastThangHeight
|
||||
[@lastThangWidth, @lastThangHeight] = [@thang.width, @thang.height]
|
||||
bounds = @imageObject.getBounds()
|
||||
@imageObject.scaleX = @thang.width * Camera.PPM / bounds.width * @thangType.get('scale') ? 1
|
||||
@imageObject.scaleY = @thang.height * Camera.PPM * @options.camera.y2x / bounds.height * @thangType.get('scale') ? 1
|
||||
@imageObject.scaleX = @thang.width * Camera.PPM / bounds.width
|
||||
@imageObject.scaleY = @thang.height * Camera.PPM * @options.camera.y2x / bounds.height
|
||||
unless @thang.spriteName is 'Beam'
|
||||
@imageObject.scaleX *= @thangType.get('scale') ? 1
|
||||
@imageObject.scaleY *= @thangType.get('scale') ? 1
|
||||
return
|
||||
scaleX = if @getActionProp 'flipX' then -1 else 1
|
||||
scaleY = if @getActionProp 'flipY' then -1 else 1
|
||||
scaleFactor = @thang.scaleFactor ? 1
|
||||
@imageObject.scaleX = @originalScaleX * scaleX * scaleFactor
|
||||
@imageObject.scaleY = @originalScaleY * scaleY * scaleFactor
|
||||
scaleFactorX = @thang.scaleFactorX ? scaleFactor
|
||||
scaleFactorY = @thang.scaleFactorY ? scaleFactor
|
||||
@imageObject.scaleX = @originalScaleX * scaleX * scaleFactorX
|
||||
@imageObject.scaleY = @originalScaleY * scaleY * scaleFactorY
|
||||
|
||||
updateAlpha: ->
|
||||
@imageObject.alpha = if @hiding then 0 else 1
|
||||
return unless @thang?.alpha?
|
||||
@imageObject.alpha = @thang.alpha
|
||||
if @options.showInvisible
|
||||
|
@ -394,7 +425,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) ->
|
||||
|
@ -414,9 +445,20 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@notifySpeechUpdated blurb: blurb
|
||||
label.update() for name, label of @labels
|
||||
|
||||
updateGold: ->
|
||||
# TODO: eventually this should be moved into some sort of team-based update
|
||||
# rather than an each-thang-that-shows-gold-per-team thing.
|
||||
return if @thang.gold is @lastGold
|
||||
gold = Math.floor @thang.gold
|
||||
return if gold is @lastGold
|
||||
@lastGold = gold
|
||||
Backbone.Mediator.publish 'surface:gold-changed', {team: @thang.team, gold: gold}
|
||||
|
||||
playSounds: (withDelay=true, volume=1.0) ->
|
||||
for event in @thang.currentEvents ? []
|
||||
@playSound event, withDelay, volume
|
||||
if event is 'pay-bounty-gold' and @thang.bountyGold > 25 and @thang.team isnt me.team
|
||||
AudioPlayer.playInterfaceSound 'coin_1', 0.25
|
||||
if @thang.actionActivated and (action = @thang.getActionName()) isnt 'say'
|
||||
@playSound action, withDelay, volume
|
||||
if @thang.sayMessage and withDelay # don't play sayMessages while scrubbing, annoying
|
||||
|
@ -433,6 +475,6 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
return null unless sound
|
||||
delay = if withDelay and sound.delay then 1000 * sound.delay / createjs.Ticker.getFPS() else 0
|
||||
name = AudioPlayer.nameForSoundReference sound
|
||||
instance = createjs.Sound.play name, "none", delay, 0, 0, volume
|
||||
instance = AudioPlayer.playSound name, volume, delay
|
||||
# console.log @thang?.id, "played sound", name, "with delay", delay, "volume", volume, "and got sound instance", instance
|
||||
instance
|
||||
|
|
|
@ -12,11 +12,13 @@ module.exports = class CoordinateDisplay extends createjs.Container
|
|||
@camera = options.camera
|
||||
console.error "CoordinateDisplay needs camera." unless @camera
|
||||
@build()
|
||||
@show = _.debounce @show, 250
|
||||
@show = _.debounce @show, 125
|
||||
Backbone.Mediator.subscribe(channel, @[func], @) for channel, func of @subscriptions
|
||||
|
||||
destroy: ->
|
||||
Backbone.Mediator.unsubscribe(channel, @[func], @) for channel, func of @subscriptions
|
||||
@show = null
|
||||
@destroyed = true
|
||||
|
||||
build: ->
|
||||
@mouseEnabled = @mouseChildren = false
|
||||
|
@ -46,14 +48,14 @@ module.exports = class CoordinateDisplay extends createjs.Container
|
|||
@uncache()
|
||||
|
||||
show: =>
|
||||
return unless @mouseInBounds and @lastPos
|
||||
return unless @mouseInBounds and @lastPos and not @destroyed
|
||||
@label.text = "(#{@lastPos.x}, #{@lastPos.y})"
|
||||
[width, height] = [@label.getMeasuredWidth(), @label.getMeasuredHeight()]
|
||||
@label.regX = width / 2
|
||||
@label.regY = height / 2
|
||||
sup = @camera.worldToSurface @lastPos
|
||||
@x = sup.x
|
||||
@y = sup.y
|
||||
@y = sup.y - 7
|
||||
@addChild @label
|
||||
@cache -width / 2, -height / 2, width, height
|
||||
Backbone.Mediator.publish 'surface:coordinates-shown', {}
|
||||
|
|
|
@ -21,9 +21,6 @@ module.exports = class Dimmer extends CocoClass
|
|||
@highlightedThangIDs = []
|
||||
@sprites = {}
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
|
||||
toString: -> "<Dimmer>"
|
||||
|
||||
build: ->
|
||||
|
|
|
@ -22,6 +22,7 @@ module.exports = IndieSprite = class IndieSprite extends CocoSprite
|
|||
thang.width = thang.height = thang.depth = 4
|
||||
thang.pos = pos ? @defaultPos()
|
||||
thang.pos.z = thang.depth / 2
|
||||
thang.shape = 'ellipsoid'
|
||||
thang.rotation = 0
|
||||
thang.action = 'idle'
|
||||
thang.setAction = (action) -> thang.action = action
|
||||
|
|
|
@ -54,17 +54,19 @@ module.exports = class Label extends CocoClass
|
|||
buildLabelOptions: ->
|
||||
o = {}
|
||||
st = {dialogue: 'D', say: 'S', name: 'N'}[@style]
|
||||
o.marginX = {D: 5, S: 2, N: 3}[st]
|
||||
o.marginY = {D: 6, S: 2, N: 3}[st]
|
||||
o.marginX = {D: 5, S: 6, N: 3}[st]
|
||||
o.marginY = {D: 6, S: 4, N: 3}[st]
|
||||
o.fontWeight = {D: "bold", S: "bold", N: "bold"}[st]
|
||||
o.shadow = {D: false, S: true, N: true}[st]
|
||||
o.fontSize = {D: 25, S: 19, N: 14}[st]
|
||||
o.shadowColor = {D: "#FFF", S: "#000", N: "#FFF"}[st]
|
||||
o.fontSize = {D: 25, S: 12, N: 12}[st]
|
||||
fontFamily = {D: "Arial", S: "Arial", N: "Arial"}[st]
|
||||
o.fontDescriptor = "#{o.fontSize}px #{fontFamily}"
|
||||
o.fontColor = {D: "#000", S: "#000", N: "#00a"}[st]
|
||||
o.backgroundFillColor = {D: "white", S: "rgba(255, 255, 255, 0.2)", N: "rgba(255, 255, 255, 0.5)"}[st]
|
||||
o.backgroundStrokeColor = {D: "black", S: "rgba(0, 0, 0, 0.2)", N: "rgba(0, 0, 0, 0.0)"}[st]
|
||||
o.fontDescriptor = "#{o.fontWeight} #{o.fontSize}px #{fontFamily}"
|
||||
o.fontColor = {D: "#000", S: "#FFF", N: "#00a"}[st]
|
||||
o.backgroundFillColor = {D: "white", S: "rgba(0, 0, 0, 0.4)", N: "rgba(255, 255, 255, 0.5)"}[st]
|
||||
o.backgroundStrokeColor = {D: "black", S: "rgba(0, 0, 0, .6)", N: "rgba(0, 0, 0, 0.0)"}[st]
|
||||
o.backgroundStrokeStyle = {D: 2, S: 1, N: 1}[st]
|
||||
o.backgroundBorderRadius = {D: 10, S: 5, N: 3}[st]
|
||||
o.backgroundBorderRadius = {D: 10, S: 3, N: 3}[st]
|
||||
o.layerPriority = {D: 10, S: 5, N: 5}[st]
|
||||
maxWidth = {D: 300, S: 300, N: 180}[st]
|
||||
maxWidth = Math.max @camera.canvasWidth / 2 - 100, maxWidth # Does this do anything?
|
||||
|
@ -79,7 +81,7 @@ module.exports = class Label extends CocoClass
|
|||
label.lineHeight = o.fontSize + 2
|
||||
label.x = o.marginX
|
||||
label.y = o.marginY
|
||||
label.shadow = new createjs.Shadow "#FFF", 1, 1, 0 if o.shadow
|
||||
label.shadow = new createjs.Shadow o.shadowColor, 1, 1, 0 if o.shadow
|
||||
label.layerPriority = o.layerPriority
|
||||
label.name = "Sprite Label - #{@style}"
|
||||
o.textHeight = label.getMeasuredHeight()
|
||||
|
|
|
@ -69,7 +69,7 @@ module.exports = class Layer extends createjs.Container
|
|||
bz = if b.z then b.z else 1000
|
||||
if az == bz
|
||||
return 0 unless a.sprite?.thang?.pos and b.sprite?.thang?.pos
|
||||
return b.sprite.thang.pos.y - a.sprite.thang.pos.y
|
||||
return (b.sprite.thang.pos.y - a.sprite.thang.pos.y) or (b.sprite.thang.pos.x - a.sprite.thang.pos.x)
|
||||
return az - bz
|
||||
|
||||
onZoomUpdated: (e) ->
|
||||
|
|
|
@ -19,6 +19,8 @@ module.exports = class Mark extends CocoClass
|
|||
|
||||
destroy: ->
|
||||
@mark?.parent?.removeChild @mark
|
||||
@markSprite?.destroy()
|
||||
@sprite = null
|
||||
super()
|
||||
|
||||
toString: -> "<Mark #{@name}: Sprite #{@sprite?.thang?.id ? 'None'}>"
|
||||
|
@ -46,7 +48,7 @@ module.exports = class Mark extends CocoClass
|
|||
build: ->
|
||||
unless @mark
|
||||
if @name is 'bounds' then @buildBounds()
|
||||
else if @name is 'shadow' then @buildRadius()
|
||||
else if @name is 'shadow' then @buildShadow()
|
||||
else if @name is 'debug' then @buildDebug()
|
||||
else if @thangType then @buildSprite()
|
||||
else console.error "Don't know how to build mark for", @name
|
||||
|
@ -85,21 +87,31 @@ module.exports = class Mark extends CocoClass
|
|||
@lastWidth = @sprite.thang.width
|
||||
@lastHeight = @sprite.thang.height
|
||||
|
||||
buildRadius: ->
|
||||
# TODO: make this not just a shadow
|
||||
# TODO: draw boxes and ellipses for non-circular Thangs
|
||||
diameter = @sprite.thangType.get('shadow') ? @sprite.thang?.width + 0.5
|
||||
diameter *= Camera.PPM
|
||||
buildShadow: ->
|
||||
width = (@sprite.thang?.width ? 0) + 0.5
|
||||
height = (@sprite.thang?.height ? 0) + 0.5
|
||||
longest = Math.max width, height
|
||||
actualLongest = @sprite.thangType.get('shadow') ? longest
|
||||
width = width * actualLongest / longest
|
||||
height = height * actualLongest / longest
|
||||
width *= Camera.PPM
|
||||
height *= Camera.PPM * @camera.y2x # TODO: doesn't work with rotation
|
||||
@mark = new createjs.Shape()
|
||||
@mark.mouseEnabled = false
|
||||
@mark.graphics.beginFill "black"
|
||||
@mark.graphics.drawEllipse 0, 0, diameter, diameter * @camera.y2x
|
||||
if @sprite.thang.shape in ['ellipsoid', 'disc']
|
||||
@mark.graphics.drawEllipse 0, 0, width, height
|
||||
else
|
||||
@mark.graphics.drawRect 0, 0, width, height
|
||||
@mark.graphics.endFill()
|
||||
@mark.regX = diameter / 2
|
||||
@mark.regY = diameter / 2 * @camera.y2x
|
||||
@mark.regX = width / 2
|
||||
@mark.regY = height / 2
|
||||
@mark.layerIndex = 10
|
||||
#@mark.cache 0, 0, diameter, diameter # not actually faster than simple ellipse draw
|
||||
|
||||
buildRadius: ->
|
||||
return # not implemented
|
||||
|
||||
buildDebug: ->
|
||||
@mark = new createjs.Shape()
|
||||
PX = 3
|
||||
|
@ -119,6 +131,7 @@ module.exports = class Mark extends CocoClass
|
|||
markSprite = new CocoSprite @thangType, @thangType.spriteOptions
|
||||
markSprite.queueAction 'idle'
|
||||
@mark = markSprite.displayObject
|
||||
@markSprite = markSprite
|
||||
|
||||
update: (pos=null) ->
|
||||
return false unless @on
|
||||
|
@ -149,7 +162,7 @@ module.exports = class Mark extends CocoClass
|
|||
@mark.y += offset.y
|
||||
|
||||
updateRotation: ->
|
||||
if @name is 'debug'
|
||||
if @name is 'debug' or (@name is 'shadow' and @sprite.thang?.shape in ["rectangle", "box"])
|
||||
@mark.rotation = @sprite.thang.rotation * 180 / Math.PI
|
||||
|
||||
updateScale: ->
|
||||
|
@ -171,3 +184,6 @@ module.exports = class Mark extends CocoClass
|
|||
@mark.scaleX = @mark.scaleY = Math.min 1, scale
|
||||
if @name in ['selection', 'target', 'repair']
|
||||
@mark.scaleY *= @camera.y2x # code applies perspective
|
||||
|
||||
stop: -> @markSprite?.stop()
|
||||
play: -> @markSprite?.play()
|
||||
|
|
|
@ -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,8 @@ 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: ->
|
||||
me.off 'change:music', @onMusicSettingChanged, @
|
||||
super()
|
||||
|
40
app/lib/surface/PlaybackOverScreen.coffee
Normal file
|
@ -0,0 +1,40 @@
|
|||
CocoClass = require 'lib/CocoClass'
|
||||
|
||||
module.exports = class PlaybackoverScreen extends CocoClass
|
||||
constructor: (options) ->
|
||||
super()
|
||||
options ?= {}
|
||||
@camera = options.camera
|
||||
@layer = options.layer
|
||||
console.error @toString(), "needs a camera." unless @camera
|
||||
console.error @toString(), "needs a layer." unless @layer
|
||||
@build()
|
||||
|
||||
toString: -> "<PlaybackoverScreen>"
|
||||
|
||||
build: ->
|
||||
@dimLayer = new createjs.Container()
|
||||
@dimLayer.mouseEnabled = @dimLayer.mouseChildren = false
|
||||
@dimLayer.layerIndex = -12
|
||||
@dimLayer.addChild @dimScreen = new createjs.Shape()
|
||||
@dimScreen.graphics.beginFill("rgba(0,0,0,0.4)").rect 0, 0, @camera.canvasWidth, @camera.canvasHeight
|
||||
@dimLayer.cache 0, 0, @camera.canvasWidth, @camera.canvasHeight
|
||||
@dimLayer.alpha = 0
|
||||
@layer.addChild @dimLayer
|
||||
|
||||
show: ->
|
||||
console.log 'show playback over screen', @showing
|
||||
return if @showing
|
||||
@showing = true
|
||||
|
||||
@dimLayer.alpha = 0
|
||||
createjs.Tween.removeTweens @dimLayer
|
||||
createjs.Tween.get(@dimLayer).to({alpha:1}, 500)
|
||||
|
||||
hide: ->
|
||||
console.log 'hide playback over screen', @showing
|
||||
return unless @showing
|
||||
@showing = false
|
||||
|
||||
createjs.Tween.removeTweens @dimLayer
|
||||
createjs.Tween.get(@dimLayer).to({alpha:0}, 500)
|
|
@ -5,10 +5,11 @@ module.exports = class PointChooser extends CocoClass
|
|||
super()
|
||||
@buildShape()
|
||||
@options.stage.addEventListener 'stagemousedown', @onMouseDown
|
||||
@options.camera.dragDisabled = true
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@options.stage.removeEventListener 'stagemousedown', @onMouseDown
|
||||
super()
|
||||
|
||||
# Called also from WorldSelectModal
|
||||
setPoint: (@point) ->
|
||||
|
|
|
@ -7,12 +7,13 @@ module.exports = class RegionChooser extends CocoClass
|
|||
@options.stage.addEventListener 'stagemousedown', @onMouseDown
|
||||
@options.stage.addEventListener 'stagemousemove', @onMouseMove
|
||||
@options.stage.addEventListener 'stagemouseup', @onMouseUp
|
||||
@options.camera.dragDisabled = true
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@options.stage.removeEventListener 'stagemousedown', @onMouseDown
|
||||
@options.stage.removeEventListener 'stagemousemove', @onMouseMove
|
||||
@options.stage.removeEventListener 'stagemouseup', @onMouseUp
|
||||
super()
|
||||
|
||||
onMouseDown: (e) =>
|
||||
return unless key.shift
|
||||
|
|
|
@ -13,15 +13,19 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
'bus:player-left': 'onPlayerLeft'
|
||||
'level-set-debug': 'onSetDebug'
|
||||
'level-highlight-sprites': 'onHighlightSprites'
|
||||
'sprite:mouse-down': 'onSpriteMouseDown'
|
||||
'sprite:mouse-up': 'onSpriteMouseUp'
|
||||
'surface:stage-mouse-down': 'onStageMouseDown'
|
||||
'level-select-sprite': 'onSelectSprite'
|
||||
'level-suppress-selection-sounds': 'onSuppressSelectionSounds'
|
||||
'level-lock-select': 'onSetLockSelect'
|
||||
'level:restarted': 'onLevelRestarted'
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
'tome:cast-spells': 'onCastSpells'
|
||||
'camera:dragged': 'onCameraDragged'
|
||||
|
||||
constructor: (@options) ->
|
||||
super()
|
||||
@dragged = 0
|
||||
@options ?= {}
|
||||
@camera = @options.camera
|
||||
@surfaceLayer = @options.surfaceLayer
|
||||
|
@ -34,10 +38,10 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
@spriteSheetCache = {}
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@removeSprite sprite for thangID, sprite of @sprites
|
||||
@targetMark?.destroy()
|
||||
@selectionMark?.destroy()
|
||||
super()
|
||||
|
||||
toString: -> "<SpriteBoss: #{@sprites.length} sprites>"
|
||||
|
||||
|
@ -87,7 +91,7 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
@selectionMark = new Mark name: 'selection', camera: @camera, layer: @spriteLayers["Ground"], thangType: @thangTypeFor("Selection")
|
||||
|
||||
createSpriteOptions: (options) ->
|
||||
_.extend options, camera: @camera, resolutionFactor: 4, groundLayer: @spriteLayers["Ground"], textLayer: @surfaceTextLayer, floatingLayer: @spriteLayers["Floating"], markThangTypes: @markThangTypes(), spriteSheetCache: @spriteSheetCache, showInvisible: @options.showInvisible, world: @world
|
||||
_.extend options, camera: @camera, resolutionFactor: 4, groundLayer: @spriteLayers["Ground"], textLayer: @surfaceTextLayer, floatingLayer: @spriteLayers["Floating"], markThangTypes: @markThangTypes(), spriteSheetCache: @spriteSheetCache, showInvisible: @options.showInvisible
|
||||
|
||||
createIndieSprites: (indieSprites, withWizards) ->
|
||||
unless @indieSprites
|
||||
|
@ -103,9 +107,14 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
unless thangType = @thangTypeFor indieSprite.thangType
|
||||
console.warn "Need to convert #{indieSprite.id}'s ThangType #{indieSprite.thangType} to a ThangType reference. Until then, #{indieSprite.id} won't show up."
|
||||
return
|
||||
sprite = new IndieSprite thangType, @createSpriteOptions {thangID: indieSprite.id, pos: indieSprite.pos, sprites: @sprites}
|
||||
sprite = new IndieSprite thangType, @createSpriteOptions {thangID: indieSprite.id, pos: indieSprite.pos, sprites: @sprites, colorConfig: indieSprite.colorConfig}
|
||||
@addSprite sprite, sprite.thang.id
|
||||
|
||||
createOpponentWizard: (opponent) ->
|
||||
# TODO: colorize name and cloud by team, colorize wizard by user's color config, level-specific wizard spawn points
|
||||
sprite = @createWizardSprite thangID: opponent.id, name: opponent.name
|
||||
sprite.targetPos = if opponent.team is 'ogres' then {x: 52, y: 52} else {x: 28, y: 28}
|
||||
|
||||
createWizardSprite: (options) ->
|
||||
sprite = new WizardSprite @thangTypeFor("Wizard"), @createSpriteOptions(options)
|
||||
@addSprite sprite, sprite.thang.id, @spriteLayers["Floating"]
|
||||
|
@ -136,15 +145,17 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
addThangToSprites: (thang, layer=null) ->
|
||||
return console.warn 'Tried to add Thang to the surface it already has:', thang.id if @sprites[thang.id]
|
||||
thangType = _.find @options.thangTypes, (m) -> m.get('name') is thang.spriteName
|
||||
sprite = new CocoSprite thangType, @createSpriteOptions thang: thang
|
||||
options = @createSpriteOptions thang: thang
|
||||
options.resolutionFactor = if thangType.get('kind') is 'Floor' then 2 else 4
|
||||
sprite = new CocoSprite thangType, options
|
||||
@addSprite sprite, null, layer
|
||||
sprite.setDebug @debug
|
||||
sprite
|
||||
|
||||
removeSprite: (sprite) ->
|
||||
sprite.displayObject.parent.removeChild sprite.displayObject
|
||||
sprite.destroy()
|
||||
delete @sprites[sprite.thang.id]
|
||||
sprite.destroy()
|
||||
|
||||
updateSounds: ->
|
||||
sprite.playSounds() for thangID, sprite of @sprites # hmm; doesn't work for sprites which we didn't add yet in adjustSpriteExistence
|
||||
|
@ -174,6 +185,11 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
sprite.hasMoved = false
|
||||
@removeSprite sprite if missing
|
||||
@cache true if updateCache and @cached
|
||||
|
||||
# mainly for handling selecting thangs from session when the thang is not always in existence
|
||||
if @willSelectThang and @sprites[@willSelectThang[0]]
|
||||
@selectThang @willSelectThang...
|
||||
@willSelectThang = null
|
||||
|
||||
cache: (update=false) ->
|
||||
return if @cached and not update
|
||||
|
@ -195,6 +211,22 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
|
||||
spriteFor: (thangID) -> @sprites[thangID]
|
||||
|
||||
onNewWorld: (e) ->
|
||||
@world = @options.world = e.world
|
||||
@play()
|
||||
|
||||
onCastSpells: -> @stop()
|
||||
|
||||
play: ->
|
||||
sprite.imageObject.play() for thangID, sprite of @sprites
|
||||
@selectionMark?.play()
|
||||
@targetMark?.play()
|
||||
|
||||
stop: ->
|
||||
sprite.imageObject.stop() for thangID, sprite of @sprites
|
||||
@selectionMark?.stop()
|
||||
@targetMark?.stop()
|
||||
|
||||
# Selection
|
||||
|
||||
onSuppressSelectionSounds: (e) -> @suppressSelectionSounds = e.suppress
|
||||
|
@ -206,8 +238,13 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
onSelectSprite: (e) ->
|
||||
@selectThang e.thangID, e.spellName
|
||||
|
||||
onSpriteMouseDown: (e) ->
|
||||
onCameraDragged: ->
|
||||
@dragged += 1
|
||||
|
||||
onSpriteMouseUp: (e) ->
|
||||
return if key.shift and @options.choosing
|
||||
return @dragged = 0 if @dragged > 3
|
||||
@dragged = 0
|
||||
sprite = if e.sprite?.thang?.isSelectable then e.sprite else null
|
||||
@selectSprite e, sprite
|
||||
|
||||
|
@ -216,9 +253,10 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
@selectSprite e if e.onBackground
|
||||
|
||||
selectThang: (thangID, spellName=null) ->
|
||||
return @willSelectThang = [thangID, spellName] unless @sprites[thangID]
|
||||
@selectSprite null, @sprites[thangID], spellName
|
||||
|
||||
selectSprite: (e, sprite=null, spellName=null) =>
|
||||
selectSprite: (e, sprite=null, spellName=null) ->
|
||||
return if e and (@disabled or @selectLocked) # Ignore clicks for selection/panning/wizard movement while disabled or select is locked
|
||||
worldPos = sprite?.thang?.pos
|
||||
worldPos ?= @camera.canvasToWorld {x: e.originalEvent.rawX, y: e.originalEvent.rawY} if e
|
||||
|
@ -248,8 +286,12 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
# Marks
|
||||
|
||||
updateSelection: ->
|
||||
if @selectedSprite?.thang and (not @selectedSprite.thang.exists or not @world.getThangByID @selectedSprite.thang.id)
|
||||
@selectSprite null, null, null
|
||||
@selectionMark?.toggle false
|
||||
@updateTarget()
|
||||
return unless @selectionMark
|
||||
@selectedSprite = null unless @selectedSprite?.thang
|
||||
@selectionMark.toggle @selectedSprite?
|
||||
@selectionMark.setSprite @selectedSprite
|
||||
@selectionMark.update()
|
||||
|
|
|
@ -8,6 +8,8 @@ CameraBorder = require './CameraBorder'
|
|||
Layer = require './Layer'
|
||||
Letterbox = require './Letterbox'
|
||||
Dimmer = require './Dimmer'
|
||||
CastingScreen = require './CastingScreen'
|
||||
PlaybackOverScreen = require './PlaybackOverScreen'
|
||||
DebugDisplay = require './DebugDisplay'
|
||||
CoordinateDisplay = require './CoordinateDisplay'
|
||||
SpriteBoss = require './SpriteBoss'
|
||||
|
@ -46,6 +48,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
coords: true
|
||||
playJingle: false
|
||||
showInvisible: false
|
||||
frameRate: 60 # Best as a divisor of 60, like 15, 30, 60, with RAF_SYNCHED timing.
|
||||
|
||||
subscriptions:
|
||||
'level-disable-controls': 'onDisableControls'
|
||||
|
@ -79,16 +82,31 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@initAudio()
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@dead = true
|
||||
@camera?.destroy()
|
||||
createjs.Ticker.removeEventListener("tick", @tick)
|
||||
createjs.Sound.stop()
|
||||
layer.destroy() for layer in @layers
|
||||
@spriteBoss.destroy()
|
||||
@chooser?.destroy()
|
||||
@dimmer?.destroy()
|
||||
@castingScreen?.destroy()
|
||||
@playbackOverScreen?.destroy()
|
||||
@stage.clear()
|
||||
@musicPlayer?.destroy()
|
||||
@stage.removeAllChildren()
|
||||
@stage.removeEventListener 'stagemousemove', @onMouseMove
|
||||
@stage.removeEventListener 'stagemousedown', @onMouseDown
|
||||
@stage.removeAllEventListeners()
|
||||
@stage.enableDOMEvents false
|
||||
@stage.enableMouseOver 0
|
||||
@onFramesScrubbed = null
|
||||
@onMouseMove = null
|
||||
@onMouseDown = null
|
||||
@tick = null
|
||||
@canvas.off 'mousewheel', @onMouseWheel
|
||||
@onMouseWheel = null
|
||||
super()
|
||||
|
||||
setWorld: (@world) ->
|
||||
@worldLoaded = true
|
||||
|
@ -163,7 +181,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
container.addChild shape
|
||||
|
||||
setProgress: (progress, scrubDuration=500) ->
|
||||
progress = Math.max(Math.min(progress, 0.99), 0.0)
|
||||
progress = Math.max(Math.min(progress, 1), 0.0)
|
||||
|
||||
@scrubbing = true
|
||||
onTweenEnd = =>
|
||||
|
@ -177,44 +195,45 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
createjs.Tween.removeTweens(@)
|
||||
@currentFrame = @scrubbingTo
|
||||
|
||||
@scrubbingTo = parseInt(progress * @world.totalFrames)
|
||||
@scrubbingTo = Math.min(Math.floor(progress * @world.totalFrames), @world.totalFrames)
|
||||
@scrubbingPlaybackSpeed = Math.sqrt(Math.abs(@scrubbingTo - @currentFrame) * @world.dt / (scrubDuration or 0.5))
|
||||
if scrubDuration
|
||||
t = createjs.Tween
|
||||
.get(@)
|
||||
.to({currentFrame:@scrubbingTo}, scrubDuration, createjs.Ease.sineInOut)
|
||||
.call(onTweenEnd)
|
||||
t.addEventListener('change', @playScrubbedSounds)
|
||||
t.addEventListener('change', @onFramesScrubbed)
|
||||
else
|
||||
@currentFrame = @scrubbingTo
|
||||
@playScrubbedSounds()
|
||||
@onFramesScrubbed() # For performance, don't play these for instant transitions.
|
||||
onTweenEnd()
|
||||
|
||||
@updateState true
|
||||
@onFrameChanged()
|
||||
|
||||
playScrubbedSounds: (e) =>
|
||||
# gotta play all the sounds, even when scrubbing!
|
||||
rising = @currentFrame > @lastFrame
|
||||
actualCurrentFrame = @currentFrame
|
||||
tempFrame = if rising then Math.ceil(@lastFrame) else Math.floor(@lastFrame)
|
||||
while true # temporary fix to stop cacophony
|
||||
break if rising and tempFrame > actualCurrentFrame
|
||||
break if (not rising) and tempFrame < actualCurrentFrame
|
||||
@currentFrame = tempFrame
|
||||
frame = @world.getFrame(@getCurrentFrame())
|
||||
frame.restoreState()
|
||||
for thangID, sprite of @spriteBoss.sprites
|
||||
sprite.playSounds false, Math.max(0.05, Math.min(1, 1 / @scrubbingPlaybackSpeed))
|
||||
tempFrame += if rising then 1 else -1
|
||||
@currentFrame = actualCurrentFrame
|
||||
onFramesScrubbed: (e) =>
|
||||
if e
|
||||
# Gotta play all the sounds when scrubbing (but not when doing an immediate transition).
|
||||
rising = @currentFrame > @lastFrame
|
||||
actualCurrentFrame = @currentFrame
|
||||
tempFrame = if rising then Math.ceil(@lastFrame) else Math.floor(@lastFrame)
|
||||
while true # temporary fix to stop cacophony
|
||||
break if rising and tempFrame > actualCurrentFrame
|
||||
break if (not rising) and tempFrame < actualCurrentFrame
|
||||
@currentFrame = tempFrame
|
||||
frame = @world.getFrame(@getCurrentFrame())
|
||||
frame.restoreState()
|
||||
for thangID, sprite of @spriteBoss.sprites
|
||||
sprite.playSounds false, Math.max(0.05, Math.min(1, 1 / @scrubbingPlaybackSpeed))
|
||||
tempFrame += if rising then 1 else -1
|
||||
@currentFrame = actualCurrentFrame
|
||||
|
||||
# TODO: are these needed, or perhaps do they duplicate things?
|
||||
@spriteBoss.update()
|
||||
@restoreWorldState()
|
||||
@spriteBoss.update true
|
||||
@onFrameChanged()
|
||||
|
||||
getCurrentFrame: ->
|
||||
return Math.max(0, Math.min(parseInt(@currentFrame), @world.totalFrames - 1))
|
||||
return Math.max(0, Math.min(Math.floor(@currentFrame), @world.totalFrames - 1))
|
||||
|
||||
getProgress: -> @currentFrame / @world.totalFrames
|
||||
|
||||
|
@ -230,7 +249,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
target = null
|
||||
@camera.setBounds e.bounds if e.bounds
|
||||
@cameraBorder.updateBounds @camera.bounds
|
||||
@camera.zoomTo target, e.zoom, e.duration
|
||||
@camera.zoomTo target, e.zoom, e.duration # TODO: SurfaceScriptModule perhaps shouldn't assign e.zoom if not set
|
||||
|
||||
setDisabled: (@disabled) ->
|
||||
@spriteBoss.disabled = @disabled
|
||||
|
@ -248,14 +267,14 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
onSetLetterbox: (e) ->
|
||||
@setDisabled e.on
|
||||
|
||||
onSetPlaying: (e) =>
|
||||
onSetPlaying: (e) ->
|
||||
@playing = (e ? {}).playing ? true
|
||||
if @playing and @currentFrame >= (@world.totalFrames - 5)
|
||||
@currentFrame = 0
|
||||
if @fastForwarding and not @playing
|
||||
@setProgress @currentFrame / @world.totalFrames
|
||||
|
||||
onSetTime: (e) =>
|
||||
onSetTime: (e) ->
|
||||
toFrame = @currentFrame
|
||||
if e.time?
|
||||
@worldLifespan = @world.totalFrames / @world.frameRate
|
||||
|
@ -282,14 +301,36 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
frame: @currentFrame
|
||||
world: @world
|
||||
)
|
||||
|
||||
if @lastFrame < @world.totalFrames and @currentFrame >= @world.totalFrames
|
||||
@spriteBoss.stop()
|
||||
@playbackOverScreen.show()
|
||||
@ended = true
|
||||
Backbone.Mediator.publish 'surface:playback-ended'
|
||||
else if @currentFrame < @world.totalFrames and @ended
|
||||
@spriteBoss.play()
|
||||
@playbackOverScreen.hide()
|
||||
@ended = false
|
||||
Backbone.Mediator.publish 'surface:playback-restarted'
|
||||
|
||||
@lastFrame = @currentFrame
|
||||
|
||||
onCastSpells: (event) ->
|
||||
@casting = true
|
||||
@wasPlayingWhenCastingBegan = @playing
|
||||
Backbone.Mediator.publish 'level-set-playing', { playing: false }
|
||||
|
||||
createjs.Tween.removeTweens(@surfaceLayer)
|
||||
createjs.Tween.get(@surfaceLayer).to({alpha:0.9}, 1000, createjs.Ease.getPowOut(4.0))
|
||||
|
||||
onNewWorld: (event) ->
|
||||
return unless event.world.name is @world.name
|
||||
@casting = false
|
||||
|
||||
# This has a tendency to break scripts that are waiting for playback to change when the level is loaded
|
||||
# so only run it after the first world is created.
|
||||
Backbone.Mediator.publish 'level-set-playing', { playing: @wasPlayingWhenCastingBegan } unless event.firstWorld
|
||||
|
||||
fastForwardTo = null
|
||||
if @playing
|
||||
fastForwardTo = Math.min event.world.firstChangedFrame, @currentFrame
|
||||
|
@ -317,6 +358,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@stage = new createjs.Stage(@canvas[0])
|
||||
canvasWidth = parseInt(@canvas.attr('width'), 10)
|
||||
canvasHeight = parseInt(@canvas.attr('height'), 10)
|
||||
@camera?.destroy()
|
||||
@camera = new Camera canvasWidth, canvasHeight
|
||||
@layers.push @surfaceLayer = new Layer name: "Surface", layerPriority: 0, transform: Layer.TRANSFORM_SURFACE, camera: @camera
|
||||
@layers.push @surfaceTextLayer = new Layer name: "Surface Text", layerPriority: 1, transform: Layer.TRANSFORM_SURFACE_TEXT, camera: @camera
|
||||
|
@ -325,13 +367,15 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
@surfaceLayer.addChild @cameraBorder = new CameraBorder bounds: @camera.bounds
|
||||
@screenLayer.addChild new Letterbox canvasWidth: canvasWidth, canvasHeight: canvasHeight
|
||||
@spriteBoss = new SpriteBoss camera: @camera, surfaceLayer: @surfaceLayer, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible
|
||||
@castingScreen ?= new CastingScreen camera: @camera, layer: @screenLayer
|
||||
@playbackOverScreen ?= new PlaybackOverScreen camera: @camera, layer: @screenLayer
|
||||
@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
|
||||
createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED
|
||||
createjs.Ticker.setFPS @options.frameRate
|
||||
|
||||
showLevel: ->
|
||||
return if @dead
|
||||
|
@ -347,6 +391,9 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
createjs.Ticker.addEventListener "tick", @tick
|
||||
Backbone.Mediator.publish 'level:started'
|
||||
|
||||
createOpponentWizard: (opponent) ->
|
||||
@spriteBoss.createOpponentWizard opponent
|
||||
|
||||
initAudio: ->
|
||||
@musicPlayer = new MusicPlayer()
|
||||
|
||||
|
@ -419,6 +466,7 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
# uh
|
||||
|
||||
onMouseMove: (e) =>
|
||||
@mouseSurfacePos = {x:e.stageX, y:e.stageY}
|
||||
return if @disabled
|
||||
Backbone.Mediator.publish 'surface:mouse-moved', x: e.stageX, y: e.stageY
|
||||
|
||||
|
@ -427,12 +475,15 @@ 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
|
||||
event =
|
||||
deltaX: e.deltaX
|
||||
deltaY: e.deltaY
|
||||
surfacePos: @mouseSurfacePos
|
||||
Backbone.Mediator.publish 'surface:mouse-scrolled', event unless @disabled
|
||||
|
||||
hookUpChooseControls: ->
|
||||
chooserOptions = stage: @stage, surfaceLayer: @surfaceLayer, camera: @camera, restrictRatio: @options.choosing is 'ratio-region'
|
||||
|
@ -444,44 +495,59 @@ module.exports = Surface = class Surface extends CocoClass
|
|||
tick: (e) =>
|
||||
# seems to be a bug where only one object can register with the Ticker...
|
||||
oldFrame = @currentFrame
|
||||
oldWorldFrame = Math.floor oldFrame
|
||||
while true
|
||||
Dropper.tick()
|
||||
@trailmaster.tick() if @trailmaster
|
||||
# Skip some frame updates unless we're playing and not at end (or we haven't drawn much yet)
|
||||
frameAdvanced = (@playing and @currentFrame < @world.totalFrames) or @totalFramesDrawn < 2
|
||||
++@currentFrame if frameAdvanced
|
||||
@updateSpriteSounds() if frameAdvanced
|
||||
@currentFrame += @world.frameRate / @options.frameRate if frameAdvanced and @playing
|
||||
newWorldFrame = Math.floor @currentFrame
|
||||
worldFrameAdvanced = newWorldFrame isnt oldWorldFrame
|
||||
if worldFrameAdvanced
|
||||
# Only restore world state when it will correspond to an integer WorldFrame, not interpolated frame.
|
||||
@restoreWorldState()
|
||||
oldWorldFrame = newWorldFrame
|
||||
break unless Dropper.drop()
|
||||
if frameAdvanced and not worldFrameAdvanced
|
||||
# We didn't end the above loop on an integer frame, so do the world state update.
|
||||
@restoreWorldState()
|
||||
|
||||
# these are skipped for dropped frames
|
||||
@updateState @currentFrame isnt oldFrame
|
||||
@drawCurrentFrame()
|
||||
@drawCurrentFrame e
|
||||
@onFrameChanged()
|
||||
@updatePaths() if (@totalFramesDrawn % 2) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
|
||||
Backbone.Mediator.publish('surface:ticked', {dt: @world.dt})
|
||||
@updatePaths() if (@totalFramesDrawn % 4) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
|
||||
Backbone.Mediator.publish('surface:ticked', {dt: 1 / @options.frameRate})
|
||||
mib = @stage.mouseInBounds
|
||||
if @mouseInBounds isnt mib
|
||||
Backbone.Mediator.publish('surface:mouse-' + (if mib then "over" else "out"), {})
|
||||
@mouseInBounds = mib
|
||||
|
||||
updateSpriteSounds: ->
|
||||
restoreWorldState: ->
|
||||
@world.getFrame(@getCurrentFrame()).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
|
||||
@spriteBoss.updateSounds()
|
||||
|
||||
updateState: (frameChanged) ->
|
||||
# world state must have been restored in @updateSpriteSounds
|
||||
# world state must have been restored in @restoreWorldState
|
||||
@camera.updateZoom()
|
||||
@spriteBoss.update frameChanged
|
||||
@spriteBoss.update frameChanged unless @casting
|
||||
@dimmer?.setSprites @spriteBoss.sprites
|
||||
|
||||
drawCurrentFrame: ->
|
||||
drawCurrentFrame: (e) ->
|
||||
++@totalFramesDrawn
|
||||
@stage.update()
|
||||
@stage.update e
|
||||
|
||||
# paths - TODO: move to SpriteBoss? but only update on frame drawing instead of on every frame update?
|
||||
|
||||
updatePaths: ->
|
||||
return unless @options.paths
|
||||
return if @casting
|
||||
@hidePaths()
|
||||
selectedThang = @spriteBoss.selectedSprite?.thang
|
||||
return if @world.showPaths is 'never'
|
||||
|
|
|
@ -24,18 +24,20 @@ module.exports = class WizardSprite extends IndieSprite
|
|||
|
||||
constructor: (thangType, options) ->
|
||||
if options?.isSelf
|
||||
options.colorConfig = me.get('wizard')?.colorConfig or {}
|
||||
options.colorConfig = _.cloneDeep(me.get('wizard')?.colorConfig) or {}
|
||||
super thangType, options
|
||||
@isSelf = options.isSelf
|
||||
@targetPos = @thang.pos
|
||||
if @isSelf
|
||||
@setNameLabel me.displayName()
|
||||
@setColorHue me.get('wizardColor1')
|
||||
else if options.name
|
||||
@setNameLabel options.name
|
||||
|
||||
makeIndieThang: (thangType, thangID, pos) ->
|
||||
thang = super thangType, thangID, pos
|
||||
thang.isSelectable = false
|
||||
thang.bobHeight = 1.5
|
||||
thang.bobHeight = 0.75
|
||||
thang.bobTime = 2
|
||||
thang.pos.z += thang.bobHeight
|
||||
thang
|
||||
|
@ -57,7 +59,12 @@ module.exports = class WizardSprite extends IndieSprite
|
|||
onMeSynced: (e) ->
|
||||
return unless @isSelf
|
||||
@setNameLabel me.displayName() if @displayObject.visible # not if we hid the wiz
|
||||
@setColorHue me.get('wizardColor1')
|
||||
newColorConfig = me.get('wizard')?.colorConfig or {}
|
||||
shouldUpdate = not _.isEqual(newColorConfig, @options.colorConfig)
|
||||
@options.colorConfig = _.cloneDeep(newColorConfig)
|
||||
if shouldUpdate
|
||||
@setupSprite()
|
||||
@playAction(@currentAction)
|
||||
|
||||
onSpriteSelected: (e) ->
|
||||
return unless @isSelf
|
||||
|
@ -183,7 +190,7 @@ module.exports = class WizardSprite extends IndieSprite
|
|||
Takes into account whether the wizard is in transit or not, and the bobbing up and down.
|
||||
Eventually will also adjust based on where other wizards are.
|
||||
"""
|
||||
@targetPos = @targetSprite.thang.pos if @targetSprite
|
||||
@targetPos = @targetSprite.thang.pos if @targetSprite?.thang
|
||||
pos = _.clone(@targetPos)
|
||||
pos.z = @defaultPos().z + @getBobOffset()
|
||||
@adjustPositionToSideOfTarget(pos) if @targetSprite # be off to the side depending on placement in world
|
||||
|
@ -213,7 +220,7 @@ module.exports = class WizardSprite extends IndieSprite
|
|||
targetPos.y += @spriteYOffset
|
||||
|
||||
faceTarget: ->
|
||||
if @targetSprite
|
||||
if @targetSprite?.thang
|
||||
@pointToward(@targetSprite.thang.pos)
|
||||
|
||||
updateMarks: ->
|
||||
|
|
|
@ -46,7 +46,6 @@ module.exports.Trailmaster = class Trailmaster
|
|||
clock: 0
|
||||
|
||||
constructor: (@camera) ->
|
||||
@listener = (e) => @tick(e)
|
||||
|
||||
tick: ->
|
||||
@clock += 1
|
||||
|
|
|
@ -15,7 +15,7 @@ module.exports = class GoalManager extends CocoClass
|
|||
|
||||
nextGoalID: 0
|
||||
|
||||
constructor: (@world) ->
|
||||
constructor: (@world, @initialGoals) ->
|
||||
super()
|
||||
@init()
|
||||
|
||||
|
@ -25,6 +25,7 @@ module.exports = class GoalManager extends CocoClass
|
|||
@userCodeMap = {} # @userCodeMap.thangID.methodName.aether.raw = codeString
|
||||
@thangTeams = {}
|
||||
@initThangTeams()
|
||||
@addGoal goal for goal in @initialGoals if @initialGoals
|
||||
|
||||
initThangTeams: ->
|
||||
return unless @world
|
||||
|
@ -34,8 +35,6 @@ module.exports = class GoalManager extends CocoClass
|
|||
@thangTeams[thang.team].push(thang.id)
|
||||
|
||||
subscriptions:
|
||||
'level-add-goals': 'onAddGoals'
|
||||
'level-remove-goals': 'onRemoveGoals'
|
||||
'god:new-world-created': 'onNewWorldCreated'
|
||||
'level:restarted': 'onLevelRestarted'
|
||||
|
||||
|
@ -46,25 +45,15 @@ module.exports = class GoalManager extends CocoClass
|
|||
'world:thang-collected-item': 'onThangCollectedItem'
|
||||
'world:ended': 'onWorldEnded'
|
||||
|
||||
onLevelRestarted: =>
|
||||
onLevelRestarted: ->
|
||||
@goals = []
|
||||
@goalStates = {}
|
||||
@userCodeMap = {}
|
||||
@notifyGoalChanges()
|
||||
@addGoal goal for goal in @initialGoals if @initialGoals
|
||||
|
||||
# INTERFACE AND LIFETIME OVERVIEW
|
||||
|
||||
# main instance receives goal updates from the script manager
|
||||
onAddGoals: (e) =>
|
||||
return unless e.worldName is @world.name
|
||||
goals = e.goals
|
||||
@addGoal(goal) for goal in goals
|
||||
|
||||
onRemoveGoals: (e) =>
|
||||
if e.goal in @goals
|
||||
@goals.remove(e.goal)
|
||||
delete @goalStates[e.goal]
|
||||
|
||||
# world generator gets current goals from the main instance
|
||||
getGoals: -> @goals
|
||||
|
||||
|
@ -79,7 +68,7 @@ module.exports = class GoalManager extends CocoClass
|
|||
func = @backgroundSubscriptions[channel]
|
||||
func = utils.normalizeFunc(func, @)
|
||||
return unless func
|
||||
func(event, frameNumber)
|
||||
func.call(@, event, frameNumber)
|
||||
|
||||
# after world generation, generated goal states
|
||||
# are grabbed to send back to main instance
|
||||
|
@ -88,8 +77,9 @@ module.exports = class GoalManager extends CocoClass
|
|||
|
||||
# main instance gets them and updates their existing goal states,
|
||||
# passes the word along
|
||||
onNewWorldCreated: (e) =>
|
||||
onNewWorldCreated: (e) ->
|
||||
@updateGoalStates(e.goalStates) if e.goalStates?
|
||||
@world = e.world
|
||||
|
||||
updateGoalStates: (newGoalStates) ->
|
||||
for goalID, goalState of newGoalStates
|
||||
|
@ -100,6 +90,7 @@ module.exports = class GoalManager extends CocoClass
|
|||
# IMPLEMENTATION DETAILS
|
||||
|
||||
addGoal: (goal) ->
|
||||
goal = _.cloneDeep(goal)
|
||||
goal.id = @nextGoalID++ if not goal.id
|
||||
return if @goalStates[goal.id]?
|
||||
@goals.push(goal)
|
||||
|
@ -134,48 +125,47 @@ module.exports = class GoalManager extends CocoClass
|
|||
status: null # should eventually be either 'success', 'failure', or 'incomplete'
|
||||
keyFrame: 0 # when it became a 'success' or 'failure'
|
||||
}
|
||||
|
||||
@initGoalState(state, [goal.killThangs, goal.saveThangs], 'killed')
|
||||
@initGoalState(state, [goal.getToLocations?.who, goal.keepFromLocations?.who], 'arrived')
|
||||
@initGoalState(state, [goal.leaveOffSides?.who, goal.keepFromLeavingOffSides?.who], 'left')
|
||||
@initGoalState(state, [goal.collectThangs?.who, goal.keepFromCollectingThangs?.who], 'collected')
|
||||
@goalStates[goal.id] = state
|
||||
|
||||
onThangDied: (e, frameNumber) =>
|
||||
onThangDied: (e, frameNumber) ->
|
||||
for goal in @goals ? []
|
||||
@checkKillThangs(goal.id, goal.killThangs, e.thang, frameNumber) if goal.killThangs?
|
||||
@checkKillThangs(goal.id, goal.saveThangs, e.thang, frameNumber) if goal.saveThangs?
|
||||
|
||||
checkKillThangs: (goalID, targets, thang, frameNumber) =>
|
||||
checkKillThangs: (goalID, targets, thang, frameNumber) ->
|
||||
return unless thang.id in targets or thang.team in targets
|
||||
@updateGoalState(goalID, thang.id, 'killed', frameNumber)
|
||||
|
||||
onThangTouchedGoal: (e, frameNumber) =>
|
||||
onThangTouchedGoal: (e, frameNumber) ->
|
||||
for goal in @goals ? []
|
||||
@checkArrived(goal.id, goal.getToLocations.who, goal.getToLocations.targets, e.actor.id, e.touched.id, frameNumber) if goal.getToLocations?
|
||||
@checkArrived(goal.id, goal.keepFromLocations.who, goal.keepFromLocations.targets, e.actor.id, e.touched.id, frameNumber) if goal.keepFromLocations?
|
||||
@checkArrived(goal.id, goal.getToLocations.who, goal.getToLocations.targets, e.actor, e.touched.id, frameNumber) if goal.getToLocations?
|
||||
@checkArrived(goal.id, goal.keepFromLocations.who, goal.keepFromLocations.targets, e.actor, e.touched.id, frameNumber) if goal.keepFromLocations?
|
||||
|
||||
checkArrived: (goalID, who, targets, thangID, touchedID, frameNumber) =>
|
||||
checkArrived: (goalID, who, targets, thang, touchedID, frameNumber) ->
|
||||
return unless touchedID in targets
|
||||
return unless thangID in who
|
||||
@updateGoalState(goalID, thangID, 'arrived', frameNumber)
|
||||
return unless thang.id in who or thang.team in who
|
||||
@updateGoalState(goalID, thang.id, 'arrived', frameNumber)
|
||||
|
||||
onThangLeftMap: (e, frameNumber) =>
|
||||
onThangLeftMap: (e, frameNumber) ->
|
||||
for goal in @goals ? []
|
||||
@checkLeft(goal.id, goal.leaveOffSides.who, goal.leaveOffSides.sides, e.thang.id, e.side, frameNumber) if goal.leaveOffSides?
|
||||
@checkLeft(goal.id, goal.keepFromLeavingOffSides.who, goal.keepFromLeavingOffSides.sides, e.thang.id, e.side, frameNumber) if goal.keepFromLeavingOffSides?
|
||||
|
||||
checkLeft: (goalID, who, sides, thangID, side, frameNumber) =>
|
||||
checkLeft: (goalID, who, sides, thangID, side, frameNumber) ->
|
||||
return if sides and side and not (side in sides)
|
||||
return unless thangID in who
|
||||
@updateGoalState(goalID, thangID, 'left', frameNumber)
|
||||
|
||||
onThangCollectedItem: (e, frameNumber) =>
|
||||
onThangCollectedItem: (e, frameNumber) ->
|
||||
for goal in @goals ? []
|
||||
@checkCollected(goal.id, goal.collectThangs.who, goal.collectThangs.targets, e.actor.id, e.item.id, frameNumber) if goal.collectThangs?
|
||||
@checkCollected(goal.id, goal.keepFromCollectingThangs.who, goal.keepFromCollectingThangs.targets, e.actor.id, e.item.id, frameNumber) if goal.keepFromCollectingThangs?
|
||||
|
||||
checkCollected: (goalID, who, targets, thangID, itemID, frameNumber) =>
|
||||
checkCollected: (goalID, who, targets, thangID, itemID, frameNumber) ->
|
||||
return unless itemID in targets
|
||||
return unless thangID in who
|
||||
@updateGoalState(goalID, thangID, 'collected', frameNumber)
|
||||
|
@ -221,7 +211,7 @@ module.exports = class GoalManager extends CocoClass
|
|||
stateThangs[thangID] = true
|
||||
success = @goalIsPositive goalID
|
||||
if success
|
||||
numNeeded = Math.max((goal.howMany ? 1), _.size stateThangs)
|
||||
numNeeded = goal.howMany ? Math.max(1, _.size stateThangs)
|
||||
else
|
||||
# saveThangs: by default we would want to save all the Thangs, which means that we would want none of them to be "done"
|
||||
numNeeded = _.size(stateThangs) - Math.min((goal.howMany ? 1), _.size stateThangs) + 1
|
||||
|
|
|
@ -1,797 +0,0 @@
|
|||
{me} = require('lib/auth')
|
||||
|
||||
# If we use marked somewhere else, we'll have to make sure to preserve options
|
||||
marked.setOptions {gfm: true, sanitize: false, smartLists: true, breaks: true}
|
||||
|
||||
markedWithImages = (s) ->
|
||||
s = s.replace /!\[(.*?)\]\((.+)? (\d+) (\d+) ?(.*?)?\)/g, '<img src="/images/docs/$2" alt="$1" title="$1" style="width: $3px; height: $4px;" class="$5"></img>' # setting width/height attrs doesn't prevent flickering, but inline css does
|
||||
marked(s)
|
||||
|
||||
module.exports.getDocsFor = (thang, props, isSnippet=false) ->
|
||||
docs = []
|
||||
types = {}
|
||||
for prop in props ? []
|
||||
type = if isSnippet then 'snippet' else typeof thang[prop]
|
||||
(types[type] ?= []).push prop
|
||||
order = ["function", "object", "string", "number", "boolean", "undefined", "snippet"]
|
||||
order.push type for type of types when not (type in order)
|
||||
for type in order
|
||||
for prop in (types[type] ? [])
|
||||
docClass = if D.hasOwnProperty prop then D[prop] else Doc
|
||||
docs.push new docClass(thang, prop, type)
|
||||
docs
|
||||
|
||||
module.exports.hasLevelDocs = (levelID) ->
|
||||
D[levelID]?
|
||||
|
||||
module.exports.getLevelDocs = (levelID, world) ->
|
||||
levelDocsClass = D[levelID] ? Level
|
||||
new levelDocsClass world
|
||||
|
||||
module.exports.Doc = class Doc
|
||||
writable: false
|
||||
owner: "this"
|
||||
constructor: (@thang, @prop, @type) ->
|
||||
if @owner isnt "this"
|
||||
@type = typeof window[@owner][@prop]
|
||||
@buildShortName()
|
||||
|
||||
buildShortName: ->
|
||||
@shortName = @prop
|
||||
if @type is 'function' then @shortName += "()"
|
||||
if @type isnt 'snippet' then @shortName = "#{@owner}.#{@shortName}"
|
||||
@shorterName = @shortName.replace 'this.', ''
|
||||
@shortName += ';'
|
||||
|
||||
title: ->
|
||||
typeStr = @type
|
||||
if @type is 'function' and @owner is 'this'
|
||||
typeStr = 'method'
|
||||
if @type isnt 'function' and not @writable
|
||||
typeStr += ' (read-only)'
|
||||
nameStr = @shortName
|
||||
"""<h4>#{nameStr} - <code class=\"prop-type\">#{typeStr}</code></h4>"""
|
||||
|
||||
html: ->
|
||||
s = markedWithImages(@doc())
|
||||
if @type in ['function', 'snippet']
|
||||
exampleCode = @example()
|
||||
if exampleCode.split('\n').length > 1
|
||||
exampleCode = "```\n#{exampleCode}```"
|
||||
else
|
||||
exampleCode = "`#{exampleCode}`"
|
||||
s += marked("**Example**:\n#{exampleCode}")
|
||||
args = @args?() or []
|
||||
if args.length
|
||||
s += marked("**Arguments**:")
|
||||
s += (arg.html() for arg in args).join('')
|
||||
else
|
||||
s += @value()
|
||||
s
|
||||
|
||||
value: ->
|
||||
"""
|
||||
<strong>Current value</strong>:
|
||||
<code class=\"current-value\" data-prop=\"#{@prop}\">#{@formatValue()}</code>
|
||||
"""
|
||||
|
||||
doc: ->
|
||||
"""
|
||||
This does something. I think.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
s = "#{@owner}.#{@shortName};"
|
||||
if @type is 'function'
|
||||
exampleArgs = (arg.example ? arg.default ? arg.name for arg in @args?() ? []).join ', '
|
||||
s = "#{@owner}.#{@prop}(#{exampleArgs});"
|
||||
s
|
||||
|
||||
formatValue: ->
|
||||
if @owner is 'this'
|
||||
v = @thang[@prop]
|
||||
else
|
||||
v = window[@owner][@prop]
|
||||
if @type is 'number' and not isNaN v
|
||||
if v == Math.round v
|
||||
return v
|
||||
return v.toFixed 2
|
||||
if _.isString v
|
||||
return "\"#{v}\""
|
||||
v
|
||||
|
||||
module.exports.Arg = class Arg
|
||||
constructor: (@name, @type, @example, @description, @default) ->
|
||||
|
||||
html: ->
|
||||
s = "`#{@name}`: `#{@type}`"
|
||||
if @example then s += " (ex: `#{@example}`)"
|
||||
if @description then s += "\n#{@description}"
|
||||
if @default? then s += "\n*Default value*: `#{@default}`"
|
||||
marked s
|
||||
|
||||
module.exports.Level = class Level
|
||||
constructor: (@world) ->
|
||||
|
||||
docID: (docName="doc") ->
|
||||
"level-doc-#{docName}"
|
||||
|
||||
html: (docName="doc", title, buttons) ->
|
||||
forVictory = docName is "victory"
|
||||
docID = @docID docName
|
||||
title ?= @world.name + (if forVictory then " Complete" else "")
|
||||
docHTML = if @[docName] then markedWithImages(@[docName]()) else "No #{docName}. Wail!"
|
||||
if forVictory
|
||||
buttonHTML = @victoryButtons()
|
||||
else
|
||||
buttonHTML = @buttons(buttons ? ["I'm Ready."])
|
||||
"""<div id="#{docID}" class="level-doc modal hide fade" tabindex="-1">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h3>#{title}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
#{docHTML}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
#{buttonHTML}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
doc: ->
|
||||
"""
|
||||
Venusaur? Oh no, counterattack with whatever you feel like, man!
|
||||
"""
|
||||
|
||||
victory: ->
|
||||
"""
|
||||
Detect it, it it no going and you tell me do things I done runnin'.
|
||||
"""
|
||||
|
||||
buttons: (names) ->
|
||||
buttonHTML = []
|
||||
for name in names
|
||||
buttonHTML.push(
|
||||
"""
|
||||
<button class="btn btn-primary" data-dismiss="modal">#{name}</button>
|
||||
"""
|
||||
)
|
||||
buttonHTML.join ' '
|
||||
|
||||
victoryButtons: ->
|
||||
buttons = """
|
||||
<button id="victory-stay" data-dismiss="modal" class="btn">Stay A While</button>
|
||||
<a href="/" class="btn">Go Home</a>
|
||||
"""
|
||||
if me.get 'anonymous'
|
||||
buttons += """
|
||||
<button class="btn btn-success sign-up-button">Sign Up for Updates</button>
|
||||
"""
|
||||
if @world.nextLevel
|
||||
buttons += """
|
||||
<a href="/play/level/#{@world.nextLevel}" class="btn btn-primary" data-dismiss="modal" >Next Level</a>
|
||||
"""
|
||||
buttons += """
|
||||
<div class="share-buttons">
|
||||
<div class="g-plusone" data-href="http://codecombat.com" data-size="medium"></div>
|
||||
<div class="fb-like" data-href="http://codecombat.com" data-send="false" data-layout="button_count" data-width="350" data-show-faces="true"></div>
|
||||
</div>
|
||||
"""
|
||||
buttons
|
||||
|
||||
|
||||
D = {} # save typing for all these things
|
||||
# Markdown: http://daringfireball.net/projects/markdown/syntax
|
||||
# GitHub Flavored Markdown: https://help.github.com/articles/github-flavored-markdown
|
||||
# Our Markdown parser and compiler: https://github.com/chjj/marked
|
||||
# I have extended the img syntax to take width and height (preventing flicker).
|
||||
|
||||
D.ifElse = class IfElse extends Doc
|
||||
buildShortName: ->
|
||||
@shortName = @shorterName = "if/else"
|
||||
|
||||
doc: ->
|
||||
"""
|
||||
The `if` control statement lets you choose whether to run the following code based on whether the condition evaluates truthily.
|
||||
|
||||
You can add an optional `else` clause to run instead when the condition evaluates falsily.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
if(2 + 2 === 4) {
|
||||
// Code here
|
||||
}
|
||||
else {
|
||||
// Code here
|
||||
}
|
||||
"""
|
||||
|
||||
D.forLoop = class ForLoop extends Doc
|
||||
buildShortName: ->
|
||||
@shortName = @shorterName = "for-loop"
|
||||
|
||||
doc: ->
|
||||
"""
|
||||
The `for` loop lets you run code many times. It has four parts:
|
||||
|
||||
* initial setup: `var i = 0;` (run at the beginning)
|
||||
* loop condition: `i < 10;` (code runs while this is true)
|
||||
* loop iteration: `i += 1` (runs after every iteration)
|
||||
* main loop code: `console.log("Counted to", i);`
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
for(var i = 0; i < 10; i += 1) {
|
||||
// Code here
|
||||
}
|
||||
"""
|
||||
|
||||
D.whileLoop = class WhileLoop extends Doc
|
||||
buildShortName: ->
|
||||
@shortName = @shorterName = "while-loop"
|
||||
|
||||
doc: ->
|
||||
"""
|
||||
The `while` loop lets you run code many times--as long as the condition is true.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
var i = 10;
|
||||
while(i < 10) {
|
||||
// Code here
|
||||
i -= 1;
|
||||
}
|
||||
"""
|
||||
|
||||
D.rotateTo = class RotateTo extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `rotateTo` method rotates the #{@thang.spriteName}. 
|
||||
|
||||
Use this method to change the direction that the #{@thang.spriteName} shoots.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[new Arg "degrees", "number", "180", "Desired rotation in degrees"]
|
||||
|
||||
D.shoot = class Shoot extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Calling `this.shoot();` makes the #{@thang.spriteName} choose the `shoot` action.
|
||||
|
||||
It's equivalent to: `this.setAction(this.actions.shoot);`
|
||||
"""
|
||||
|
||||
D.pos = class Pos extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `x` (horizontal) and `y` (vertical) coordinates of the #{@thang.spriteName}'s center.
|
||||
"""
|
||||
|
||||
D.rotation = class Rotation extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The #{@thang.spriteName}'s rotation in radians (`0` to `2 * Math.PI`).
|
||||
|
||||
Use the `rotateTo` method to set this value.
|
||||
"""
|
||||
|
||||
D.degrees = class Degrees extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The #{@thang.spriteName}'s rotation in degrees (`0` to `360`).
|
||||
|
||||
Use the `rotateTo` method to set this value.
|
||||
"""
|
||||
|
||||
D.attackRange = class AttackRange extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
How far the #{@thang.spriteName}'s attack reaches, in meters.
|
||||
"""
|
||||
|
||||
D.health = class Health extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
How many health points the #{@thang.spriteName} has left.
|
||||
"""
|
||||
|
||||
D.team = class Team extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
What team the #{@thang.spriteName} is on.
|
||||
"""
|
||||
|
||||
D.actions = class Actions extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The #{@thang.spriteName}'s available actions.
|
||||
|
||||
To, say, move, use: `this.setAction("move");`
|
||||
"""
|
||||
|
||||
formatValue: () ->
|
||||
v = @thang[@prop]
|
||||
'[' + ("\"#{actionName}\"" for actionName of v).join(', ') + ']'
|
||||
|
||||
D.action = class Action extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The current action the #{@thang.spriteName} is running.
|
||||
|
||||
To change this, use the `setAction` method.
|
||||
"""
|
||||
|
||||
D.setAction = class SetAction extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Sets the action that the #{@thang.spriteName} is running. Only actions in `this.actions` are valid.
|
||||
"""
|
||||
#For example, if `this.action` is currently `"idle"` and you want it to move instead, you'd set a target location, then: `this.setAction("move");`
|
||||
|
||||
args: ->
|
||||
exampleAction = "idle"
|
||||
for action in ["move", "shoot", "attack"]
|
||||
if @thang.actions[action]
|
||||
exampleAction = action
|
||||
break
|
||||
unless exampleAction
|
||||
exampleAction = _.some @thang.actions, "name"
|
||||
exampleAction = "\"#{exampleAction}\""
|
||||
[new Arg "action", "object", exampleAction, "The action to perform (must be one of `this.actions`)."]
|
||||
|
||||
D.target = class Target extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The current target upon which the #{@thang.spriteName} is running its `action`.
|
||||
|
||||
To change this, use the `setTarget` method.
|
||||
"""
|
||||
|
||||
formatValue: () ->
|
||||
v = @thang[@prop]
|
||||
if v? then v.toString() else 'null'
|
||||
|
||||
D.setTarget = class SetTarget extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Sets what the #{@thang.spriteName} is targeting with its current `action`, such as an enemy to attack or a position to move to.
|
||||
"""
|
||||
#For example, if `this.action` is currently `this.actions.move`, the #{@thang.spriteName} will move toward its `target`; if its action is `this.actions.attack`, it will try to attack its target.
|
||||
#For some actions, you can also pass `x` and `y` coordinates as a target instead of another unit: `this.setTarget(65, 40);`
|
||||
|
||||
args: ->
|
||||
exampleTarget = "65, 40"
|
||||
for [methods, code] in [[["getNearestEnemy"], "this.getNearestEnemy()"],
|
||||
[["pos", "move"], "this.pos.x + 20, this.pos.y - 20"],
|
||||
[["attack"], "enemy"],
|
||||
[["shoot"], "enemy"]]
|
||||
if (m for m in methods when m in @thang.programmableProperties).length
|
||||
exampleTarget = code
|
||||
break
|
||||
|
||||
[new Arg "target", "object", exampleTarget, "The new target upon which to act."]
|
||||
|
||||
D.chooseAction = class ChooseAction extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `chooseAction` method is run every frame, allowing the #{@thang.spriteName} a chance to look at the world and decide what action to pursue this frame.
|
||||
|
||||
To see available actions, hover over the `actions` property below. To choose an action, say `attack`, you can write: `this.setAction(this.actions.attack);`
|
||||
"""
|
||||
|
||||
D.plan = class Plan extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `plan` method (spell) is where you write a sequence of methods (spells) to command the #{@thang.spriteName}.
|
||||
|
||||
Type your methods into the Spell Editor below. Hover over your available methods at the bottom to see what they do.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
this.moveRight();
|
||||
this.moveRight();
|
||||
this.attackNearbyEnemy();
|
||||
"""
|
||||
|
||||
D.attack = class Attack extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `attack` method takes an enemy `target`, sets the #{@thang.spriteName}'s `target` to that `target` with the `setTarget` method, and sets the #{@thang.spriteName}'s `action` to the `this.actions.attack` action with the `setAction` method.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
exampleTarget = "enemy"
|
||||
for [methods, code] in [[["getNearestEnemy"], "this.getNearestEnemy()"],
|
||||
[["getEnemies"], "this.getEnemies()[0]"]]
|
||||
if (m for m in methods when m in @thang.programmableProperties).length
|
||||
exampleTarget = code
|
||||
break
|
||||
|
||||
[new Arg "target", "object", exampleTarget, "The target enemy to attack."]
|
||||
|
||||
D.moveXY = class MoveXY extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `moveXY` method sets the #{@thang.spriteName}'s `targetPos` to the given `(x, y)` coordinates and also sets the #{@thang.spriteName}'s `action` to `move`.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[
|
||||
new Arg "x", "number", "24", "The x coordinate toward which to move."
|
||||
new Arg "y", "number", "35", "The y coordinate toward which to move."
|
||||
]
|
||||
|
||||
D.distanceTo = class DistanceTo extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Returns the distance in meters to the `target` unit from the center of the #{@thang.spriteName}.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
exampleTarget = "enemy"
|
||||
for [methods, code] in [#[["getNearestEnemy"], "this.getNearestEnemy()"],
|
||||
[["getEnemies"], "this.getEnemies()[0]"],
|
||||
[["getFriends"], "this.getFriends()[0]"]]
|
||||
if (m for m in methods when m in @thang.programmableProperties).length
|
||||
exampleTarget = code
|
||||
break
|
||||
|
||||
[new Arg "target", "object", exampleTarget, "The target unit whose distance you want to measure."]
|
||||
|
||||
D.getEnemies = class GetEnemies extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Returns an array of all living enemies within eyesight.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
var enemies = this.getEnemies();
|
||||
for(var i = 0; i < enemies.length; ++i) {
|
||||
var enemy = enemies[i];
|
||||
// Do something with each enemy here
|
||||
this.attack(enemy); // Example
|
||||
}
|
||||
"""
|
||||
|
||||
D.getFriends = class GetFriends extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Returns an array of all living friends within eyesight.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
var friends = this.getFriends();
|
||||
for(var i = 0; i < friends.length; ++i) {
|
||||
var friend = friends[i];
|
||||
// Do something with each friend here
|
||||
this.follow(friend); // Example
|
||||
}
|
||||
"""
|
||||
|
||||
D.getItems = class GetItems extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Returns an array of all living items within eyesight.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
var items = this.getItems()
|
||||
for(var i = 0; i < items.length; ++i) {
|
||||
var item = items[i];
|
||||
// Do something with each item here
|
||||
this.move(item.pos); // Example
|
||||
}
|
||||
"""
|
||||
|
||||
D.attackNearbyEnemy = class GetNearbyEnemy extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Attacks any enemy within #{@thang.attackNearbyEnemyRange ? 5} meters of the #{@thang.spriteName}.
|
||||
"""
|
||||
|
||||
D.getNearestEnemy = class GetNearestEnemy extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Returns the closest living enemy, or `null` if there aren\'t any.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
var enemy = this.getNearestEnemy();
|
||||
"""
|
||||
|
||||
D.getNearestFriend = class GetNearestFriend extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Returns the closest living friend, or `null` if there aren\'t any.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
var friend = this.getNearestFriend();
|
||||
"""
|
||||
|
||||
D.getNearestCombtaant = class GetNearestCombatant extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Returns the closest living friend or foe, or `null` if there aren\'t any.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
var enemy = this.getNearestCombatant();
|
||||
"""
|
||||
|
||||
D.attackXY = class AttackXY extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `attackXY` method makes the #{@thang.spriteName} attack the ground at the given `(x, y)` coordinates.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[
|
||||
new Arg "x", "number", "24", "The x coordinate to attack."
|
||||
new Arg "y", "number", "35", "The y coordinate to attack."
|
||||
]
|
||||
|
||||
D.patrol = class Patrol extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `patrol` method causes the #{@thang.spriteName} to move between the given waypoints in a loop. When combined with code to `attack` nearby enemies, you can use it to guard an area.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[new Arg "patrolPoints", "array", "[{x: 15, y: 45}, {x: 30, y: 40}, {x: 25, y: 35}]", "An array of positions to move between."]
|
||||
|
||||
D.attackNearestEnemy = class AttackNearestEnemy extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `attackNearestEnemy` method causes the #{@thang.spriteName} to charge at the nearest enemy and try to slay it.
|
||||
"""
|
||||
|
||||
D.moveRight = class MoveRight extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Moves the #{@thang.spriteName} right by #{@thang.simpleMoveDistance} meters.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
this.moveRight();
|
||||
"""
|
||||
|
||||
D.moveLeft = class MoveLeft extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Moves the #{@thang.spriteName} left by #{@thang.simpleMoveDistance} meters.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
this.moveLeft();
|
||||
"""
|
||||
|
||||
D.moveUp = class MoveUp extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Moves the #{@thang.spriteName} up by #{@thang.simpleMoveDistance} meters.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
this.moveUp();
|
||||
"""
|
||||
|
||||
D.moveDown = class MoveDown extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Moves the #{@thang.spriteName} down by #{@thang.simpleMoveDistance} meters.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
this.moveDown();
|
||||
"""
|
||||
|
||||
D.say = class Say extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Makes the #{@thang.spriteName} say the given message. Anything within #{@thang.voiceRange ? 20} meters will hear it.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[new Arg "message", "string", "\"Follow me!\"", "The message to say."]
|
||||
|
||||
D.chaseAndAttack = class ChaseAndAttack extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
Makes the #{@thang.spriteName} attack `target` if in range, otherwise move to `target`.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[new Arg "target", "object", "this.getNearestEnemy()", "The unit to chase and attack."]
|
||||
|
||||
|
||||
D.wait = class Wait extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `wait()` method makes the #{@thang.spriteName} wait for a moment before continuing to execute the rest of the code.
|
||||
|
||||
It currently doesn't work inside nested functions in a `plan()` method.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[
|
||||
new Arg "duration", "number", "0.1", "Number of seconds to wait."
|
||||
]
|
||||
|
||||
D.addRect = class AddRect extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `addRect()` method adds a rectangle centered at the given `(x, y)` coordinate with the given `width` and `height`.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[
|
||||
new Arg "x", "number", "30", "x-coordinate of center of the rectangle."
|
||||
new Arg "y", "number", "12", "y-coordinate of center of the rectangle."
|
||||
new Arg "width", "number", "4", "width of the rectangle."
|
||||
new Arg "height", "number", "24", "height of the rectangle."
|
||||
]
|
||||
|
||||
D.removeRectAt = class RemoveRectAt extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `removeRectAt()` method removes a previously added rectangle centered at the given `(x, y)` coordinate.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[
|
||||
new Arg "x", "number", "30", "x-coordinate of center of the rectangle to remove."
|
||||
new Arg "y", "number", "12", "y-coordinate of center of the rectangle to remove."
|
||||
]
|
||||
|
||||
D.getNavGrid = class GetNavGrid extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
The `getNavGrid()` method returns an undocumented data structure CodeCombat uses in its pathfinding system. Sorry--will improve.
|
||||
|
||||
Just use its `grid` property, which is a two-dimensional array with one-meter resolution indicating where the walls are:
|
||||
|
||||
```
|
||||
var grid = this.getNavGrid().grid;
|
||||
var y = 12;
|
||||
var x = 30;
|
||||
var occupied = grid[y][x].length > 0;
|
||||
```
|
||||
"""
|
||||
|
||||
D.spawnedRectangles = class SpawnedRectangles extends Doc
|
||||
doc: ->
|
||||
"""
|
||||
An array of rectangle objects which have been added with the `addRect()` method.
|
||||
|
||||
You can get a rectangle's dimensions, like this:
|
||||
|
||||
```
|
||||
for(var i = 0; i < this.spawnedRectangles.length; ++i) {
|
||||
var rect = this.spawnedRectangles[i];
|
||||
// rect.pos.x, rect.pos.y, rect.width, rect.height
|
||||
}
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
D.pow = class Pow extends Doc
|
||||
owner: "Math"
|
||||
doc: ->
|
||||
"""
|
||||
Returns `base` to the `exponent` power, that is, <code>base<sup>exponent</sup></code>.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
Math.pow(7, 2); // returns 49
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[
|
||||
new Arg "base", "number", "7", "The base number."
|
||||
new Arg "exponent", "number", "2", "The exponent used to raise the `base`."
|
||||
]
|
||||
|
||||
D.sqrt = class Sqrt extends Doc
|
||||
owner: "Math"
|
||||
doc: ->
|
||||
"""
|
||||
Returns the square root of a non-negative number. Equivalent to `Math.pow(x, 0.5)`.
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
Math.sqrt(49); // returns 7
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[new Arg "x", "number", "49", ""]
|
||||
|
||||
D.sin = class Sin extends Doc
|
||||
owner: "Math"
|
||||
doc: ->
|
||||
"""
|
||||
Returns the sine of a number (between -1 and 1).
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
Math.sin(Math.PI / 4); // returns √2
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[new Arg "x", "number", "Math.PI / 2", "A number in radians."]
|
||||
|
||||
D.cos = class Cos extends Doc
|
||||
owner: "Math"
|
||||
doc: ->
|
||||
"""
|
||||
Returns the cosine of a number (between -1 and 1).
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
Math.cos(3 * Math.PI / 4); // returns -√2
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[new Arg "x", "number", "Math.PI / 2", "A number in radians."]
|
||||
|
||||
D.tan = class Tan extends Doc
|
||||
owner: "Math"
|
||||
doc: ->
|
||||
"""
|
||||
Returns the tangent of a number (between -1 and 1).
|
||||
"""
|
||||
|
||||
example: ->
|
||||
"""
|
||||
Math.tan(Math.PI / 4); // returns 0.9999999999999999
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[new Arg "x", "number", "Math.PI / 2", "A number in radians."]
|
||||
|
||||
D.atan2 = class Atan2 extends Doc
|
||||
owner: "Math"
|
||||
doc: ->
|
||||
"""
|
||||
Returns the arctangent of the quotient of its arguments--a numeric value between -π and π representing the counterclockwise angle theta of an (x, y) point and the positive X axis.
|
||||
"""
|
||||
|
||||
args: ->
|
||||
[
|
||||
new Arg "y", "number", "90", ""
|
||||
new Arg "x", "number", "15", ""
|
||||
]
|
||||
|
||||
D.PI = class PI extends Doc
|
||||
owner: "Math"
|
||||
doc: ->
|
||||
"""
|
||||
The ratio of the circumference of a circle to its diameter, approximately 3.14159.
|
||||
"""
|
||||
|
||||
D.random = class Random extends Doc
|
||||
owner: "Math"
|
||||
doc: ->
|
||||
"""
|
||||
Returns a random number x such that 0 <= x < 1.
|
||||
"""
|
|
@ -78,6 +78,7 @@ module.exports.thangNames = thangNames =
|
|||
"Giselle"
|
||||
"Bernadette"
|
||||
"Hershell"
|
||||
"Gawain"
|
||||
]
|
||||
"Archer F": [
|
||||
"Phoebe"
|
||||
|
@ -107,6 +108,9 @@ module.exports.thangNames = thangNames =
|
|||
"Archer M": [
|
||||
"Brian"
|
||||
"Cole"
|
||||
"Roman"
|
||||
"Hunter"
|
||||
"Simon"
|
||||
]
|
||||
"Ogre Munchkin M": [
|
||||
"Brack"
|
||||
|
@ -133,6 +137,8 @@ module.exports.thangNames = thangNames =
|
|||
"Iyert"
|
||||
"Palt"
|
||||
"Shmeal"
|
||||
"Gurzunn"
|
||||
"Yugark"
|
||||
]
|
||||
"Ogre M": [
|
||||
"Krogg"
|
||||
|
@ -143,11 +149,14 @@ module.exports.thangNames = thangNames =
|
|||
"Mak Fod"
|
||||
"Trung"
|
||||
"Axe Ox"
|
||||
"Vargutt"
|
||||
]
|
||||
"Ogre F": [
|
||||
"Nareng"
|
||||
"Morthrug"
|
||||
"Glonc"
|
||||
"Marghurk"
|
||||
|
||||
]
|
||||
"Ogre Brawler": [
|
||||
"Grul'thock"
|
||||
|
@ -161,6 +170,7 @@ module.exports.thangNames = thangNames =
|
|||
"Zeredd"
|
||||
"Borgag"
|
||||
"Grognar"
|
||||
"Ironjaw"
|
||||
]
|
||||
"Ogre Fangrider": [
|
||||
"Dreek"
|
||||
|
|
|
@ -32,6 +32,9 @@ module.exports.CollisionCategory = class CollisionCategory
|
|||
# "ground_and_air_<team>" units don't hit ground or air units on their team (so missiles don't hit same team)
|
||||
sameTeam = @superteamIndex and cat.superteamIndex is @superteamIndex
|
||||
return false if sameTeam and @ground and @air
|
||||
|
||||
# actually, "ground_and_air<team>" units don't hit any ground_and_air units (temp missile collision fix)
|
||||
return false if @ground and @air and cat.ground and cat.air
|
||||
|
||||
# "ground" collides with "ground"
|
||||
return true if cat.ground and @ground
|
||||
|
|
|
@ -67,7 +67,7 @@ module.exports = class ThangState
|
|||
|
||||
restore: ->
|
||||
# Restore trackedProperties' values to @thang, retrieving them from @trackedPropertyValues if needed. Optimize it.
|
||||
return @ if @thang._state is @
|
||||
return @ if @thang._state is @ and not @thang.partialState
|
||||
unless @hasRestored # Restoring in a deserialized World for first time
|
||||
props = []
|
||||
for prop, propIndex in @trackedPropertyKeys
|
||||
|
@ -81,6 +81,26 @@ module.exports = class ThangState
|
|||
else # Restoring later times
|
||||
for prop, propIndex in @trackedPropertyKeys
|
||||
@thang[prop] = @props[propIndex]
|
||||
@thang.partialState = false
|
||||
@
|
||||
|
||||
restorePartial: (ratio) ->
|
||||
inverse = 1 - ratio
|
||||
for prop, propIndex in @trackedPropertyKeys when prop is "pos" or prop is "rotation"
|
||||
if @hasRestored
|
||||
value = @props[propIndex]
|
||||
else
|
||||
type = @trackedPropertyTypes[propIndex]
|
||||
storage = @trackedPropertyValues[propIndex]
|
||||
value = @getStoredProp propIndex, type, storage
|
||||
if prop is "pos"
|
||||
@thang.pos = @thang.pos.copy()
|
||||
@thang.pos.x = inverse * @thang.pos.x + ratio * value.x
|
||||
@thang.pos.y = inverse * @thang.pos.y + ratio * value.y
|
||||
@thang.pos.z = inverse * @thang.pos.z + ratio * value.z
|
||||
else if prop is "rotation"
|
||||
@thang.rotation = inverse * @thang.rotation + ratio * value
|
||||
@thang.partialState = true
|
||||
@
|
||||
|
||||
serialize: (frameIndex, trackedPropertyIndices, trackedPropertyTypes, trackedPropertyValues, specialValuesToKeys, specialKeysToValues) ->
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
class Vector
|
||||
@className: "Vector"
|
||||
# Class methods for nondestructively operating
|
||||
for name in ['add', 'subtract', 'multiply', 'divide']
|
||||
for name in ['add', 'subtract', 'multiply', 'divide', 'limit', 'normalize']
|
||||
do (name) ->
|
||||
Vector[name] = (a, b, useZ) ->
|
||||
a.copy()[name](b, useZ)
|
||||
|
|
|
@ -32,12 +32,6 @@ module.exports = class World
|
|||
@rand = new Rand 0
|
||||
@frames = [new WorldFrame(@, 0)]
|
||||
|
||||
# --- This config needs to move into Systems config --- TODO
|
||||
playableTeams: ["humans"]
|
||||
teamForPlayer: (n) ->
|
||||
@playableTeams[n % @playableTeams.length]
|
||||
# -----------------------------------------------------
|
||||
|
||||
getFrame: (frameIndex) ->
|
||||
# Optimize it a bit--assume we have all if @ended and are at the previous frame otherwise
|
||||
frames = @frames
|
||||
|
@ -61,7 +55,7 @@ module.exports = class World
|
|||
@thangMap[thang.id] = thang
|
||||
|
||||
thangDialogueSounds: ->
|
||||
if @frames.length < @totalFrames then worldShouldBeOverBeforeGrabbingDialogue
|
||||
if @frames.length < @totalFrames then throw new Error("World should be over before grabbing dialogue")
|
||||
[sounds, seen] = [[], {}]
|
||||
for frame in @frames
|
||||
for thangID, state of frame.thangStateMap
|
||||
|
@ -78,7 +72,7 @@ module.exports = class World
|
|||
(@runtimeErrors ?= []).push error
|
||||
(@unhandledRuntimeErrors ?= []).push error
|
||||
|
||||
loadFrames: (loadedCallback, errorCallback, loadProgressCallback) =>
|
||||
loadFrames: (loadedCallback, errorCallback, loadProgressCallback) ->
|
||||
return if @aborted
|
||||
unless @thangs.length
|
||||
console.log "Warning: loadFrames called on empty World (no thangs)."
|
||||
|
@ -251,7 +245,7 @@ module.exports = class World
|
|||
|
||||
serialize: ->
|
||||
# Code hotspot; optimize it
|
||||
if @frames.length < @totalFrames then worldShouldBeOverBeforeSerialization
|
||||
if @frames.length < @totalFrames then throw new Error("World Should Be Over Before Serialization")
|
||||
[transferableObjects, nontransferableObjects] = [0, 0]
|
||||
o = {name: @name, totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}}
|
||||
o.trackedProperties[prop] = @[prop] for prop in @trackedProperties or []
|
||||
|
@ -259,7 +253,7 @@ module.exports = class World
|
|||
for thangID, methods of @userCodeMap
|
||||
serializedMethods = o.userCodeMap[thangID] = {}
|
||||
for methodName, method of methods
|
||||
serializedMethods[methodName] = method.serialize()
|
||||
serializedMethods[methodName] = method.serialize?() ? method # serialize the method again if it has been deserialized
|
||||
|
||||
t0 = now()
|
||||
o.trackedPropertiesThangIDs = []
|
||||
|
@ -426,7 +420,7 @@ module.exports = class World
|
|||
pos = camera.worldToSurface {x: pos.x, y: pos.y} if camera # without z
|
||||
if not lastPos.x? or (Math.abs(lastPos.x - pos.x) + Math.abs(lastPos.y - pos.y)) > 1
|
||||
lastPos = pos
|
||||
allPoints.push lastPos.y, lastPos.x
|
||||
allPoints.push lastPos.y, lastPos.x unless lastPos.y is 0 and lastPos.x is 0
|
||||
allPoints.reverse()
|
||||
@pointsForThangCache[cacheKey] = allPoints
|
||||
|
||||
|
@ -464,3 +458,7 @@ module.exports = class World
|
|||
colorConfigs = {}
|
||||
colorConfigs[teamName] = config.color for teamName, config of teamConfigs
|
||||
colorConfigs
|
||||
|
||||
teamForPlayer: (n) ->
|
||||
playableTeams = @playableTeams ? ['humans']
|
||||
playableTeams[n % playableTeams.length]
|
||||
|
|
|
@ -25,6 +25,9 @@ module.exports = class WorldFrame
|
|||
#console.log "Frame", @time, "restoring state for", thang.id, "and saying it don't exist"
|
||||
thang.exists = false
|
||||
|
||||
restorePartialState: (ratio) ->
|
||||
thangState.restorePartial ratio for thangID, thangState of @thangStateMap
|
||||
|
||||
restoreStateForThang: (thang) ->
|
||||
thangState = @thangStateMap[thang.id]
|
||||
if not thangState
|
||||
|
|
|
@ -42,9 +42,9 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
|
|||
# cla_agree: "I AGREE"
|
||||
|
||||
# login:
|
||||
# sign_up: "Create Account"
|
||||
# log_in: "Log In"
|
||||
# log_out: "Log Out"
|
||||
# sign_up: "Create An Account"
|
||||
# recover: "recover account"
|
||||
|
||||
# recover:
|
||||
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
|
|||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
# account_settings:
|
||||
# title: "Account Settings"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
|
|||
# gravatar_profile_link: "Full Gravatar Profile"
|
||||
|
||||
# play_level:
|
||||
# level_load_error: "Level could not be loaded."
|
||||
# level_load_error: "Level could not be loaded: "
|
||||
# done: "Done"
|
||||
# grid: "Grid"
|
||||
# customize_wizard: "Customize Wizard"
|
||||
|
@ -173,7 +181,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
|
|||
# victory_go_home: "Go Home"
|
||||
# victory_review: "Tell us more!"
|
||||
# victory_hour_of_code_done: "Are You Done?"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
# multiplayer_title: "Multiplayer Settings"
|
||||
# multiplayer_link_description: "Give this link to anyone to have them join you."
|
||||
# multiplayer_hint_label: "Hint:"
|
||||
|
@ -183,7 +191,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
|
|||
# tome_minion_spells: "Your Minions' Spells"
|
||||
# tome_read_only_spells: "Read-Only Spells"
|
||||
# tome_other_units: "Other Units"
|
||||
# tome_cast_button_castable: "Cast"
|
||||
# tome_cast_button_castable: "Cast Spell"
|
||||
# tome_cast_button_casting: "Casting"
|
||||
# tome_cast_button_cast: "Spell Cast"
|
||||
# tome_autocast_delay: "Autocast Delay"
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
module.exports = nativeDescription: "български език", englishDescription: "Bulgarian", translation:
|
||||
common:
|
||||
loading: "Loading..."
|
||||
# saving: "Saving..."
|
||||
# sending: "Sending..."
|
||||
# cancel: "Cancel"
|
||||
# save: "Save"
|
||||
loading: "Зареждане..."
|
||||
saving: "Записване..."
|
||||
sending: "Изпращане..."
|
||||
cancel: "Отказ"
|
||||
save: "Запис"
|
||||
delay_1_sec: "1 секунда"
|
||||
delay_3_sec: "3 секунди"
|
||||
delay_5_sec: "5 секунди"
|
||||
# manual: "Manual"
|
||||
# fork: "Fork"
|
||||
# play: "Play"
|
||||
# delay_1_sec: "1 second"
|
||||
# delay_3_sec: "3 seconds"
|
||||
# delay_5_sec: "5 seconds"
|
||||
# manual: "Manual"
|
||||
|
||||
# modal:
|
||||
# close: "Close"
|
||||
# okay: "Okay"
|
||||
modal:
|
||||
close: "Затвори"
|
||||
okay: "Добре"
|
||||
|
||||
# not_found:
|
||||
# page_not_found: "Page not found"
|
||||
not_found:
|
||||
page_not_found: "Страницата не е намерена"
|
||||
|
||||
# nav:
|
||||
# play: "Levels"
|
||||
# editor: "Editor"
|
||||
# blog: "Blog"
|
||||
# forum: "Forum"
|
||||
nav:
|
||||
play: "Нива"
|
||||
editor: "Редактор"
|
||||
blog: "Блог"
|
||||
forum: "Форум"
|
||||
# admin: "Admin"
|
||||
# home: "Home"
|
||||
# contribute: "Contribute"
|
||||
|
@ -41,34 +41,34 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# cla_suffix: "."
|
||||
# cla_agree: "I AGREE"
|
||||
|
||||
# login:
|
||||
# sign_up: "Create Account"
|
||||
# log_in: "Log In"
|
||||
# log_out: "Log Out"
|
||||
# recover: "recover account"
|
||||
login:
|
||||
sign_up: "Създай Профил"
|
||||
log_in: "Вход"
|
||||
log_out: "Изход"
|
||||
recover: "Възстанови акаунт"
|
||||
|
||||
# recover:
|
||||
# recover_account_title: "Recover Account"
|
||||
# send_password: "Send Recovery Password"
|
||||
recover:
|
||||
recover_account_title: "Възстанови Акаунт"
|
||||
send_password: "Изпрати парола за възстановяване"
|
||||
|
||||
# signup:
|
||||
signup:
|
||||
# create_account_title: "Create Account to Save Progress"
|
||||
# description: "It's free. Just need a couple things and you'll be good to go:"
|
||||
# email_announcements: "Receive announcements by email"
|
||||
# coppa: "13+ or non-USA "
|
||||
# coppa_why: "(Why?)"
|
||||
# creating: "Creating Account..."
|
||||
# sign_up: "Sign Up"
|
||||
# log_in: "log in with password"
|
||||
coppa_why: "(Защо?)"
|
||||
creating: "Създаване на профил..."
|
||||
sign_up: "Регистриране"
|
||||
log_in: "Вход с парола"
|
||||
|
||||
# home:
|
||||
# slogan: "Learn to Code JavaScript by Playing a Game"
|
||||
# no_ie: "CodeCombat does not run in Internet Explorer 9 or older. Sorry!"
|
||||
# no_mobile: "CodeCombat wasn't designed for mobile devices and may not work!"
|
||||
# play: "Play"
|
||||
home:
|
||||
slogan: "Научи се да програмираш на JavaScript, докато играеш игра "
|
||||
no_ie: "CodeCombat не работи под Internet Explorer 9 или по-стар. Съжалявам!"
|
||||
no_mobile: "CodeCombat не е направен за мобилни устройства и може да не работи!"
|
||||
play: "Играй"
|
||||
|
||||
# play:
|
||||
# choose_your_level: "Choose Your Level"
|
||||
play:
|
||||
choose_your_level: "Избери своето ниво"
|
||||
# adventurer_prefix: "You can jump to any level below, or discuss the levels on "
|
||||
# adventurer_forum: "the Adventurer forum"
|
||||
# adventurer_suffix: "."
|
||||
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
# account_settings:
|
||||
# title: "Account Settings"
|
||||
|
@ -133,12 +141,12 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# saved: "Changes Saved"
|
||||
# password_mismatch: "Password does not match."
|
||||
|
||||
# account_profile:
|
||||
# edit_settings: "Edit Settings"
|
||||
account_profile:
|
||||
edit_settings: "Промени настройките"
|
||||
# profile_for_prefix: "Profile for "
|
||||
# profile_for_suffix: ""
|
||||
# profile: "Profile"
|
||||
# user_not_found: "No user found. Check the URL?"
|
||||
user_not_found: "Няма намерен потребител. Провери URL-а?"
|
||||
# gravatar_not_found_mine: "We couldn't find your profile associated with:"
|
||||
# gravatar_not_found_email_suffix: "."
|
||||
# gravatar_signup_prefix: "Sign up at "
|
||||
|
@ -149,9 +157,9 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# gravatar_accounts: "As Seen On"
|
||||
# gravatar_profile_link: "Full Gravatar Profile"
|
||||
|
||||
# play_level:
|
||||
# level_load_error: "Level could not be loaded."
|
||||
# done: "Done"
|
||||
play_level:
|
||||
level_load_error: "Нивото не може да бъде заредено: "
|
||||
done: "Готово"
|
||||
# grid: "Grid"
|
||||
# customize_wizard: "Customize Wizard"
|
||||
# home: "Home"
|
||||
|
@ -173,7 +181,7 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# victory_go_home: "Go Home"
|
||||
# victory_review: "Tell us more!"
|
||||
# victory_hour_of_code_done: "Are You Done?"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
# multiplayer_title: "Multiplayer Settings"
|
||||
# multiplayer_link_description: "Give this link to anyone to have them join you."
|
||||
# multiplayer_hint_label: "Hint:"
|
||||
|
@ -183,7 +191,7 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# tome_minion_spells: "Your Minions' Spells"
|
||||
# tome_read_only_spells: "Read-Only Spells"
|
||||
# tome_other_units: "Other Units"
|
||||
# tome_cast_button_castable: "Cast"
|
||||
# tome_cast_button_castable: "Cast Spell"
|
||||
# tome_cast_button_casting: "Casting"
|
||||
# tome_cast_button_cast: "Spell Cast"
|
||||
# tome_autocast_delay: "Autocast Delay"
|
||||
|
@ -239,22 +247,22 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# new_component_title: "Create New Component"
|
||||
# new_component_field_system: "System"
|
||||
|
||||
# article:
|
||||
# edit_btn_preview: "Preview"
|
||||
# edit_article_title: "Edit Article"
|
||||
article:
|
||||
edit_btn_preview: "Преглед"
|
||||
edit_article_title: "Промени статията"
|
||||
|
||||
# general:
|
||||
# and: "and"
|
||||
# name: "Name"
|
||||
general:
|
||||
and: "и"
|
||||
name: "Име"
|
||||
# body: "Body"
|
||||
# version: "Version"
|
||||
version: "Версия"
|
||||
# commit_msg: "Commit Message"
|
||||
# version_history_for: "Version History for: "
|
||||
# results: "Results"
|
||||
# description: "Description"
|
||||
# or: "or"
|
||||
# email: "Email"
|
||||
# message: "Message"
|
||||
results: "Резултати"
|
||||
description: "Описание"
|
||||
or: "или"
|
||||
email: "Email"
|
||||
message: "Съобщение"
|
||||
|
||||
# about:
|
||||
# who_is_codecombat: "Who is CodeCombat?"
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "български език", englishDescri
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
wizard_settings:
|
||||
title: "Nastavení Kouzelníka"
|
||||
customize_avatar: "Upravte vás Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
account_settings:
|
||||
title: "Nastavení účtu"
|
||||
|
@ -136,7 +144,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
account_profile:
|
||||
edit_settings: "Editovat Nastavení"
|
||||
profile_for_prefix: "Profil pro "
|
||||
profile_for_suffix: ""
|
||||
# profile_for_suffix: ""
|
||||
profile: "Profil"
|
||||
user_not_found: "Uživatel nenalezen. Zkontrolujte adresu URL?"
|
||||
gravatar_not_found_mine: "Nenalezli jsme profil asociovaný s:"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
gravatar_profile_link: "Účet Gravatar"
|
||||
|
||||
play_level:
|
||||
level_load_error: "Úroveň se nepodařilo otevřít."
|
||||
level_load_error: "Úroveň se nepodařilo otevřít: "
|
||||
done: "Hotovo"
|
||||
grid: "Mřížka"
|
||||
customize_wizard: "Upravit Kouzelníka"
|
||||
|
@ -164,7 +172,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
reload_title: "Znovunačíst veškerý kód?"
|
||||
reload_really: "Opravdu chcete resetovat tuto úroveň do počátečního stavu?"
|
||||
reload_confirm: "Znovu načíst vše"
|
||||
victory_title_prefix: ""
|
||||
# victory_title_prefix: ""
|
||||
victory_title_suffix: " Hotovo"
|
||||
victory_sign_up: "Přihlásit se pro uložení postupu"
|
||||
victory_sign_up_poke: "Chcete uložit váš kód? Vytvořte si účet zdarma!"
|
||||
|
@ -238,6 +246,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
create_system_title: "Vytvořit nový systém"
|
||||
new_component_title: "Vytvořit novou komponentu"
|
||||
new_component_field_system: "Systém"
|
||||
|
||||
article:
|
||||
edit_btn_preview: "Náhled"
|
||||
edit_article_title: "Editovat článek"
|
||||
|
@ -351,6 +360,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
alert_account_message_pref: "K přihlášení odebírání emailů si nejprve musíte "
|
||||
alert_account_message_suf: "vytvořit účet"
|
||||
alert_account_message_create_url: "."
|
||||
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
archmage_introduction: "Jedna z nejlepších věcí na vytváření her je to, že se jedná o spojení různých procesů. Grafika, zvuk, síťování v reálném čase, mezilidské vztahy a samozřejmě také spousta běžných aspektů programování, od nízkoúrovňového managementu databáze přes administraci serverů až po tvorbu uživatelská rozhraní. Je zde spousta práce a pokud jste zkušený programátor a všeuměl připravený k ponoření se do hloubek CodeCombatu, tato skupina je pro vás. Budeme moc rádi za vaši pomoc při tvorbě té nejlepší programovací hry."
|
||||
class_attributes: "Vlastnosti"
|
||||
archmage_attribute_1_pref: "Znáte "
|
||||
|
@ -365,6 +375,8 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
join_url_hipchat: "veřejné HipChat chatovací místnosti"
|
||||
more_about_archmage: "Dozvědět se více o tom, jak se stát mocným Arcimágem"
|
||||
archmage_subscribe_desc: "Dostávat emailem oznámení a informacemi nových programovacích příležitostech"
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
artisan_introduction_pref: "Musíme vytvářet další úrovně! Lidé nás prosí o další obsah, ale sami zvládáme vytvořit jen málo. Naším prvním pracovním zastavením je první úroveň. Editor úrovní je tak-tak použitelný i pro jeho vlastní tvůrce. Máte-li vizi pro vytvoření vnořených úrovní alá "
|
||||
artisan_introduction_suf: "pak neváhejte, toto je vaše destinace."
|
||||
artisan_attribute_1: "Předchozí zkušenosti s vytvářením podobného obsahu by byly vítány, například z editorů úrovní Blizzardu, ale nejsou vyžadovány!"
|
||||
|
@ -377,6 +389,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
artisan_join_step4: "Zveřejněte vaši úroveň na fóru pro připomínkování."
|
||||
more_about_artisan: "Dozvědět se více o tom, jak se stát kreativním Řemeslníkem"
|
||||
artisan_subscribe_desc: "Dostávat emailem oznámení a informace o aktualizacích editoru úrovní."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
adventurer_introduction: "Ujasněme si dopředu jednu věc o vaší roli: budete jako tank. Projdete ohněm. Potřebujeme někoho, kdo odzkouší zbrusu nové úrovně a pomůže identifikovat kde je možno je zlepšit. Ten boj bude ohromný - tvorba her je dlouhý proces, který nikdo nezvládne na první pokus. Máte-li na to a vydržíte-li to, pak toto je vaše skupina."
|
||||
adventurer_attribute_1: "Touha po učení se. Vy se chcete naučit programovat a my vás to chceme naučit. Jenom, v tomto případě to budete vy, kdo bude vyučovat."
|
||||
adventurer_attribute_2: "Charismatický. Buďte mírný a pečlivě artikulujte co a jak je potřeba zlepšit."
|
||||
|
@ -384,7 +397,9 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
adventurer_forum_url: " našem fóru"
|
||||
adventurer_join_suf: "takže pokud chcete být v obraze, připojte se k nám!"
|
||||
more_about_adventurer: "Dozvědět se více o tom, jak se stát statečným Dobrodruhem"
|
||||
adventurer_subscribe_desc: "Dostávat emailem oznámení a informace nových úrovních k testování."
|
||||
adventurer_subscribe_desc: "Dostávat emailem oznámení a informace nových úrovních k testování."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
scribe_introduction_pref: "CodeCombat nebude pouze kupa úrovní. Bude také zahrnovat informační zdroje a wiki programovacích konceptů na které se úrovně mohou navázat. Takto, namísto toho aby každý Řemeslník musel sám do detailu popsatco který operátor dělá, mohou jednoduše nalinkovat svoji úroveň na článek existující k edukaci hráčů. Něco ve stylu "
|
||||
scribe_introduction_url_mozilla: "Mozilla Developer Network"
|
||||
scribe_introduction_suf: ". Jestliže vás baví popisovat a předávat koncept programování v Markdown editoru, pak tato role může být právě pro vás."
|
||||
|
@ -393,15 +408,17 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
scribe_join_description: "dejte nám o vás vědět, o vašich zkušenostech s programováním a o čm byste rádi psali. Od toho začneme!"
|
||||
more_about_scribe: "Dozvědět se více o tom, jak se stát pilným Pisálkem"
|
||||
scribe_subscribe_desc: "Dostávat emailem oznámení a informace o článcích."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
diplomat_introduction_pref: "Jedna z věcí, kterou jsme zjistili během "
|
||||
diplomat_launch_url: "zahájení v Říjnu"
|
||||
diplomat_introduction_suf: "bylo, že o CodeCombat je velký zájem i v jiných zemích, obzvláště v Brazílii! Chystáme regiment překladatelů ke zpřístupnění CodeCombatu světu. Pokud chcete nakouknout pod pokličku, dozvědět se o připravovaných novinkách a zpřístupnit úrovně vašim národním kolegům, toto je role pro vás."
|
||||
diplomat_attribute_1: "Plynulost v angličtině a v jazyce do kterého budete překládat. Při předávání komplexních myšlenek je důležité si být jistí v kramflecích v obou jazycích!"
|
||||
diplomat_join_pref: "Úvodní překladatelský počin začal v tomto "
|
||||
diplomat_doc_url: "příspěvku na fóru"
|
||||
diplomat_join_suf: ", tak si jej přečtěte a případně doplňte informace o vašem překladu. Přihlaste se také k odběru informací o vývoji v internacionalizaci!"
|
||||
# diplomat_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
more_about_diplomat: "Dozvědět se více o tom, jak se stát Diplomatem"
|
||||
diplomat_subscribe_desc: "Dostávat emailem oznámení a informace o internacionalizaci a o úrovních k překladu."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
ambassador_introduction: "Zde se tvoří komunita a vy jste její spojení. Využíváme chat, emaily a sociální sítě se spoustou lidí k informování a diskuzím a seznámení s naší hrou. Chcete-li pomoci lidem se přidat a pobavit se a získat dobrý náhled na CodeCombat a kam směřujeme, pak toto je vaše role."
|
||||
ambassador_attribute_1: "Komunikační schopnosti. Schopnost identifikovat problémy hráčů a pomoci jim je řešit. Naslouchat co hráči říkají, co mají rádi a co rádi nemají a komunikovat to zpět ostatním!"
|
||||
ambassador_join_desc: "dejte nám o sobě vědět, o tom co děláte a co byste rádi dělali. Od toho začneme!"
|
||||
|
@ -409,6 +426,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
|
|||
ambassador_join_note_desc: "Jedna z našich priorit je vytvoření vícehráčové hry, kde hráč, který má problém s řešením úrovní může oslovit a požádat o pomoc zkušenější kouzelníky. To je přesně ten případ a místo pro pomoc Velvyslance . Dáme vám vědět více!"
|
||||
more_about_ambassador: "Dozvědět se více o tom, jak se stát nápomocným Velvyslancem"
|
||||
ambassador_subscribe_desc: "Dostávat emailem oznámení a informace o vývoji v podpoře a vícehráčové hře."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
counselor_introduction_1: "Máte životní zkušenosti? Máte odlišný náhled na věci a jste schopni nám tímto pomoci v dalším vývoji CodeCombatu? Jedna z důležitých rolí i když asi nejméně časově náročná, nicméně každá individualita je schopná udělat velký rozdíl. Hledáme zkušené odborníky, zvláště pak v oblastech vzdělávání, vývoji her managementu open source, source project management, náboru lidských zdrojů, podnikání nebo designu."
|
||||
counselor_introduction_2: "Nebo cokoliv, co je relevantní ve vývoji CodeCombatu. Máte-li znalosti a jste-li ochotni se o ně podělit pro další růst tohoto projektu , pak toto je role pro vás."
|
||||
counselor_attribute_1: "Zkušenosti ve výše zmíněných oblastech, nebo něco, čím byste mohli být nápomocni."
|
||||
|
|
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
wizard_settings:
|
||||
title: "Troldmandsinstillinger"
|
||||
customize_avatar: "Tilpas din avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
account_settings:
|
||||
title: "Kontoindstillinger"
|
||||
|
@ -136,7 +144,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
account_profile:
|
||||
edit_settings: "Redigér Indstillinger"
|
||||
profile_for_prefix: "Profil for "
|
||||
profile_for_suffix: ""
|
||||
# profile_for_suffix: ""
|
||||
profile: "Profil"
|
||||
user_not_found: "Ingen bruger fundet. Tjek URL'en?"
|
||||
gravatar_not_found_mine: "Vi kunne ikke finde din profil associeret med:"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
gravatar_profile_link: "Fuld Gravatar Profil"
|
||||
|
||||
play_level:
|
||||
level_load_error: "Banen kunne ikke indlæses."
|
||||
level_load_error: "Banen kunne ikke indlæses: "
|
||||
done: "Færdig"
|
||||
grid: "Gitter"
|
||||
customize_wizard: "Tilpas troldmand"
|
||||
|
@ -183,7 +191,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# tome_minion_spells: "Your Minions' Spells"
|
||||
# tome_read_only_spells: "Read-Only Spells"
|
||||
tome_other_units: "Andre enheder"
|
||||
# tome_cast_button_castable: "Cast"
|
||||
# tome_cast_button_castable: "Cast Spell"
|
||||
# tome_cast_button_casting: "Casting"
|
||||
# tome_cast_button_cast: "Spell Cast"
|
||||
# tome_autocast_delay: "Autocast Delay"
|
||||
|
@ -252,9 +260,9 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
version_history_for: "versionhistorie for: "
|
||||
results: "resultater"
|
||||
description: "beskrivelse"
|
||||
or: "eller"
|
||||
email: "e-mail"
|
||||
message: "Besked"
|
||||
or: "eller"
|
||||
|
||||
about:
|
||||
who_is_codecombat: "Hvem er CodeCombat?"
|
||||
|
@ -282,7 +290,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# page_title: "Legal"
|
||||
# opensource_intro: "CodeCombat is free to play and completely open source."
|
||||
# opensource_description_prefix: "Check out "
|
||||
github_url: "vores GitHub"
|
||||
# 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."
|
||||
|
@ -290,11 +298,11 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# 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: "Sikkerhed"
|
||||
# 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: "E-mail"
|
||||
# email_title: "Email"
|
||||
# email_description_prefix: "We will not inundate you with spam. Through"
|
||||
email_settings_url: "dine e-mail instillinger"
|
||||
# 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:"
|
||||
|
@ -317,8 +325,8 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# 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: "Musik"
|
||||
art_sound: "Lyd"
|
||||
# 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."
|
||||
|
@ -335,7 +343,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# 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: "I en nødeskal"
|
||||
# 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."
|
||||
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
# join_desc_4: "and we'll go from there!"
|
||||
join_url_email: "Skriv til os"
|
||||
# join_url_hipchat: "public HipChat room"
|
||||
# more_about_archmage: "Learn More About Becoming A Powerful Archmage"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
|
|||
artisan_join_step2: "Lav en ny bane og udforsk eksisterende baner."
|
||||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -2,7 +2,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
common:
|
||||
loading: "Lade..."
|
||||
saving: "Speichere..."
|
||||
sending: "Übertrage..." # or Sende... ?
|
||||
sending: "Übertrage..."
|
||||
cancel: "Abbrechen"
|
||||
save: "Speichern"
|
||||
delay_1_sec: "1 Sekunde"
|
||||
|
@ -36,10 +36,10 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
versions:
|
||||
save_version_title: "Neue Version speichern"
|
||||
new_major_version: "Neue Hauptversion"
|
||||
cla_prefix: "Damit Änderungen gespeichert werden können, musst du unsere Lizenzbedingungen (" # To save changes, first you must agree to our ...
|
||||
cla_url: "CLA" # ? CLA: What is this? -> CodeCombat Individual Contributor License Agreement
|
||||
cla_prefix: "Damit Änderungen gespeichert werden können, musst du unsere Lizenzbedingungen ("
|
||||
cla_url: "CLA"
|
||||
cla_suffix: ") akzeptieren."
|
||||
cla_agree: "Ich stimme zu" # die Bestimmungen / I agree the rules
|
||||
cla_agree: "Ich stimme zu"
|
||||
|
||||
login:
|
||||
sign_up: "Registrieren"
|
||||
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
wizard_settings:
|
||||
title: "Zauberer Einstellungen"
|
||||
customize_avatar: "Individualisiere deinen Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
account_settings:
|
||||
title: "Accounteinstellungen"
|
||||
|
@ -122,6 +130,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
new_password_verify: "Passwort verifizieren"
|
||||
email_subscriptions: "Email Abonnements"
|
||||
email_announcements: "Ankündigungen"
|
||||
# email_notifications_description: "Get periodic notifications for your account."
|
||||
email_announcements_description: "Erhalte regelmäßig Mitteilungen für deinen Account."
|
||||
contributor_emails: "Unterstützer Email"
|
||||
contribute_prefix: "Wir suchen nach Leuten, die mitmachen! Schau dir die"
|
||||
|
@ -139,7 +148,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
profile: "Profil"
|
||||
user_not_found: "Kein Nutzer gefunden. URL überprüft?"
|
||||
gravatar_not_found_mine: "Wir konnten dein Profil nicht finden, das mit folgender Email Adresse verbunden ist:"
|
||||
# gravatar_not_found_email_suffix: "."
|
||||
gravatar_not_found_email_suffix: "."
|
||||
gravatar_signup_prefix: "Melde dich an unter "
|
||||
gravatar_signup_suffix: " um los zu legen!"
|
||||
gravatar_not_found_other: "Leider ist kein Profil mit der Email Adresse verknüpft."
|
||||
|
@ -149,7 +158,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
gravatar_profile_link: "Gravatar Profil"
|
||||
|
||||
play_level:
|
||||
level_load_error: "Level konnte nicht geladen werden."
|
||||
level_load_error: "Level konnte nicht geladen werden: "
|
||||
done: "Fertig"
|
||||
grid: "Raster"
|
||||
customize_wizard: "Bearbeite den Zauberer"
|
||||
|
@ -212,12 +221,11 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
level_title: "Level Editor"
|
||||
level_description: "Beinhaltet die Werkzeuge zum Scripten, Hochladen von Tönen und zur Konstruktion eigener Logik, damit jedes erdenkliches Level erstellt werden kann. Genau die Sachen, die wir selber benutzen!"
|
||||
security_notice: "Viele Hauptfunktionen der Editoren sind standardmäßig noch nicht aktiviert. Sobald die Sicherheit dieser Systeme gewährleistet ist, werden sie generell freigeschaltet. Falls Du diese Funktionen früher nutzen möchtest, "
|
||||
contact_us: "setze dich mit uns in Verbindung!" # kontaktiere uns!
|
||||
contact_us: "setze dich mit uns in Verbindung!"
|
||||
hipchat_prefix: "Besuche uns auch in unserem"
|
||||
hipchat_url: "HipChat room."
|
||||
level_some_options: "Einige Einstellungsmöglichkeiten?"
|
||||
# level_tab_thangs: "Thangs" # Things? # <= no Thangs are the components of the level. Check the editor if you're not sure what it is.
|
||||
# rather dont't translate it
|
||||
level_tab_thangs: "Thangs"
|
||||
level_tab_scripts: "Skripte"
|
||||
level_tab_settings: "Einstellungen"
|
||||
level_tab_components: "Komponenten"
|
||||
|
@ -252,15 +260,15 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
version_history_for: "Versionsgeschichte für: "
|
||||
results: "Ergebnisse"
|
||||
description: "Beschreibung"
|
||||
or: "oder"
|
||||
email: "Email"
|
||||
message: "Nachricht"
|
||||
or: "oder"
|
||||
|
||||
about:
|
||||
who_is_codecombat: "Wer ist CodeCombat?" # Wer steckt hinter CodeCombat # behind
|
||||
who_is_codecombat: "Wer ist CodeCombat?"
|
||||
why_codecombat: "Warum CodeCombat?"
|
||||
who_description_prefix: "gründeten CodeCombat im Jahre 2013 zusammen. Wir entwickelten außerdem "
|
||||
who_description_suffix: ", die meist benutzte (#1) Web and iOS Applikation 2008 zum Lernen des Schreibens von chinesischen und japanischen Schriftzeichen." # need improvements
|
||||
who_description_suffix: ", die meist benutzte (#1) Web and iOS Applikation 2008 zum Lernen des Schreibens von chinesischen und japanischen Schriftzeichen."
|
||||
who_description_ending: "Nun ist es an der Zeit, den Leuten das Programmieren beizubringen."
|
||||
why_paragraph_1: "Als er Skritter machte, wusste George nicht wie man programmiert und war permanent darüber frustriert, dass er seine Ideen nicht umsetzen konnte. Danach versuchte er es zu lernen, aber das ging ihm zu langsam. Sein Mitbewohner versuchte Codecademy, als er sich umorientierte und aufhörte zu lehren, aber \"langweilte sich\". Jede Woche begann ein neuer Freund mit Codecademy und ließ es dann wieder bleiben. Wir erkannten, dass es das gleiche Problem war, welches wir mit Skritter gelöst hatten: Leute lernen eine Fähigkeit mittels langsamer, intersiver Lerneinheiten, wobei sie schnelle, umfassende Übung bräuchten. Wir kennen Abhilfe."
|
||||
why_paragraph_2: "Programmieren lernen? Du brauchst keine Stunden. Du musst einen Haufen Code schreiben und dabei Spaß haben."
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -71,7 +71,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
choose_your_level: "Διάλεξε την πίστα σου"
|
||||
adventurer_prefix: "Μπορείτε να μεταβείτε σε οποιοδήποτε επίπεδο κάτω, ή να συζητήσετε για τις πίστες στο "
|
||||
adventurer_forum: "Φόρουμ του \"Τυχοδιώκτη\""
|
||||
# adventurer_suffix: ""
|
||||
# adventurer_suffix: "."
|
||||
campaign_beginner: "Εκστρατεία για Αρχάριους"
|
||||
campaign_beginner_description: "... στο οποίο μπορείτε να μάθετε τη μαγεία του προγραμματισμού"
|
||||
campaign_dev: "Τυχαία δυσκολότερα επίπεδα"
|
||||
|
@ -90,7 +90,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
contribute_suffix: "!"
|
||||
forum_prefix: "Για οτιδήποτε δημόσιο, δοκίμασε "
|
||||
forum_page: "το φόρουμ μας"
|
||||
# forum_suffix: " instead."
|
||||
# forum_suffix: " instead."
|
||||
send: "Αποστολή σχολίων"
|
||||
|
||||
diplomat_suggestion:
|
||||
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
account_settings:
|
||||
title: "Ρυθμίσεις λογαριασμού"
|
||||
|
@ -123,7 +131,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
email_subscriptions: "Συνδρομές Email"
|
||||
email_announcements: "Ανακοινώσεις"
|
||||
# email_notifications_description: "Get periodic notifications for your account."
|
||||
# email_announcements_description: "Λάβετε emails για τα τελευταία νέα και τις εξελίξεις του CodeCombat."
|
||||
email_announcements_description: "Λάβετε emails για τα τελευταία νέα και τις εξελίξεις του CodeCombat."
|
||||
contributor_emails: "Contributor Class Emails"
|
||||
contribute_prefix: "Αναζητούμε για ανθρώπους που θέλουν να "
|
||||
contribute_page: "Σελίδα συνεισφοράς"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
gravatar_profile_link: "Πλήρη προφίλ \"Gravatar\""
|
||||
|
||||
play_level:
|
||||
level_load_error: "Το επίπεδο δεν μπόρεσε να φορτωθεί"
|
||||
level_load_error: "Το επίπεδο δεν μπόρεσε να φορτωθεί: "
|
||||
done: "Έτοιμο"
|
||||
grid: "Πλέγμα"
|
||||
customize_wizard: "Προσαρμόστε τον Μάγο"
|
||||
|
@ -245,16 +253,16 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
|
||||
# general:
|
||||
# and: "and"
|
||||
name: "Όνομα"
|
||||
# name: "Name"
|
||||
# body: "Body"
|
||||
# version: "Version"
|
||||
# commit_msg: "Commit Message"
|
||||
# version_history_for: "Version History for: "
|
||||
# results: "Results"
|
||||
# description: "Description"
|
||||
or: "ή"
|
||||
email: "Email "
|
||||
message: "Μήνυμα"
|
||||
# or: "or"
|
||||
# email: "Email"
|
||||
# message: "Message"
|
||||
|
||||
# about:
|
||||
# who_is_codecombat: "Who is CodeCombat?"
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
|
|||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
# account_settings:
|
||||
# title: "Account Settings"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
|
|||
# gravatar_profile_link: "Full Gravatar Profile"
|
||||
|
||||
# play_level:
|
||||
# level_load_error: "Level could not be loaded."
|
||||
# level_load_error: "Level could not be loaded: "
|
||||
# done: "Done"
|
||||
# grid: "Grid"
|
||||
# customize_wizard: "Customize Wizard"
|
||||
|
@ -173,7 +181,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
|
|||
# victory_go_home: "Go Home"
|
||||
# victory_review: "Tell us more!"
|
||||
# victory_hour_of_code_done: "Are You Done?"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
# multiplayer_title: "Multiplayer Settings"
|
||||
# multiplayer_link_description: "Give this link to anyone to have them join you."
|
||||
# multiplayer_hint_label: "Hint:"
|
||||
|
@ -183,7 +191,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
|
|||
# tome_minion_spells: "Your Minions' Spells"
|
||||
# tome_read_only_spells: "Read-Only Spells"
|
||||
# tome_other_units: "Other Units"
|
||||
# tome_cast_button_castable: "Cast"
|
||||
# tome_cast_button_castable: "Cast Spell"
|
||||
# tome_cast_button_casting: "Casting"
|
||||
# tome_cast_button_cast: "Spell Cast"
|
||||
# tome_autocast_delay: "Autocast Delay"
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
|
|||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
# account_settings:
|
||||
# title: "Account Settings"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
|
|||
# gravatar_profile_link: "Full Gravatar Profile"
|
||||
|
||||
# play_level:
|
||||
# level_load_error: "Level could not be loaded."
|
||||
# level_load_error: "Level could not be loaded: "
|
||||
# done: "Done"
|
||||
# grid: "Grid"
|
||||
# customize_wizard: "Customize Wizard"
|
||||
|
@ -173,7 +181,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
|
|||
# victory_go_home: "Go Home"
|
||||
# victory_review: "Tell us more!"
|
||||
# victory_hour_of_code_done: "Are You Done?"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
# multiplayer_title: "Multiplayer Settings"
|
||||
# multiplayer_link_description: "Give this link to anyone to have them join you."
|
||||
# multiplayer_hint_label: "Hint:"
|
||||
|
@ -183,7 +191,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
|
|||
# tome_minion_spells: "Your Minions' Spells"
|
||||
# tome_read_only_spells: "Read-Only Spells"
|
||||
# tome_other_units: "Other Units"
|
||||
# tome_cast_button_castable: "Cast"
|
||||
# tome_cast_button_castable: "Cast Spell"
|
||||
# tome_cast_button_casting: "Casting"
|
||||
# tome_cast_button_cast: "Spell Cast"
|
||||
# tome_autocast_delay: "Autocast Delay"
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
|
|||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
# account_settings:
|
||||
# title: "Account Settings"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
|
|||
# gravatar_profile_link: "Full Gravatar Profile"
|
||||
|
||||
# play_level:
|
||||
# level_load_error: "Level could not be loaded."
|
||||
# level_load_error: "Level could not be loaded: "
|
||||
# done: "Done"
|
||||
# grid: "Grid"
|
||||
# customize_wizard: "Customize Wizard"
|
||||
|
@ -173,7 +181,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
|
|||
# victory_go_home: "Go Home"
|
||||
# victory_review: "Tell us more!"
|
||||
# victory_hour_of_code_done: "Are You Done?"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
# multiplayer_title: "Multiplayer Settings"
|
||||
# multiplayer_link_description: "Give this link to anyone to have them join you."
|
||||
# multiplayer_hint_label: "Hint:"
|
||||
|
@ -183,7 +191,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
|
|||
# tome_minion_spells: "Your Minions' Spells"
|
||||
# tome_read_only_spells: "Read-Only Spells"
|
||||
# tome_other_units: "Other Units"
|
||||
# tome_cast_button_castable: "Cast"
|
||||
# tome_cast_button_castable: "Cast Spell"
|
||||
# tome_cast_button_casting: "Casting"
|
||||
# tome_cast_button_cast: "Spell Cast"
|
||||
# tome_autocast_delay: "Autocast Delay"
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
|
|||
wizard_settings:
|
||||
title: "Wizard Settings"
|
||||
customize_avatar: "Customize Your Avatar"
|
||||
clothes: "Clothes"
|
||||
trim: "Trim"
|
||||
cloud: "Cloud"
|
||||
spell: "Spell"
|
||||
boots: "Boots"
|
||||
hue: "Hue"
|
||||
saturation: "Saturation"
|
||||
lightness: "Lightness"
|
||||
|
||||
account_settings:
|
||||
title: "Account Settings"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
|
|||
gravatar_profile_link: "Full Gravatar Profile"
|
||||
|
||||
play_level:
|
||||
level_load_error: "Level could not be loaded."
|
||||
level_load_error: "Level could not be loaded: "
|
||||
done: "Done"
|
||||
grid: "Grid"
|
||||
customize_wizard: "Customize Wizard"
|
||||
|
@ -173,7 +181,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
|
|||
victory_go_home: "Go Home"
|
||||
victory_review: "Tell us more!"
|
||||
victory_hour_of_code_done: "Are You Done?"
|
||||
victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
|
||||
victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
multiplayer_title: "Multiplayer Settings"
|
||||
multiplayer_link_description: "Give this link to anyone to have them join you."
|
||||
multiplayer_hint_label: "Hint:"
|
||||
|
@ -183,7 +191,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
|
|||
tome_minion_spells: "Your Minions' Spells"
|
||||
tome_read_only_spells: "Read-Only Spells"
|
||||
tome_other_units: "Other Units"
|
||||
tome_cast_button_castable: "Cast"
|
||||
tome_cast_button_castable: "Cast Spell"
|
||||
tome_cast_button_casting: "Casting"
|
||||
tome_cast_button_cast: "Spell Cast"
|
||||
tome_autocast_delay: "Autocast Delay"
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
|
|||
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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
|
|||
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"
|
||||
more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
artisan_summary_suf: "then this class is for you."
|
||||
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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
|
|||
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"
|
||||
more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
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"
|
||||
more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
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"
|
||||
more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
diplomat_github_url: "on GitHub"
|
||||
diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
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"
|
||||
more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
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"
|
||||
more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
diligent_scribes: "Our Diligent Scribes:"
|
||||
powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
|
|||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
account_settings:
|
||||
title: "Configuración de la Cuenta"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
|
|||
gravatar_profile_link: "Perfil Gravatar Completo"
|
||||
|
||||
play_level:
|
||||
level_load_error: "El nivel no puede ser cargado."
|
||||
level_load_error: "El nivel no puede ser cargado: "
|
||||
done: "Listo"
|
||||
grid: "Cuadricula"
|
||||
customize_wizard: "Personalizar Hechicero"
|
||||
|
@ -245,16 +253,16 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
|
|||
|
||||
# general:
|
||||
# and: "and"
|
||||
or: "o"
|
||||
name: "Nombre"
|
||||
# name: "Name"
|
||||
# body: "Body"
|
||||
# version: "Version"
|
||||
# commit_msg: "Commit Message"
|
||||
# version_history_for: "Version History for: "
|
||||
# results: "Results"
|
||||
# description: "Description"
|
||||
email: "Email"
|
||||
message: "Mensaje"
|
||||
# or: "or"
|
||||
# email: "Email"
|
||||
# message: "Message"
|
||||
|
||||
# about:
|
||||
# who_is_codecombat: "Who is CodeCombat?"
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -104,6 +104,14 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
wizard_settings:
|
||||
title: "Ajustes del mago"
|
||||
customize_avatar: "Personaliza tu Avatar"
|
||||
clothes: "Ropa"
|
||||
# trim: "Trim"
|
||||
cloud: "Nube"
|
||||
# spell: "Spell"
|
||||
boots: "Botas"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
account_settings:
|
||||
title: "Ajustes de la cuenta"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
gravatar_profile_link: "Perfil de Gravatar completo"
|
||||
|
||||
play_level:
|
||||
level_load_error: "No se pudo cargar el nivel."
|
||||
level_load_error: "No se pudo cargar el nivel: "
|
||||
done: "Hecho"
|
||||
grid: "Cuadrícrula"
|
||||
customize_wizard: "Personalizar Mago"
|
||||
|
@ -194,14 +202,14 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
spell_saved: "Hechizo guardado"
|
||||
|
||||
# admin:
|
||||
av_title: "Vista de Administrador"
|
||||
# av_title: "Admin Views"
|
||||
av_entities_sub_title: "Entidades"
|
||||
av_entities_users_url: "Usuarios"
|
||||
av_entities_active_instances_url: "Instancias Activas"
|
||||
av_other_sub_title: "Otras"
|
||||
av_other_debug_base_url: "Base (para depurar base.jade)"
|
||||
u_title: "Lista de Usuario"
|
||||
lg_title: "Últimos juegos"
|
||||
av_other_sub_title: "Otros"
|
||||
# av_other_debug_base_url: "Base (for debugging base.jade)"
|
||||
u_title: "Lista de Usuarios"
|
||||
lg_title: "Últimos Juegos"
|
||||
|
||||
editor:
|
||||
main_title: "Editores de CodeCombat"
|
||||
|
@ -245,7 +253,6 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
|
||||
general:
|
||||
and: "y"
|
||||
or: "o"
|
||||
name: "Nombre"
|
||||
body: "Cuerpo"
|
||||
version: "Versión"
|
||||
|
@ -253,6 +260,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
version_history_for: "Historial de las versiones de: "
|
||||
results: "Resultados"
|
||||
description: "Descripción"
|
||||
or: "o"
|
||||
email: "Correo electrónico"
|
||||
message: "Mensaje"
|
||||
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
alert_account_message_pref: "Para suscribirte a los correos electrónicos de las distintas Clases, necesitarás "
|
||||
alert_account_message_suf: "primero."
|
||||
alert_account_message_create_url: "crear una cuenta"
|
||||
# archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
archmage_introduction: "Una de las mejores partes de desarrollar juegos es que combinan cosas muy diferentes. Gráficos, sonido, uso de redes en tiempo real, redes sociales y por supuesto mucho de los aspectos comunes de la programación, desde gestión de bases de datos a bajo nivel y administración de servidores hasta diseño de experiencia del usuario y creación de interfaces. Hay un montón de cosas por hacer y si eres un programador experimentado con interés en conocer lo que se cuece en la trastienda de CodeCombat, esta Clase puede ser la ideal para ti. Nos encantaría recibir tu ayuda para crear el mejor juego de programación de la historia."
|
||||
class_attributes: "Atributos de las Clases"
|
||||
archmage_attribute_1_pref: "Conocimiento en "
|
||||
|
@ -366,6 +375,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
join_url_hipchat: "sala pública en HipChat"
|
||||
more_about_archmage: "Aprende más sobre convertirte en un poderoso Archimago"
|
||||
archmage_subscribe_desc: "Recibe correos sobre nuevos anuncios y oportunidades de codificar."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
artisan_summary_suf: "entonces esta Clase es la tuya."
|
||||
artisan_introduction_pref: "¡Debemos construir niveles adicionales! La gente clama por más contenido y solo podemos crear unos cuantos. Ahora mismo tu estación de trabajo es el nivel uno; nuestro editor de niveles es apenas usable por sus creadores, así que ten cuidado. Si tienes visiones de campañas que alcanzan el infinito"
|
||||
artisan_introduction_suf: "entonces esta Clase es ideal para ti."
|
||||
artisan_attribute_1: "Cualquier experiencia creando contenido similar estaría bien, como por ejemplo el editor de niveles de Blizzard. ¡Aunque no es necesaria!"
|
||||
|
@ -378,6 +389,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
artisan_join_step4: "Publica tus niveles en el foro para recibir comentarios críticos."
|
||||
more_about_artisan: "Aprende más sobre convertirte en un Artesano creativo"
|
||||
artisan_subscribe_desc: "Recibe correos sobre actualizaciones del editor de niveles y anuncios."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
adventurer_introduction: "Hablemos claro sobre tu papel: eres el tanque. Vas a recibir fuertes daños. Necesitamos gente para probar nuestros flamantes niveles y ayudar a mejorarlos. El dolor será enorme; hacer buenos juegos es un proceso largo y nadie lo consigue a la primera. Si puedes resistir y tener una puntuación alta en Resistencia, entonces esta Clase es para ti."
|
||||
adventurer_attribute_1: "Estar sediento de conocimientos. Quieres aprender a programar y nosotros queremos enseñarte cómo hacerlo. Aunque en este caso es más probable que seas tú el que esté haciendo la mayor parte de la enseñanza."
|
||||
adventurer_attribute_2: "Carismático. Se amable pero claro a la hora de desglosar qué necesita ser mejorado y sugiere de qué formas podría hacerse."
|
||||
|
@ -386,6 +398,8 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
adventurer_join_suf: "así que si prefieres estar informado en esa forma, ¡crea una cuenta allí!"
|
||||
more_about_adventurer: "Aprende más sobre cómo convertirte en un bravo Aventurero"
|
||||
adventurer_subscribe_desc: "Recibe correos cuando haya nuevos niveles para testar."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
scribe_introduction_pref: "CodeCombat no será solo un montón de niveles. También será una fuente de conocimientos, una wiki de conceptos de programación a la que los niveles se engancharan. De esa forma, en lugar de que cada Artesano tenga que describir en detalle qué es un operador de comparación, podrá simplemente enlazar el nivel al Artículo que los describe y que ya ha sido escrito para edificación del jugador. Algo en la línea de lo que la "
|
||||
scribe_introduction_url_mozilla: "Mozilla Developer Network"
|
||||
scribe_introduction_suf: " ha construido. Si tu idea de diversión es articular los conceptos de la programación de una forma sencilla, entonces esta clase es para ti."
|
||||
|
@ -394,15 +408,17 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
scribe_join_description: "cuéntanos más sobre ti, tu experiencia en el mundo de la programación y sobre qué cosas te gustaría escribir. ¡Y continuaremos a partir de ahí!"
|
||||
more_about_scribe: "Aprende más sobre convertirte en un Escriba diligente"
|
||||
scribe_subscribe_desc: "Recibe correos sobre anuncios de redacción de Artículos."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
diplomat_introduction_pref: "Así, si hemos aprendido algo desde el "
|
||||
diplomat_launch_url: "lanzamiento en octubre"
|
||||
diplomat_introduction_suf: "hay un interés considerable en CodeCombat en otros paises, ¡especialmente Brasil! Estamos formando un cuerpo de traductores con ganas de traducir un grupo de palabras tras otro para hacer CodeCombat tan accesible para todo el mundo como sea posible. Si quieres recibir avances de próximos contenidos y quieres poner esos niveles a disposición de los que comparten tu idioma tan pronto como sea posible, entonces esta Clase es para ti."
|
||||
diplomat_attribute_1: "Fluidez con el ingles y el lenguaje al que quieras traducir. Cuando de transmitir ideas complejas se trata, ¡es importante tener grandes conocimientos de ambas!"
|
||||
diplomat_join_pref: "Hemos comenzado un montón de traducciones en "
|
||||
diplomat_doc_url: "este post del foro"
|
||||
diplomat_join_suf: "así que échale un vistazo y añade cosas para tu idioma. También, marca la casilla de abajo para mantenerte al día en nuevos desarrollos de internacionalización!"
|
||||
diplomat_join_pref_github: "Encuentra el fichero local de tu idioma "
|
||||
diplomat_github_url: "en GitHub"
|
||||
diplomat_join_suf_github: ", edítalo online, y solicita que sea revisado. Además, marca la casilla de abajo para mantenerte informado en nuevos progresos en Internacionalización."
|
||||
more_about_diplomat: "Aprende más sobre cómo convertirte en un gran Diplomático"
|
||||
diplomat_subscribe_desc: "Recibe correos sobre nuevos niveles y desarrollos para traducir."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
ambassador_introduction: "Esta es una comunidad en construcción y tú eres parte de las conexiones. Tenemos chat Olark, correos electrónicos y las redes sociales con una gran cantidad de personas con quienes hablar, ayudar a familiarizarse con el juego y aprender. Si quieres ayudar a la gente a que se involucre, se divierta, y tenga buenas sensaciones sobre CodeCombat y hacia dónde vamos, entonces esta clase es para ti."
|
||||
ambassador_attribute_1: "Habilidades de comunicación. Ser capaz de identificar los problemas que los jugadores están teniendo y ayudarles a resolverlos. Además, mantener al resto de nosotros informados sobre lo que los jugadores están diciendo, lo que les gusta, lo que no ¡y de lo que quieren más!"
|
||||
ambassador_join_desc: "cuéntanos más sobre ti, que has hecho y qué estarías interesado en hacer. ¡Y continuaremos a partir de ahí!"
|
||||
|
@ -410,6 +426,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
|
|||
ambassador_join_note_desc: "Una de nuestras principales prioridades es construir un modo multijugador donde los jugadores con mayores dificultades a la hora de resolver un nivel, puedan invocar a los magos más avanzados para que les ayuden. Será una buena manera de que los Embajadores puedan hacer su trabajo. ¡Te mantendremos informado!"
|
||||
more_about_ambassador: "Aprende más sobre cómo convertirte en un amable Embajador"
|
||||
ambassador_subscribe_desc: "Recibe correos sobre actualizaciones de soporte y desarrollo del multijugador."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
counselor_introduction_1: "¿Tienes mucha experiencia vital? ¿Una perspectiva diferente de las cosas que nos puede ayudar a decidir cómo moldear CodeCombat? De todos estos papeles, este es el que te llevará menos tiempo pero en el que marcarás más la diferencia. Estamos buscando eruditos particularmente en áreas como: enseñanza, desarrollo de juegos, gestión de proyectos de código abierto, contratación de técnicos, iniciativa empresarial o diseño."
|
||||
counselor_introduction_2: "O realmente cualquier cosa que sea relevante para el desarrollo de CodeCombat. Si tienes el conocimiento y quieres compartirlo para ayudar a que este proyecto crezca, entonces esta Clase es ideal para ti."
|
||||
counselor_attribute_1: "Experiencia en cualquiera de las áreas mencionadas, o en lo que creas que puede ser de utilidad."
|
||||
|
|
|
@ -4,7 +4,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
saving: "Guardando..."
|
||||
sending: "Enviando..."
|
||||
cancel: "Cancelar"
|
||||
# save: "Save"
|
||||
# save: "Guardar"
|
||||
delay_1_sec: "1 segundo"
|
||||
delay_3_sec: "3 segundos"
|
||||
delay_5_sec: "5 segundos"
|
||||
|
@ -31,15 +31,15 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
about: "Sobre"
|
||||
contact: "Contacto"
|
||||
twitter_follow: "Seguir"
|
||||
# employers: "Employers"
|
||||
# employers: "Empleados"
|
||||
|
||||
# versions:
|
||||
# save_version_title: "Save New Version"
|
||||
# save_version_title: "Guardar Nueva Versión"
|
||||
# new_major_version: "New Major Version"
|
||||
# cla_prefix: "To save changes, first you must agree to our"
|
||||
# cla_prefix: "Para poder guardar los cambios, primero debes aceptar nuestra"
|
||||
# cla_url: "CLA"
|
||||
# cla_suffix: "."
|
||||
# cla_agree: "I AGREE"
|
||||
# cla_agree: "ACEPTO"
|
||||
|
||||
login:
|
||||
sign_up: "Crear Cuenta"
|
||||
|
@ -48,11 +48,11 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
recover: "recuperar cuenta"
|
||||
|
||||
# recover:
|
||||
# recover_account_title: "Recover Account"
|
||||
# send_password: "Send Recovery Password"
|
||||
# recover_account_title: "Recuperar cuenta"
|
||||
# send_password: "Enviar contraseña olvidada"
|
||||
|
||||
signup:
|
||||
# create_account_title: "Create Account to Save Progress"
|
||||
# create_account_title: "Crea una cuenta para guardar el progreso"
|
||||
description: "Es gratis. Solo necesitas un par de cosas y estarás listo para comenzar:"
|
||||
email_announcements: "Recibe noticias por email"
|
||||
coppa: "más de 13 años o fuera de los Estados Unidos"
|
||||
|
@ -102,13 +102,21 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
subscribe_as_diplomat: "Suscribete como un Diplomático"
|
||||
|
||||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
# title: "Configuración del mago"
|
||||
# customize_avatar: "Personaliza tu avatar"
|
||||
# clothes: "Ropa"
|
||||
# trim: "Trim"
|
||||
# cloud: "Nube"
|
||||
# spell: "Spell"
|
||||
# boots: "Botas"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturación"
|
||||
# lightness: "Brillo"
|
||||
|
||||
account_settings:
|
||||
title: "Configuración de la Cuenta"
|
||||
not_logged_in: "Inicia sesión o crea una cuenta para cambiar tu configuración."
|
||||
autosave: "Cambios Guardados Automáticamente"
|
||||
autosave: "Los cambios se guardan Automáticamente"
|
||||
me_tab: "Yo"
|
||||
picture_tab: "Imagen"
|
||||
wizard_tab: "Hechicero"
|
||||
|
@ -131,7 +139,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
email_toggle: "Activar todo"
|
||||
error_saving: "Error al guardar"
|
||||
saved: "Cambios guardados"
|
||||
password_mismatch: "El password no coincide"
|
||||
password_mismatch: "La contraseña no coincide"
|
||||
|
||||
account_profile:
|
||||
edit_settings: "Editar Ajustes"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
gravatar_profile_link: "Prefil de Gravatar completo"
|
||||
|
||||
play_level:
|
||||
level_load_error: "No se pudo cargar el nivel."
|
||||
level_load_error: "No se pudo cargar el nivel: "
|
||||
done: "Hecho"
|
||||
grid: "Cuadrícrula"
|
||||
customize_wizard: "Personalizar Mago"
|
||||
|
@ -225,7 +233,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
# level_tab_thangs_title: "Current Thangs"
|
||||
# level_tab_thangs_conditions: "Starting Conditions"
|
||||
# level_tab_thangs_add: "Add Thangs"
|
||||
# level_settings_title: "Settings"
|
||||
# level_settings_title: "Ajustes"
|
||||
# level_component_tab_title: "Current Components"
|
||||
# level_component_btn_new: "Create New Component"
|
||||
# level_systems_tab_title: "Current Systems"
|
||||
|
@ -245,7 +253,6 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
|
||||
general:
|
||||
# and: "and"
|
||||
or: "o"
|
||||
name: "Nombre"
|
||||
# body: "Body"
|
||||
# version: "Version"
|
||||
|
@ -253,6 +260,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
# version_history_for: "Version History for: "
|
||||
# results: "Results"
|
||||
# description: "Description"
|
||||
or: "o"
|
||||
email: "Email"
|
||||
message: "Mensaje"
|
||||
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|
|
@ -5,10 +5,10 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
sending: "...در حال ارسال"
|
||||
cancel: "لغو"
|
||||
save: "ذخیره "
|
||||
# delay_1_sec: "1 second"
|
||||
# delay_3_sec: "3 seconds"
|
||||
# delay_5_sec: "5 seconds"
|
||||
# manual: "Manual"
|
||||
delay_1_sec: "1 ثانیه"
|
||||
delay_3_sec: "3 ثانیه"
|
||||
delay_5_sec: "5 ثانیه"
|
||||
manual: "دستی"
|
||||
# fork: "Fork"
|
||||
play: "سطوح"
|
||||
|
||||
|
@ -75,47 +75,55 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
campaign_beginner: "کمپین تازه کارها"
|
||||
campaign_beginner_description: ".که شما در آن می توانید جادوگری به وسیله برنامه نویسی را یادبگیرید..."
|
||||
campaign_dev: "مراحل سخت تصادفی"
|
||||
# campaign_dev_description: "... in which you learn the interface while doing something a little harder."
|
||||
campaign_dev_description: "... جایی که میتونید طراحی ظاهر رو یاد بگیرید درحالی که فعالیت سخت تری انجام میدید"
|
||||
campaign_multiplayer: "مسابقات چند نفره"
|
||||
# campaign_multiplayer_description: "... in which you code head-to-head against other players."
|
||||
campaign_multiplayer_description: "... جایی که کد رو به رو شدن با بقیه بازیکنان رو مینویسید."
|
||||
campaign_player_created: "ایجاد بازیکن"
|
||||
# campaign_player_created_description: "... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>."
|
||||
# level_difficulty: "Difficulty: "
|
||||
campaign_player_created_description: "... جایی که در مقابل خلاقیت نیرو هاتون قرار میگیرید <a href=\"/contribute#artisan\">جادوگران آرتیزان</a>."
|
||||
level_difficulty: "سختی: "
|
||||
|
||||
contact:
|
||||
contact_us: "CodeCombatتماس با "
|
||||
welcome: "خوب است از شما بشنویم, از طریق این فرم برای ما ایمیل ارسال کنید"
|
||||
# contribute_prefix: "If you're interested in contributing, check out our "
|
||||
# contribute_page: "contribute page"
|
||||
# contribute_suffix: "!"
|
||||
# forum_prefix: "For anything public, please try "
|
||||
# forum_page: "our forum"
|
||||
# forum_suffix: " instead."
|
||||
# send: "Send Feedback"
|
||||
contribute_prefix: "اگر علاقه مند به همکاری با ما هستید ، این صفحه را مطالعه کنید"
|
||||
contribute_page: "صفحه همکاری"
|
||||
contribute_suffix: "!"
|
||||
forum_prefix: "باری هر چیز عمومی، اینجا را مشاهده کنید "
|
||||
forum_page: "فاروم ما"
|
||||
forum_suffix: " به جای"
|
||||
send: "ارسال بازخورد"
|
||||
|
||||
diplomat_suggestion:
|
||||
# title: "Help translate CodeCombat!"
|
||||
# sub_heading: "We need your language skills."
|
||||
pitch_body: "We develop CodeCombat in English, but we already have players all over the world. Many of them want to play in Persian but don't speak English, so if you can speak both, please consider signing up to be a Diplomat and help translate both the CodeCombat website and all the levels into Persian."
|
||||
missing_translations: "Until we can translate everything into Persian, you'll see English when Persian isn't available."
|
||||
# learn_more: "Learn more about being a Diplomat"
|
||||
# subscribe_as_diplomat: "Subscribe as a Diplomat"
|
||||
title: "کمک به ترجمه کمبت کد!"
|
||||
sub_heading: "ما توانایی زبان شما را نیاز داریم"
|
||||
pitch_body: "ما کمبت کد را به زبان انگلیسی توسعه داده ایم اما بازیکنانی از سراسر دنیا داریم. خیلی از آنها دوست داند به فارسی بازیکنند اما انگلیسی صحبت نکنند, پس اگر به هر دو زبان میتوانید صحبت کنید, پس لطفاً به عنوان دیپلمات ثبت نامکنید و مارا در ترجمه بازی و تمام مراحل به فارسی یاری نمایید."
|
||||
missing_translations: "تا زمانی که به مشغول ترجمه به فارسی هستیم , شما انگلیسی مشاهده میکنید بدون ترجمه فارسی."
|
||||
learn_more: "بیشتر درباره دیپلمات بودن بیاموزید"
|
||||
subscribe_as_diplomat: "به عنوان یک دیپلمات تعقیبمان کنید"
|
||||
|
||||
# wizard_settings:
|
||||
# title: "Wizard Settings"
|
||||
# customize_avatar: "Customize Your Avatar"
|
||||
wizard_settings:
|
||||
title: "تنظیمات جادویی"
|
||||
customize_avatar: "آواتار خود را شکل دهید"
|
||||
# clothes: "Clothes"
|
||||
# trim: "Trim"
|
||||
# cloud: "Cloud"
|
||||
# spell: "Spell"
|
||||
# boots: "Boots"
|
||||
# hue: "Hue"
|
||||
# saturation: "Saturation"
|
||||
# lightness: "Lightness"
|
||||
|
||||
# account_settings:
|
||||
# title: "Account Settings"
|
||||
# not_logged_in: "Log in or create an account to change your settings."
|
||||
# autosave: "Changes Save Automatically"
|
||||
# me_tab: "Me"
|
||||
# picture_tab: "Picture"
|
||||
# wizard_tab: "Wizard"
|
||||
# password_tab: "Password"
|
||||
# emails_tab: "Emails"
|
||||
# gravatar_select: "Select which Gravatar photo to use"
|
||||
# gravatar_add_photos: "Add thumbnails and photos to a Gravatar account for your email to choose an image."
|
||||
account_settings:
|
||||
title: "تنظیمات حساب کاربری"
|
||||
not_logged_in: "برای ایجاد تغییر وارد شوید یا ثبت نام نمایید"
|
||||
autosave: "تغییرات به طور خودکار ثبت شد"
|
||||
me_tab: "من"
|
||||
picture_tab: "تصاویر"
|
||||
wizard_tab: "جادو"
|
||||
password_tab: "کلمه عبور"
|
||||
emails_tab: "ایمیل ها"
|
||||
gravatar_select: " استفاده شود Gravatar انتخاب کنید کدام تصویر"
|
||||
gravatar_add_photos: "Add thumbnails and photos to a Gravatar account for your email to choose an image."
|
||||
# gravatar_add_more_photos: "Add more photos to your Gravatar account to access them here."
|
||||
# wizard_color: "Wizard Clothes Color"
|
||||
# new_password: "New Password"
|
||||
|
@ -150,7 +158,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
# gravatar_profile_link: "Full Gravatar Profile"
|
||||
|
||||
# play_level:
|
||||
# level_load_error: "Level could not be loaded."
|
||||
# level_load_error: "Level could not be loaded: "
|
||||
# done: "Done"
|
||||
# grid: "Grid"
|
||||
# customize_wizard: "Customize Wizard"
|
||||
|
@ -173,7 +181,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
# victory_go_home: "Go Home"
|
||||
# victory_review: "Tell us more!"
|
||||
# victory_hour_of_code_done: "Are You Done?"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
# multiplayer_title: "Multiplayer Settings"
|
||||
# multiplayer_link_description: "Give this link to anyone to have them join you."
|
||||
# multiplayer_hint_label: "Hint:"
|
||||
|
@ -183,7 +191,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
# tome_minion_spells: "Your Minions' Spells"
|
||||
# tome_read_only_spells: "Read-Only Spells"
|
||||
# tome_other_units: "Other Units"
|
||||
# tome_cast_button_castable: "Cast"
|
||||
# tome_cast_button_castable: "Cast Spell"
|
||||
# tome_cast_button_casting: "Casting"
|
||||
# tome_cast_button_cast: "Spell Cast"
|
||||
# tome_autocast_delay: "Autocast Delay"
|
||||
|
@ -245,7 +253,6 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
|
||||
general:
|
||||
# and: "and"
|
||||
or: "یا"
|
||||
name: "نام"
|
||||
# body: "Body"
|
||||
# version: "Version"
|
||||
|
@ -253,6 +260,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
# version_history_for: "Version History for: "
|
||||
# results: "Results"
|
||||
# description: "Description"
|
||||
or: "یا"
|
||||
email: "ایمیل"
|
||||
message: "پیام"
|
||||
|
||||
|
@ -352,6 +360,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
# 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_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever."
|
||||
# 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 "
|
||||
|
@ -364,10 +373,12 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
# 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"
|
||||
# more_about_archmage: "Learn More About Becoming an Archmage"
|
||||
# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
|
||||
# artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to"
|
||||
# artisan_summary_suf: "then this class is for you."
|
||||
# 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_introduction_suf: "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!"
|
||||
|
@ -376,46 +387,52 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
|
|||
# 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"
|
||||
# more_about_artisan: "Learn More About Becoming an Artisan"
|
||||
# artisan_subscribe_desc: "Get emails on level editor updates and announcements."
|
||||
# adventurer_sumamry: "Let us be clear about your role: you are the tank. You are 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 is for you."
|
||||
# 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"
|
||||
# more_about_adventurer: "Learn More About Becoming an Adventurer"
|
||||
# adventurer_subscribe_desc: "Get emails when there are new levels to test."
|
||||
# scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the "
|
||||
# scribe_summary_sufx: " has built. If you enjoy explaining programming concepts, then this class is for you."
|
||||
# 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"
|
||||
# more_about_scribe: "Learn More About Becoming a Scribe"
|
||||
# scribe_subscribe_desc: "Get emails about article writing announcements."
|
||||
# diplomat_summary: "There is a large interest in CodeCombat in other countries that do not speak English! We are looking for translators who are willing to spend their time translating the site's corpus of words so that CodeCombat is accessible across the world as soon as possible. If you'd like to help getting CodeCombat international, then this class is for you."
|
||||
# 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_introduction_suf: "it's that there is sizeable interest in CodeCombat in other countries! 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_join_pref_github: "Find your language locale file "
|
||||
# diplomat_github_url: "on GitHub"
|
||||
# diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!"
|
||||
# more_about_diplomat: "Learn More About Becoming a Diplomat"
|
||||
# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate."
|
||||
# ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you."
|
||||
# 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"
|
||||
# more_about_ambassador: "Learn More About Becoming an Ambassador"
|
||||
# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments."
|
||||
# counselor_summary: "None of the above roles fit what you are interested in? Do not worry, we are on the lookout for anybody who wants a hand in the development of CodeCombat! If you are interested in teaching, game development, open source management, or anything else that you think will be relevant to us, then this class is for you."
|
||||
# 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"
|
||||
# more_about_counselor: "Learn More About Becoming a Counselor"
|
||||
# changes_auto_save: "Changes are saved automatically when you toggle checkboxes."
|
||||
# diligent_scribes: "Our Diligent Scribes:"
|
||||
# powerful_archmages: "Our Powerful Archmages:"
|
||||
|
|