mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-13 22:49:51 -04:00
Merge branch 'master' of https://github.com/codecombat/codecombat
This commit is contained in:
commit
6350debf26
23 changed files with 576 additions and 216 deletions
BIN
app/assets/images/pages/play/level/modal/achievement_plate.png
Normal file
BIN
app/assets/images/pages/play/level/modal/achievement_plate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
BIN
app/assets/images/pages/play/level/modal/reward_icon_gems.png
Normal file
BIN
app/assets/images/pages/play/level/modal/reward_icon_gems.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
app/assets/images/pages/play/level/modal/reward_icon_xp.png
Normal file
BIN
app/assets/images/pages/play/level/modal/reward_icon_xp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
app/assets/images/pages/play/level/modal/reward_plate.png
Normal file
BIN
app/assets/images/pages/play/level/modal/reward_plate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
app/assets/images/pages/play/level/modal/victory_word.png
Normal file
BIN
app/assets/images/pages/play/level/modal/victory_word.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9 KiB |
|
@ -29,7 +29,7 @@ module.exports = class LevelBus extends Bus
|
|||
constructor: ->
|
||||
super(arguments...)
|
||||
@changedSessionProperties = {}
|
||||
@saveSession = _.debounce(@saveSession, 1000, {maxWait: 5000})
|
||||
@saveSession = _.debounce(@reallySaveSession, 1000, {maxWait: 5000})
|
||||
@playerIsIdle = false
|
||||
|
||||
init: ->
|
||||
|
@ -190,7 +190,7 @@ module.exports = class LevelBus extends Bus
|
|||
state.complete = true
|
||||
@session.set('state', state)
|
||||
@changedSessionProperties.state = true
|
||||
@saveSession()
|
||||
@reallySaveSession() # Make sure it saves right away; don't debounce it.
|
||||
|
||||
onNewGoalStates: ({goalStates})->
|
||||
state = @session.get 'state'
|
||||
|
@ -232,7 +232,8 @@ module.exports = class LevelBus extends Bus
|
|||
@changedSessionProperties.permissions = true
|
||||
@saveSession()
|
||||
|
||||
saveSession: ->
|
||||
# Debounced as saveSession
|
||||
reallySaveSession: ->
|
||||
return if _.isEmpty @changedSessionProperties
|
||||
# don't let peeking admins mess with the session accidentally
|
||||
return unless @session.get('multiplayer') or @session.get('creator') is me.id
|
||||
|
|
|
@ -8,7 +8,7 @@ module.exports.createAetherOptions = (options) ->
|
|||
aetherOptions =
|
||||
functionName: options.functionName
|
||||
protectAPI: not options.skipProtectAPI
|
||||
includeFlow: options.includeFlow
|
||||
includeFlow: Boolean options.includeFlow
|
||||
yieldConditionally: options.functionName is 'plan'
|
||||
simpleLoops: true
|
||||
globals: ['Vector', '_']
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
** Paths and target pieces (and ghosts?)
|
||||
** Normal Thangs, bots, wizards (z-indexing based on World-determined sprite.thang.pos.z/y, mainly, instead of sprite-map-determined sprite.z, which we rename to... something)
|
||||
** Above-thang marks (blood, highlight) and health bars
|
||||
|
||||
|
||||
* Stage (Regular Canvas)
|
||||
** Camera border
|
||||
** surfaceTextLayer (speech, names)
|
||||
|
@ -14,7 +14,7 @@
|
|||
*** Letterbox
|
||||
**** Letterbox top and bottom
|
||||
*** FPS display, maybe grid axis labels, coordinate hover
|
||||
|
||||
|
||||
** Grid lines--somewhere--we will figure it out, do not really need it at first
|
||||
###
|
||||
|
||||
|
@ -26,7 +26,7 @@ SingularSprite = require './SingularSprite'
|
|||
NEVER_RENDER_ANYTHING = false # set to true to test placeholders
|
||||
|
||||
module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
||||
|
||||
|
||||
# Intermediary between a Surface Stage and a top-level static normal Container or hot-swapped WebGL SpriteContainer.
|
||||
# It handles zooming in different ways and, if webGL, creating and assigning spriteSheets.
|
||||
|
||||
|
@ -79,8 +79,9 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
toString: -> "<Layer #{@layerPriority}: #{@name}>"
|
||||
|
||||
#- Layer ordering
|
||||
|
||||
|
||||
updateLayerOrder: ->
|
||||
return if @destroyed
|
||||
@container.sortChildren @layerOrderComparator
|
||||
|
||||
layerOrderComparator: (a, b) ->
|
||||
|
@ -105,7 +106,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
return 0 unless aPos and bPos
|
||||
return (bPos.y - aPos.y) or (bPos.x - aPos.x)
|
||||
return az - bz
|
||||
|
||||
|
||||
#- Zoom updating
|
||||
|
||||
onZoomUpdated: (e) ->
|
||||
|
@ -141,13 +142,13 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
child.scaleY *= @container.scaleY
|
||||
|
||||
#- Adding, removing children for WebGL layers.
|
||||
|
||||
|
||||
addLank: (lank) ->
|
||||
# TODO: Move this into the production DB rather than setting it dynamically.
|
||||
if lank.thangType?.get('name') is 'Highlight'
|
||||
lank.thangType.set('spriteType', 'segmented')
|
||||
lank.options.resolutionFactor = @resolutionFactor
|
||||
|
||||
|
||||
lank.layer = @
|
||||
@listenTo(lank, 'action-needs-render', @onActionNeedsRender)
|
||||
@lanks.push lank
|
||||
|
@ -164,7 +165,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
@lanks = _.without @lanks, lank
|
||||
|
||||
#- Loading network resources dynamically
|
||||
|
||||
|
||||
loadThangType: (thangType) ->
|
||||
if not thangType.isFullyLoaded()
|
||||
thangType.setProjection null
|
||||
|
@ -185,7 +186,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
@renderNewSpriteSheet()
|
||||
|
||||
#- Adding to the list of things we need to render
|
||||
|
||||
|
||||
onActionNeedsRender: (lank, action) ->
|
||||
@upsertActionToRender(lank.thangType, action.name, lank.options.colorConfig)
|
||||
|
||||
|
@ -214,16 +215,16 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
@_renderNewSpriteSheet(false)
|
||||
|
||||
#- Rendering sprite sheets
|
||||
|
||||
|
||||
renderNewSpriteSheet: ->
|
||||
@willRender = false
|
||||
return if @numThingsLoading
|
||||
@_renderNewSpriteSheet()
|
||||
|
||||
|
||||
_renderNewSpriteSheet: (async) ->
|
||||
@asyncBuilder.stopAsync() if @asyncBuilder
|
||||
@asyncBuilder = null
|
||||
|
||||
|
||||
async ?= @buildAsync
|
||||
builder = new createjs.SpriteSheetBuilder()
|
||||
groups = _.groupBy(@toRenderBundles, ((bundle) -> @renderGroupingKey(bundle.thangType, '', bundle.colorConfig)), @)
|
||||
|
@ -233,7 +234,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
dimension = @resolutionFactor * SPRITE_PLACEHOLDER_WIDTH
|
||||
placeholder.setBounds(0, 0, dimension, dimension)
|
||||
builder.addFrame(placeholder)
|
||||
|
||||
|
||||
# Add custom graphics
|
||||
extantGraphics = if @spriteSheet?.resolutionFactor is @resolutionFactor then @spriteSheet.getAnimations() else []
|
||||
for key, graphic of @customGraphics
|
||||
|
@ -244,7 +245,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
else
|
||||
frame = builder.addFrame(graphic.graphic, graphic.bounds, @resolutionFactor)
|
||||
builder.addAnimation(key, [frame], false)
|
||||
|
||||
|
||||
# Render ThangTypes
|
||||
groups = {} if NEVER_RENDER_ANYTHING
|
||||
for bundleGrouping in _.values(groups)
|
||||
|
@ -259,7 +260,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
@renderSingularThangType(args...)
|
||||
else
|
||||
@renderRasterThangType(thangType, builder)
|
||||
|
||||
|
||||
if async
|
||||
try
|
||||
builder.buildAsync()
|
||||
|
@ -272,11 +273,11 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
sheet = builder.build()
|
||||
@onBuildSpriteSheetComplete({async:async}, builder)
|
||||
return sheet
|
||||
|
||||
|
||||
onBuildSpriteSheetComplete: (e, builder) ->
|
||||
return if @initializing or @destroyed
|
||||
@asyncBuilder = null
|
||||
|
||||
|
||||
if builder.spriteSheet._images.length > 1
|
||||
total = 0
|
||||
# get a rough estimate of how much smaller the spritesheet needs to be
|
||||
|
@ -285,10 +286,10 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
@resolutionFactor /= (Math.max(1.1, Math.sqrt(total)))
|
||||
@_renderNewSpriteSheet(e.async)
|
||||
return
|
||||
|
||||
|
||||
@spriteSheet = builder.spriteSheet
|
||||
@spriteSheet.resolutionFactor = @resolutionFactor
|
||||
oldLayer = @container
|
||||
oldLayer = @container
|
||||
@container = new createjs.SpriteContainer(@spriteSheet)
|
||||
for lank in @lanks
|
||||
console.log 'zombie sprite found on layer', @name if lank.destroyed
|
||||
|
@ -307,7 +308,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
lank.updateScale()
|
||||
lank.updateRotation()
|
||||
@trigger 'new-spritesheet'
|
||||
|
||||
|
||||
resetSpriteSheet: ->
|
||||
@removeLank(lank) for lank in @lanks.slice(0)
|
||||
@toRenderBundles = []
|
||||
|
@ -317,9 +318,9 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
@initializing = false
|
||||
|
||||
#- Placeholder
|
||||
|
||||
|
||||
createPlaceholder: ->
|
||||
# TODO: Experiment with this. Perhaps have rectangles if default layer is obstacle or floor,
|
||||
# TODO: Experiment with this. Perhaps have rectangles if default layer is obstacle or floor,
|
||||
# and different colors for different layers.
|
||||
g = new createjs.Graphics()
|
||||
g.setStrokeStyle(5)
|
||||
|
@ -341,7 +342,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
else
|
||||
g.drawRect(bounds...)
|
||||
new createjs.Shape(g)
|
||||
|
||||
|
||||
#- Rendering containers for segmented thang types
|
||||
|
||||
renderSegmentedThangType: (thangType, colorConfig, actionNames, spriteSheetBuilder) ->
|
||||
|
@ -353,7 +354,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
else if action.animation
|
||||
animationContainers = @getContainersForAnimation(thangType, action.animation, action)
|
||||
containersToRender[container.gn] = true for container in animationContainers
|
||||
|
||||
|
||||
spriteBuilder = new SpriteBuilder(thangType, {colorConfig: colorConfig})
|
||||
for containerGlobalName in _.keys(containersToRender)
|
||||
containerKey = @renderGroupingKey(thangType, containerGlobalName, colorConfig)
|
||||
|
@ -374,9 +375,9 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
for animation in thangType.get('raw').animations[animation].animations
|
||||
containers = containers.concat(@getContainersForAnimation(thangType, animation.gn, action))
|
||||
return containers
|
||||
|
||||
|
||||
#- Rendering sprite sheets for singular thang types
|
||||
|
||||
|
||||
renderSingularThangType: (thangType, colorConfig, actionNames, spriteSheetBuilder) ->
|
||||
actionObjects = _.values(thangType.getActions())
|
||||
animationActions = []
|
||||
|
@ -384,14 +385,14 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
continue unless a.animation
|
||||
continue unless a.name in actionNames
|
||||
animationActions.push(a)
|
||||
|
||||
|
||||
spriteBuilder = new SpriteBuilder(thangType, {colorConfig: colorConfig})
|
||||
|
||||
|
||||
animationGroups = _.groupBy animationActions, (action) -> action.animation
|
||||
for animationName, actions of animationGroups
|
||||
renderAll = _.any actions, (action) -> action.frames is undefined
|
||||
scale = actions[0].scale or thangType.get('scale') or 1
|
||||
|
||||
|
||||
actionKeys = (@renderGroupingKey(thangType, action.name, colorConfig) for action in actions)
|
||||
if @spriteSheet?.resolutionFactor is @resolutionFactor and _.all(actionKeys, (key) => key in @spriteSheet.getAnimations())
|
||||
framesNeeded = _.uniq(_.flatten((@spriteSheet.getAnimation(key)).frames for key in actionKeys))
|
||||
|
@ -406,9 +407,9 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
next = @nextForAction(action)
|
||||
spriteSheetBuilder.addAnimation(key, frames, next)
|
||||
continue
|
||||
|
||||
|
||||
mc = spriteBuilder.buildMovieClip(animationName, null, null, null, {'temp':0})
|
||||
|
||||
|
||||
if renderAll
|
||||
res = spriteSheetBuilder.addMovieClip(mc, null, scale * @resolutionFactor)
|
||||
frames = spriteSheetBuilder._animations['temp'].frames
|
||||
|
@ -420,23 +421,23 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
frame = parseInt(frame)
|
||||
f = _.bind(mc.gotoAndStop, mc, frame)
|
||||
framesMap[frame] = spriteSheetBuilder.addFrame(mc, null, scale * @resolutionFactor, f)
|
||||
|
||||
|
||||
for action in actions
|
||||
name = @renderGroupingKey(thangType, action.name, colorConfig)
|
||||
|
||||
|
||||
if action.frames
|
||||
frames = (framesMap[parseInt(frame)] for frame in action.frames.split(','))
|
||||
else
|
||||
frames = _.sortBy(_.values(framesMap))
|
||||
next = @nextForAction(action)
|
||||
spriteSheetBuilder.addAnimation(name, frames, next)
|
||||
|
||||
spriteSheetBuilder.addAnimation(name, frames, next)
|
||||
|
||||
containerActions = []
|
||||
for a in actionObjects
|
||||
continue unless a.container
|
||||
continue unless a.name in actionNames
|
||||
containerActions.push(a)
|
||||
|
||||
|
||||
containerGroups = _.groupBy containerActions, (action) -> action.container
|
||||
for containerName, actions of containerGroups
|
||||
container = spriteBuilder.buildContainerFromStore(containerName)
|
||||
|
@ -444,25 +445,25 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
frame = spriteSheetBuilder.addFrame(container, null, scale * @resolutionFactor)
|
||||
for action in actions
|
||||
name = @renderGroupingKey(thangType, action.name, colorConfig)
|
||||
spriteSheetBuilder.addAnimation(name, [frame], false)
|
||||
|
||||
spriteSheetBuilder.addAnimation(name, [frame], false)
|
||||
|
||||
nextForAction: (action) ->
|
||||
next = true
|
||||
next = action.goesTo if action.goesTo
|
||||
next = false if action.loops is false
|
||||
return next
|
||||
|
||||
|
||||
#- Rendering frames for raster thang types
|
||||
|
||||
|
||||
renderRasterThangType: (thangType, spriteSheetBuilder) ->
|
||||
unless thangType.rasterImage
|
||||
console.error("Cannot render the LayerAdapter SpriteSheet until the raster image for <#{thangType.get('name')}> is loaded.")
|
||||
|
||||
|
||||
bm = new createjs.Bitmap(thangType.rasterImage[0])
|
||||
scale = thangType.get('scale') or 1
|
||||
frame = spriteSheetBuilder.addFrame(bm, null, scale)
|
||||
spriteSheetBuilder.addAnimation(@renderGroupingKey(thangType), [frame], false)
|
||||
|
||||
|
||||
#- Distributing new Segmented/Singular/RasterSprites to Lanks
|
||||
|
||||
setSpriteToLank: (lank) ->
|
||||
|
@ -474,7 +475,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
sprite.regX = @resolutionFactor * SPRITE_PLACEHOLDER_WIDTH / 2
|
||||
sprite.regY = @resolutionFactor * SPRITE_PLACEHOLDER_WIDTH
|
||||
sprite.baseScaleX = sprite.baseScaleY = sprite.scaleX = sprite.scaleY = 10 / (@resolutionFactor * SPRITE_PLACEHOLDER_WIDTH)
|
||||
|
||||
|
||||
else if lank.thangType.get('raster')
|
||||
sprite = new createjs.Sprite(@spriteSheet)
|
||||
scale = lank.thangType.get('scale') or 1
|
||||
|
@ -483,7 +484,7 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
sprite.regY = -reg.y * scale
|
||||
sprite.gotoAndStop(@renderGroupingKey(lank.thangType))
|
||||
sprite.baseScaleX = sprite.baseScaleY = 1
|
||||
|
||||
|
||||
else
|
||||
SpriteClass = if (lank.thangType.get('spriteType') or @defaultSpriteType) is 'segmented' then SegmentedSprite else SingularSprite
|
||||
prefix = @renderGroupingKey(lank.thangType, null, lank.options.colorConfig) + '.'
|
||||
|
@ -507,4 +508,4 @@ module.exports = LayerAdapter = class LayerAdapter extends CocoClass
|
|||
destroy: ->
|
||||
child.destroy?() for child in @container.children
|
||||
@asyncBuilder.stopAsync() if @asyncBuilder
|
||||
super()
|
||||
super()
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
module.exports = nativeDescription: "Ελληνικά", englishDescription: "Greek", translation:
|
||||
home:
|
||||
slogan: "Μάθε να προγραμμάτιζεις με JavaScript μέσω ενός παιχνιδιού"
|
||||
no_ie: "Το CodeCombat δεν παίζει με το Internet Explorer 8 ή κάποια παλαιότερη έκδοση. Συγνώμη!" # Warning that only shows up in IE8 and older
|
||||
slogan: "Μάθε να Προγραμμάτιζεις Παίζοντας ένα Παιχνίδι"
|
||||
no_ie: "Το CodeCombat δεν τρέχει σε Internet Explorer 9 ή παλαιότερη έκδοση. Συγνώμη!" # Warning that only shows up in IE8 and older
|
||||
no_mobile: "Το CodeCombat δεν σχεδιάστηκε για κινητά και μπορεί να μην δουλεύει!" # Warning that shows up on mobile devices
|
||||
play: "Παίξε" # The big play button that just starts playing a level
|
||||
old_browser: "Ωχ, ο περιηγητής σας είναι πολύ παλιός για να τρέξετε το CodeCombat. Συγνώμη!" # Warning that shows up on really old Firefox/Chrome/Safari
|
||||
old_browser_suffix: "Μπορείτε να δοκιμάσετε, αλλά πιθανών να μην λειτουργήσει."
|
||||
old_browser: "Ωχ, ο περιηγητής σας είναι πολύ παλιός για να τρέξει το CodeCombat. Συγνώμη!" # Warning that shows up on really old Firefox/Chrome/Safari
|
||||
old_browser_suffix: "Μπορείτε να δοκιμάσετε, αλλά πιθανότατα να μην λειτουργήσει."
|
||||
campaign: "Εκστρατεία"
|
||||
for_beginners: "Για αρχάριους"
|
||||
# multiplayer: "Multiplayer" # Not currently shown on home page
|
||||
multiplayer: "Πολλαπλοί Παίκτες" # Not currently shown on home page
|
||||
for_developers: "Για προγραμματιστές" # Not currently shown on home page.
|
||||
# javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers." # Not currently shown on home page
|
||||
# python_blurb: "Simple yet powerful, Python is a great general purpose programming language." # Not currently shown on home page
|
||||
# coffeescript_blurb: "Nicer JavaScript syntax." # Not currently shown on home page
|
||||
# clojure_blurb: "A modern Lisp." # Not currently shown on home page
|
||||
# lua_blurb: "Game scripting language." # Not currently shown on home page
|
||||
# io_blurb: "Simple but obscure." # Not currently shown on home page
|
||||
javascript_blurb: "Η γλώσσα του web. Ιδανική για δημιουργία ιστοσελίδων, web εφαρμογών, παιχνίδια HTML5, και διακομιστές." # Not currently shown on home page
|
||||
python_blurb: "Απλή αλλά δυνατή, η Python είναι μια πολύ καλή γλώσσα προγραμματισμού γενικής χρήσης." # Not currently shown on home page
|
||||
coffeescript_blurb: "Καλύτερη JavaScript σύνταξη." # Not currently shown on home page
|
||||
clojure_blurb: "Μοντέρνα Lisp." # Not currently shown on home page
|
||||
lua_blurb: "Scripting γλώσσα παιχνιδιών." # Not currently shown on home page
|
||||
io_blurb: "Απλή αλλά ασαφής." # Not currently shown on home page
|
||||
|
||||
nav:
|
||||
play: "Επίπεδα" # The top nav bar entry where players choose which levels to play
|
||||
|
@ -30,7 +30,7 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
admin: "Διαχειριστής" # Only shows up when you are an admin
|
||||
home: "Αρχική"
|
||||
contribute: "Συνεισφέρω"
|
||||
legal: "Νόμικά"
|
||||
legal: "Νομικά"
|
||||
about: "Σχετικά με"
|
||||
contact: "Επικοινωνία"
|
||||
twitter_follow: "Ακολούθησε"
|
||||
|
@ -44,76 +44,76 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
page_not_found: "Η σελίδα δεν βρέθηκε"
|
||||
|
||||
diplomat_suggestion:
|
||||
title: "Βοηθήστε στην μετάφραση CodeCombat!" # This shows up when a player switches to a non-English language using the language selector.
|
||||
title: "Βοηθήστε στην μετάφραση του CodeCombat!" # This shows up when a player switches to a non-English language using the language selector.
|
||||
sub_heading: "Χρειαζόμαστε τις γλωσσικές σας δεξιότητες."
|
||||
pitch_body: "Αναπτύσσουμε το CodeCombat στα αγγλικά, αλλά ήδη έχουμε παίκτες από όλο τον κόσμο. Πολλοί από αυτούς θέλουν να παίξουν στα αγγλικά, αλλά δεν μιλούν αγγλικά, οπότε αν μπορείτε να μιλήσετε και τις δύο, παρακαλούμε να Αναπτύσσουμε CodeCombat στα αγγλικά, αλλά ήδη έχουμε παίκτες σε όλο τον κόσμο. Πολλοί από αυτούς θέλουν να παίξουν στα Ελληνικά, αλλά δεν μιλούν αγγλικά, οπότε αν μπορείτε να μιλήσετε και τις δύο γλώσσες, παρακαλούμε να σκεφτείτε την εγγραφή ως ένας Διπλωμάτης και βοηθήστε να μεταφραστεί τόσο η ιστοσελίδα CodeCombat και όλα τα επίπεδα στην Ελληνική γλώσσα."
|
||||
pitch_body: "Αναπτύσσουμε το CodeCombat στα Αγγλικά, αλλά ήδη έχουμε παίκτες από όλο τον κόσμο. Πολλοί από αυτούς θέλουν να παίξουν στα Ελληνικά, αλλά δεν μιλούν Αγγλικά, οπότε αν μπορείτε να μιλήσετε και τις δύο, παρακαλούμε να σκεφτείτε την εγγραφή ως Διπλωμάτης και να βοηθήσετε να μεταφραστεί τόσο η ιστοσελίδα CodeCombat και όλα τα επίπεδα στην Ελληνική."
|
||||
missing_translations: "Μέχρι να μπορούν να μεταφράσουν τα πάντα σε Ελληνικά, θα δείτε την αγγλική γλώσσα όπου τα Ελληνικά δεν είναι διαθέσιμα."
|
||||
learn_more: "Μάθετε περισσότερα σχετικά με το να είστε ένας Διπλωμάτης"
|
||||
subscribe_as_diplomat: "Εγγραφή ως Διπλωμάτης"
|
||||
|
||||
play:
|
||||
# play_as: "Play As" # Ladder page
|
||||
# spectate: "Spectate" # Ladder page
|
||||
# players: "players" # Hover over a level on /play
|
||||
# hours_played: "hours played" # Hover over a level on /play
|
||||
# items: "Items" # Tooltip on item shop button from /play
|
||||
# heroes: "Heroes" # Tooltip on hero shop button from /play
|
||||
# achievements: "Achievements" # Tooltip on achievement list button from /play
|
||||
# account: "Account" # Tooltip on account button from /play
|
||||
# settings: "Settings" # Tooltip on settings button from /play
|
||||
# next: "Next" # Go from choose hero to choose inventory before playing a level
|
||||
play_as: "Παίξτε ως" # Ladder page
|
||||
spectate: "Θεατής" # Ladder page
|
||||
players: "παίκτες" # Hover over a level on /play
|
||||
hours_played: "ώρες παιχνιδιού" # Hover over a level on /play
|
||||
items: "Αντικείμενα" # Tooltip on item shop button from /play
|
||||
heroes: "Ήρωες" # Tooltip on hero shop button from /play
|
||||
achievements: "Επιτεύγματα" # Tooltip on achievement list button from /play
|
||||
account: "Λογαριασμός" # Tooltip on account button from /play
|
||||
settings: "Ρυθμίσεις" # Tooltip on settings button from /play
|
||||
next: "Επόμενο" # Go from choose hero to choose inventory before playing a level
|
||||
# change_hero: "Change Hero" # Go back from choose inventory to choose hero
|
||||
# choose_inventory: "Equip Items"
|
||||
# older_campaigns: "Older Campaigns"
|
||||
# anonymous: "Anonymous Player"
|
||||
choose_inventory: "Εξοπλίσου με Αντικείμενα"
|
||||
older_campaigns: "Παλαιότερες Εκστρατείες"
|
||||
anonymous: "Ανώνυμοι Παίκτες"
|
||||
level_difficulty: "Δυσκολία: "
|
||||
campaign_beginner: "Εκστρατεία για Αρχάριους"
|
||||
choose_your_level: "Διάλεξε την πίστα σου" # The rest of this section is the old play view at /play-old and isn't very important.
|
||||
adventurer_prefix: "Μπορείτε να μεταβείτε σε οποιοδήποτε επίπεδο κάτω, ή να συζητήσετε για τις πίστες στο "
|
||||
adventurer_forum: "Φόρουμ του \"Τυχοδιώκτη\""
|
||||
# adventurer_suffix: "."
|
||||
# campaign_old_beginner: "Old Beginner Campaign"
|
||||
campaign_beginner_description: "... στο οποίο μπορείτε να μάθετε τη μαγεία του προγραμματισμού"
|
||||
campaign_dev: "Τυχαία δυσκολότερα επίπεδα"
|
||||
campaign_dev_description: "... στο οποίο μπορείτε να μάθετε το περιβάλλον, ενώ κάνετε κάτι λίγο πιο δύσκολο."
|
||||
choose_your_level: "Διάλεξε το επίπεδο σου" # The rest of this section is the old play view at /play-old and isn't very important.
|
||||
adventurer_prefix: "Μπορείτε να μεταβείτε σε οποιοδήποτε επίπεδο κάτω, ή να συζητήσετε για τις πίστες στο "
|
||||
adventurer_forum: "Φόρουμ του Adventurer"
|
||||
adventurer_suffix: "."
|
||||
campaign_old_beginner: "Παλαιότερη Εκστρατεία Αρχαρίων"
|
||||
campaign_beginner_description: "... στην οποία μαθαίνετε τη μαγεία του προγραμματισμού."
|
||||
campaign_dev: "Τυχαία Δυσκολότερα Επίπεδα"
|
||||
campaign_dev_description: "... στα οποία μπορείτε να μάθετε το περιβάλλον, ενώ κάνετε κάτι λίγο δυσκολότερο."
|
||||
campaign_multiplayer: "Αρένες Πολλαπλών Παικτών"
|
||||
campaign_multiplayer_description: "... στο οποίο μπορείτε να προγραμματίσετε σώμα με σώμα έναντι άλλων παικτών."
|
||||
# campaign_player_created: "Player-Created"
|
||||
# campaign_player_created_description: "... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>."
|
||||
# campaign_classic_algorithms: "Classic Algorithms"
|
||||
# campaign_classic_algorithms_description: "... in which you learn the most popular algorithms in Computer Science."
|
||||
campaign_multiplayer_description: "... στις οποίες προγραμματίζετε σώμα-με-σώμα εναντίον άλλων παικτών."
|
||||
campaign_player_created: "Δημιουργημένη-από-Παίκτες"
|
||||
campaign_player_created_description: "... στην οποία μάχεστε ενάντια στην δημιουργικότητα των συναδέλφων <a href=\"/contribute#artisan\">Τεχνιτών Μάγων</a>."
|
||||
campaign_classic_algorithms: "Κλασσικοί Αλγόριθμοι"
|
||||
campaign_classic_algorithms_description: "... στο οποίο μαθαίνετε του πιο δημοφιλής αλγορίθμους της Επιστήμης της Πληροφορικής."
|
||||
|
||||
login:
|
||||
sign_up: "Δημιούργησε Λογαριασμό"
|
||||
sign_up: "Δημιουργία Λογαριασμού"
|
||||
log_in: "Σύνδεση"
|
||||
# logging_in: "Logging In"
|
||||
logging_in: "Σύνδεση"
|
||||
log_out: "Αποσύνδεση"
|
||||
recover: "Κάντε ανάκτηση του λογαριασμού σας"
|
||||
recover: "Ανάκτηση λογαριασμού"
|
||||
|
||||
signup:
|
||||
create_account_title: "Δημιουργία λογαριασμού για αποθήκευση της προόδου"
|
||||
description: "Είναι δωρεάν. Απλώς χρειάζεται να έχεις έναν λογαριασμό και θα είσαι έτοιμος να παίξεις:"
|
||||
email_announcements: "Λαμβάνετε ανακοινώσεις μέσω e-mail"
|
||||
create_account_title: "Δημιουργία λογαριασμού για Αποθήκευση της Προόδου"
|
||||
description: "Είναι δωρεάν. Απλώς χρειάζεται λίγα πράγματα και θα είσαι έτοιμος να παίξεις:"
|
||||
email_announcements: "Λαμβάνετε ανακοινώσεις μέσω email"
|
||||
coppa: "13+ ή Εκτός Αμερικής "
|
||||
coppa_why: "(Γιατί;)"
|
||||
creating: "Δημιουργία λογαριασμού"
|
||||
creating: "Δημιουργία Λογαριασμού..."
|
||||
sign_up: "Εγγραφή"
|
||||
log_in: "Σύνδεση με κωδικό"
|
||||
social_signup: "Ή, μπορείς να συνδεθείς μέσω του Facebook ή του G+:"
|
||||
# required: "You need to log in before you can go that way."
|
||||
social_signup: "Ή, μπορείς να συνδεθείς μέσω Facebook ή G+:"
|
||||
required: "Θα πρέπει να συνδεθείτε πριν πάτε προς τα εκεί."
|
||||
|
||||
recover:
|
||||
recover_account_title: "Κάντε ανάκτηση του λογαριασμού σας"
|
||||
send_password: "Αποστολή κωδικού ανάκτησης"
|
||||
# recovery_sent: "Recovery email sent."
|
||||
recover_account_title: "Ανάκτηση λογαριασμού"
|
||||
send_password: "Αποστολή Κωδικού Ανάκτησης"
|
||||
recovery_sent: "Email ανάκτησης στάλθηκε."
|
||||
|
||||
# items:
|
||||
# armor: "Armor"
|
||||
# hands: "Hands"
|
||||
# accessories: "Accessories"
|
||||
# books: "Books"
|
||||
# minions: "Minions"
|
||||
# misc: "Misc"
|
||||
items:
|
||||
armor: "Πανοπλία"
|
||||
hands: "Χέρια"
|
||||
accessories: "Εξαρτήματα"
|
||||
books: "Βιβλία"
|
||||
minions: "Minions"
|
||||
misc: "Διάφορα"
|
||||
|
||||
common:
|
||||
loading: "Φορτώνει..."
|
||||
|
@ -182,13 +182,13 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
play_level:
|
||||
done: "Έτοιμο"
|
||||
home: "Αρχική"
|
||||
# skip: "Skip"
|
||||
# game_menu: "Game Menu"
|
||||
skip: "Παράλειψη"
|
||||
game_menu: "Μενού Παιχνιδιού"
|
||||
guide: "Οδηγός"
|
||||
# restart: "Restart"
|
||||
restart: "Επανεκκίνηση"
|
||||
goals: "Στόχοι"
|
||||
# goal: "Goal"
|
||||
# success: "Success!"
|
||||
goal: "Στόχος"
|
||||
success: "Επιτυχία!"
|
||||
# incomplete: "Incomplete"
|
||||
# timed_out: "Ran out of time"
|
||||
# failing: "Failing"
|
||||
|
@ -267,7 +267,7 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
# tip_hofstadters_law: "Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law."
|
||||
# tip_premature_optimization: "Premature optimization is the root of all evil. - Donald Knuth"
|
||||
# tip_brute_force: "When in doubt, use brute force. - Ken Thompson"
|
||||
customize_wizard: "Προσαρμόστε τον Μάγο"
|
||||
customize_wizard: "Προσαρμογή Μάγου"
|
||||
|
||||
game_menu:
|
||||
# inventory_tab: "Inventory"
|
||||
|
@ -363,9 +363,9 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
contribute_prefix: "Αν σας ενδιαφέρει να βοηθήσετε, ελέγξτε την "
|
||||
contribute_page: "σελίδα συνεισφοράς"
|
||||
contribute_suffix: "!"
|
||||
forum_prefix: "Για οτιδήποτε δημόσιο, δοκίμασε "
|
||||
forum_prefix: "Για οτιδήποτε δημόσιο, παρακαλούμε δοκίμαστε "
|
||||
forum_page: "το φόρουμ μας"
|
||||
# forum_suffix: " instead."
|
||||
forum_suffix: ""
|
||||
send: "Αποστολή σχολίων"
|
||||
# contact_candidate: "Contact Candidate" # Deprecated
|
||||
# recruitment_reminder: "Use this form to reach out to candidates you are interested in interviewing. Remember that CodeCombat charges 15% of first-year salary. The fee is due upon hiring the employee and is refundable for 90 days if the employee does not remain employed. Part time, remote, and contract employees are free, as are interns." # Deprecated
|
||||
|
@ -379,7 +379,7 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
upload_picture: "Ανέβασμα φωτογραφίας"
|
||||
password_tab: "Κωδικός"
|
||||
emails_tab: "Emails"
|
||||
# admin: "Admin"
|
||||
admin: "Διαχειριστής"
|
||||
new_password: "Καινούργιος Κωδικός"
|
||||
new_password_verify: " Επαλήθευση Κωδικού"
|
||||
email_subscriptions: "Συνδρομές Email"
|
||||
|
@ -401,7 +401,7 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
error_saving: "Σφάλμα αποθήκευσης"
|
||||
saved: "Οι αλλαγές αποθηκεύτηκαν"
|
||||
password_mismatch: "Οι κωδικοί δεν ταιριάζουν"
|
||||
# password_repeat: "Please repeat your password."
|
||||
password_repeat: "Παρακαλώ επαναλάβετε τον κωδικό σας."
|
||||
# job_profile: "Job Profile" # Rest of this section (the job profile stuff and wizard stuff) is deprecated
|
||||
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
|
||||
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."
|
||||
|
@ -874,7 +874,7 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
color: "Χρώμα"
|
||||
group: "Ομάδα"
|
||||
clothes: "Ρούχα"
|
||||
# trim: "Trim"
|
||||
trim: "Τελείωμα"
|
||||
cloud: "Σύννεφο"
|
||||
team: "Ομάδα"
|
||||
spell: "Ξόρκι"
|
||||
|
@ -888,9 +888,9 @@ module.exports = nativeDescription: "Ελληνικά", englishDescription: "Gre
|
|||
edit_profile: "Επεξεργασία προφίλ"
|
||||
done_editing: "Τέλος επεξεργασίας"
|
||||
profile_for_prefix: "Προφίλ για "
|
||||
# profile_for_suffix: ""
|
||||
# featured: "Featured"
|
||||
# not_featured: "Not Featured"
|
||||
profile_for_suffix: ""
|
||||
featured: "Προτεινόμενα"
|
||||
not_featured: "Μη Προτεινόμενα"
|
||||
looking_for: "Αναζήτηση για:"
|
||||
last_updated: "Τελευταία ενημερώθηκε:"
|
||||
contact: "Επικοινωνία"
|
||||
|
|
|
@ -205,6 +205,7 @@
|
|||
victory_return_to_ladder: "Return to Ladder"
|
||||
victory_play_next_level: "Play Next Level" # Only in old-style levels.
|
||||
victory_play_continue: "Continue"
|
||||
victory_saving_progress: "Saving Progress"
|
||||
victory_go_home: "Go Home" # Only in old-style levels.
|
||||
victory_review: "Tell us more!" # Only in old-style levels.
|
||||
victory_hour_of_code_done: "Are You Done?"
|
||||
|
|
|
@ -27,12 +27,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
profile: "Perfil"
|
||||
stats: "Estatísticas"
|
||||
code: "Código"
|
||||
admin: "Administrador" # Only shows up when you are an admin
|
||||
admin: "Admin" # Only shows up when you are an admin
|
||||
home: "Início"
|
||||
contribute: "Contribuir"
|
||||
legal: "Legal"
|
||||
about: "Sobre"
|
||||
contact: "Contacte"
|
||||
contact: "Contactar"
|
||||
twitter_follow: "Seguir"
|
||||
teachers: "Professores"
|
||||
|
||||
|
@ -216,9 +216,9 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
tome_cast_button_castable: "Lançar Feitiço" # Temporary, if tome_cast_button_run isn't translated.
|
||||
tome_cast_button_casting: "A Lançar" # Temporary, if tome_cast_button_running isn't translated.
|
||||
tome_cast_button_cast: "Feitiço Lançado" # Temporary, if tome_cast_button_ran isn't translated.
|
||||
tome_cast_button_run: "Correr"
|
||||
tome_cast_button_running: "A Correr"
|
||||
tome_cast_button_ran: "Corrido"
|
||||
tome_cast_button_run: "Executar"
|
||||
tome_cast_button_running: "A Executar"
|
||||
tome_cast_button_ran: "Executado"
|
||||
tome_submit_button: "Submeter"
|
||||
tome_reload_method: "Recarregar o código original para este método" # Title text for individual method reload button.
|
||||
tome_select_method: "Selecionar um método"
|
||||
|
@ -545,9 +545,9 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
# 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: "Atributos da Classe"
|
||||
# archmage_attribute_1_pref: "Knowledge in "
|
||||
# archmage_attribute_1_suf: ", or a desire to learn. Most of our code is in this language. If you're a fan of Ruby or Python, you'll feel right at home. It's JavaScript, but with a nicer syntax."
|
||||
# archmage_attribute_2: "Some experience in programming and personal initiative. We'll help you get oriented, but we can't spend much time training you."
|
||||
archmage_attribute_1_pref: "Conhecimento em "
|
||||
archmage_attribute_1_suf: ", ou vontade de aprender. A maioria do nosso código está nesta linguagem. Se és um fã de Ruby ou Python, vais sentir-te em casa. É igual ao JavaScript, mas com uma sintaxe melhor."
|
||||
archmage_attribute_2: "Alguma experiência em programação e iniciativa pessoal. Nós ajudamos-te a orientares-te, mas não podemos gastar muito tempo a treinar-te."
|
||||
how_to_join: "Como Me Junto"
|
||||
join_desc_1: "Qualquer um pode ajudar! Só tens de conferir o nosso "
|
||||
join_desc_2: "para começares, e assinalar a caixa abaixo para te declarares um bravo Arcomago e receberes as últimas notícias por e-mail. Queres falar sobre o que fazer ou como te envolveres mais profundamente no projeto? "
|
||||
|
@ -591,10 +591,10 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
more_about_scribe: "Aprende Mais Sobre Tornares-te um Escrivão"
|
||||
scribe_subscribe_desc: "Receber e-mails sobre anúncios relativos à escrita de artigos."
|
||||
# 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! 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_introduction_pref: "Portanto, se há uma coisa que aprendemos com o nosso "
|
||||
diplomat_launch_url: "lançamento em Outubro"
|
||||
diplomat_introduction_suf: "é que há um interesse considerável no CodeCombat noutros países! Estamos a construir um exército de tradutores dispostos a transformar um conjunto de palavras noutro conjuto de palavras, para conseguir que o CodeCombat fique o mais acessível quanto posível em todo o mundo. Se gostas de dar espreitadelas a conteúdos futuros e disponibilizar estes níveis para os teus colegas nacionais o mais depressa possível, então esta classe talvez seja para ti."
|
||||
diplomat_attribute_1: "Fluência em Inglês e no idioma para o qual gostarias de traduzir. Quando são tentadas passar ideias complicadas, é importante uma excelente compreensão das duas!"
|
||||
diplomat_join_pref_github: "Encontra o ficheiro 'locale' do teu idioma "
|
||||
diplomat_github_url: "no GitHub"
|
||||
diplomat_join_suf_github: ", edita-o online e submete um 'pull request'. Assinala ainda esta caixa abaixo para ficares atualizado em relação a novos desenvolvimentos da internacionalização!"
|
||||
|
@ -814,16 +814,16 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
# recruitment_description_ending: "the site remains free and everybody's happy. That's the plan."
|
||||
copyrights_title: "Direitos Autorais e Licensas"
|
||||
contributor_title: "Contrato de Licença do Contribuinte (CLA)"
|
||||
# contributor_description_prefix: "All contributions, both on the site and on our GitHub repository, are subject to our"
|
||||
contributor_description_prefix: "Todas as contribuições, tanto no sítio como no nosso repositório GitHub, estão sujeitas ao nosso"
|
||||
cla_url: "CLA"
|
||||
# contributor_description_suffix: "to which you should agree before contributing."
|
||||
contributor_description_suffix: "com o qual deves concordar antes de contribuir."
|
||||
code_title: "Código - MIT"
|
||||
# code_description_prefix: "All code owned by CodeCombat or hosted on codecombat.com, both in the GitHub repository or in the codecombat.com database, is licensed under the"
|
||||
mit_license_url: "licença do MIT"
|
||||
# code_description_suffix: "This includes all code in Systems and Components that are made available by CodeCombat for the purpose of creating levels."
|
||||
art_title: "Arte/Música - Creative Commons "
|
||||
# art_description_prefix: "All common content is available under the"
|
||||
# cc_license_url: "Creative Commons Attribution 4.0 International License"
|
||||
art_description_prefix: "Todos os conteúdos comuns estão disponíveis à luz da"
|
||||
cc_license_url: "Licença 'Creative Commons Attribution 4.0 International'"
|
||||
# art_description_suffix: "Common content is anything made generally available by CodeCombat for the purpose of creating Levels. This includes:"
|
||||
art_music: "Música"
|
||||
art_sound: "Som"
|
||||
|
@ -989,8 +989,8 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
|
|||
player_code: "Código do Jogador"
|
||||
|
||||
employers:
|
||||
# deprecation_warning_title: "Sorry, CodeCombat is not recruiting right now."
|
||||
# deprecation_warning: "We are focusing on beginner levels instead of finding expert developers for the time being."
|
||||
deprecation_warning_title: "Desculpa, o CodeCombat não está a recrutar por agora."
|
||||
deprecation_warning: "Atualmente, estamos a focar-nos em níveis para iniciantes, em vez de tentar encontar desenvolvedores peritos."
|
||||
hire_developers_not_credentials: "Não contrates cartas de recomendação, mas sim programadores." # We are not actively recruiting right now, so there's no need to add new translations for the rest of this section.
|
||||
get_started: "Começar"
|
||||
already_screened: "Nós já selecionamos tecnicamente todos os nossos candidatos"
|
||||
|
|
|
@ -108,12 +108,12 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
# recovery_sent: "Recovery email sent."
|
||||
|
||||
items:
|
||||
armor: "Броня" #"Armor"
|
||||
hands: "Руки" #"Hands"
|
||||
accessories: "Аксессуары" #"Accessories"
|
||||
books: "Книги" #"Books"
|
||||
armor: "Броня"
|
||||
hands: "Руки"
|
||||
accessories: "Аксессуары"
|
||||
books: "Книги"
|
||||
# minions: "Minions"
|
||||
misc: "Разное" #"Misc"
|
||||
misc: "Разное"
|
||||
|
||||
common:
|
||||
loading: "Загрузка..."
|
||||
|
@ -277,7 +277,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
# guide_tab: "Guide"
|
||||
multiplayer_tab: "Мультиплеер"
|
||||
# inventory_caption: "Equip your hero"
|
||||
choose_hero_caption: "Выбор героя, языка" #"Choose hero, language"
|
||||
choose_hero_caption: "Выбор героя, языка"
|
||||
# save_load_caption: "... and view history"
|
||||
# options_caption: "Configure settings"
|
||||
# guide_caption: "Docs and tips"
|
||||
|
@ -287,13 +287,13 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
# choose_inventory: "Equip Items"
|
||||
|
||||
choose_hero:
|
||||
choose_hero: "Выберите героя" # "Choose Your Hero"
|
||||
programming_language: "Язык программирования" # "Programming Language"
|
||||
programming_language_description: "Какой язык программирования вы хотите использовать?" # "Which programming language do you want to use?"
|
||||
status: "Статус" # "Status"
|
||||
weapons: "Оружие" # "Weapons"
|
||||
health: "Жизнь" # "Health"
|
||||
speed: "Скорость" # "Speed"
|
||||
choose_hero: "Выберите героя"
|
||||
programming_language: "Язык программирования"
|
||||
programming_language_description: "Какой язык программирования вы хотите использовать?"
|
||||
status: "Статус"
|
||||
weapons: "Оружие"
|
||||
health: "Жизнь"
|
||||
speed: "Скорость"
|
||||
|
||||
save_load:
|
||||
granularity_saved_games: "Сохранено"
|
||||
|
|
|
@ -670,29 +670,29 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese
|
|||
# rules: "Rules"
|
||||
# winners: "Winners"
|
||||
|
||||
# user:
|
||||
user:
|
||||
# stats: "Stats"
|
||||
# singleplayer_title: "Singleplayer Levels"
|
||||
# multiplayer_title: "Multiplayer Levels"
|
||||
# achievements_title: "Achievements"
|
||||
# last_played: "Last Played"
|
||||
# status: "Status"
|
||||
# status_completed: "Completed"
|
||||
# status_unfinished: "Unfinished"
|
||||
# no_singleplayer: "No Singleplayer games played yet."
|
||||
# no_multiplayer: "No Multiplayer games played yet."
|
||||
# no_achievements: "No Achievements earned yet."
|
||||
# favorite_prefix: "Favorite language is "
|
||||
# favorite_postfix: "."
|
||||
singleplayer_title: "單人遊戲等級"
|
||||
multiplayer_title: "多人遊戲等級"
|
||||
achievements_title: "成就"
|
||||
last_played: "最後游玩"
|
||||
status: "狀態"
|
||||
status_completed: "已完成"
|
||||
status_unfinished: "未完成"
|
||||
no_singleplayer: "還沒有玩過單人遊戲."
|
||||
no_multiplayer: "還沒有玩過多 人遊戲."
|
||||
no_achievements: "還沒有取得成就."
|
||||
favorite_prefix: "語言喜好為"
|
||||
favorite_postfix: "."
|
||||
|
||||
# achievements:
|
||||
achievements:
|
||||
# last_earned: "Last Earned"
|
||||
# amount_achieved: "Amount"
|
||||
# achievement: "Achievement"
|
||||
# category_contributor: "Contributor"
|
||||
amount_achieved: "數量"
|
||||
achievement: "成就"
|
||||
category_contributor: "貢獻者"
|
||||
# category_miscellaneous: "Miscellaneous"
|
||||
# category_levels: "Levels"
|
||||
# category_undefined: "Uncategorized"
|
||||
category_levels: "等級"
|
||||
category_undefined: "未定義"
|
||||
# current_xp_prefix: ""
|
||||
# current_xp_postfix: " in total"
|
||||
# new_xp_prefix: ""
|
||||
|
@ -701,9 +701,9 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese
|
|||
# left_xp_infix: " until level "
|
||||
# left_xp_postfix: ""
|
||||
|
||||
# account:
|
||||
# recently_played: "Recently Played"
|
||||
# no_recent_games: "No games played during the past two weeks."
|
||||
account:
|
||||
recently_played: "最近玩過"
|
||||
no_recent_games: "在過去兩個星期沒有遊戲玩過。"
|
||||
|
||||
# loading_error:
|
||||
# could_not_load: "Error loading from server"
|
||||
|
|
|
@ -1,2 +1,188 @@
|
|||
#hero-victory-modal
|
||||
color: red
|
||||
|
||||
//- Header
|
||||
|
||||
.background-wrapper
|
||||
background: url("/images/pages/play/level/modal/victory_modal_background.png")
|
||||
height: 650px
|
||||
width: 550px
|
||||
|
||||
#victory-header
|
||||
display: block
|
||||
margin: 40px auto 0
|
||||
|
||||
.modal-header
|
||||
height: 110px
|
||||
border: none
|
||||
|
||||
|
||||
//- Achievement panels
|
||||
|
||||
.modal-body
|
||||
padding: 0 20px
|
||||
|
||||
.achievement-panel
|
||||
background: url("/images/pages/play/level/modal/achievement_plate.png")
|
||||
width: 451px
|
||||
height: 144px
|
||||
margin: 5px auto
|
||||
position: relative
|
||||
|
||||
-webkit-transition-duration: 1s
|
||||
-moz-transition-duration: 1s
|
||||
-o-transition-duration: 1s
|
||||
transition-duration: 1s
|
||||
|
||||
-webkit-filter: grayscale(100%)
|
||||
-moz-filter: grayscale(100%)
|
||||
-o-filter: grayscale(100%)
|
||||
filter: grayscale(100%)
|
||||
|
||||
&.earned
|
||||
-webkit-filter: none
|
||||
-moz-filter: none
|
||||
-o-filter: none
|
||||
filter: none
|
||||
|
||||
.achievement-description
|
||||
position: absolute
|
||||
text-align: center
|
||||
left: 95px
|
||||
right: 98px
|
||||
top: 10px
|
||||
color: white
|
||||
white-space: nowrap
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
|
||||
.achievement-rewards
|
||||
position: absolute
|
||||
left: 25px
|
||||
right: 23px
|
||||
top: 41px
|
||||
bottom: 18px
|
||||
|
||||
|
||||
//- Reward panels
|
||||
|
||||
.reward-panel
|
||||
background: url("/images/pages/play/level/modal/reward_plate.png")
|
||||
background: url("/images/pages/play/level/modal/reward_plate.png")
|
||||
width: 77px
|
||||
height: 85px
|
||||
float: left
|
||||
margin: 0 1.8px
|
||||
position: relative
|
||||
|
||||
.reward-image-container
|
||||
top: 8px
|
||||
left: 11px
|
||||
height: 55px
|
||||
width: 56px
|
||||
position: relative
|
||||
|
||||
-webkit-transform: scale(0, 0)
|
||||
-moz-transform: scale(0, 0)
|
||||
-o-transform: scale(0, 0)
|
||||
transform: scale(0, 0)
|
||||
|
||||
-webkit-transition-duration: 0.5s
|
||||
-moz-transition-duration: 0.5s
|
||||
-o-transition-duration: 0.5s
|
||||
transition-duration: 0.5s
|
||||
|
||||
&.show
|
||||
-webkit-transform: scale(1, 1)
|
||||
-moz-transform: scale(1, 1)
|
||||
-o-transform: scale(1, 1)
|
||||
transform: scale(1, 1)
|
||||
|
||||
img
|
||||
margin: 0
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 50%
|
||||
margin-right: -50%
|
||||
|
||||
-webkit-transition-duration: 0.5s
|
||||
-moz-transition-duration: 0.5s
|
||||
-o-transition-duration: 0.5s
|
||||
transition-duration: 0.5s
|
||||
|
||||
-webkit-transform: translate(-50%, -50%)
|
||||
-moz-transform: translate(-50%, -50%)
|
||||
-o-transform: translate(-50%, -50%)
|
||||
transform: translate(-50%, -50%)
|
||||
|
||||
max-width: 56px
|
||||
max-height: 55px
|
||||
|
||||
.reward-text
|
||||
position: absolute
|
||||
bottom: 6px
|
||||
left: 4px
|
||||
right: 3px
|
||||
height: 15px
|
||||
text-align: center
|
||||
color: white
|
||||
font-weight: bold
|
||||
font-size: 12px
|
||||
white-space: nowrap
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
|
||||
|
||||
//- Pulse effect
|
||||
|
||||
@-webkit-keyframes pulse
|
||||
from
|
||||
-webkit-transform: translate(-50%, -50%) scale(1.0)
|
||||
50%
|
||||
-webkit-transform: translate(-50%, -50%) scale(1.3)
|
||||
to
|
||||
-webkit-transform: translate(-50%, -50%) scale(1.0)
|
||||
|
||||
@-moz-keyframes pulse
|
||||
from
|
||||
-moz-transform: translate(-50%, -50%) scale(1.0)
|
||||
50%
|
||||
-moz-transform: translate(-50%, -50%) scale(1.3)
|
||||
to
|
||||
-moz-transform: translate(-50%, -50%) scale(1.0)
|
||||
|
||||
@-o-keyframes pulse
|
||||
from
|
||||
-o-transform: translate(-50%, -50%) scale(1.0)
|
||||
50%
|
||||
-o-transform: translate(-50%, -50%) scale(1.3)
|
||||
to
|
||||
-o-transform: translate(-50%, -50%) scale(1.0)
|
||||
|
||||
@keyframes pulse
|
||||
from
|
||||
transform: translate(-50%, -50%) scale(1.0)
|
||||
50%
|
||||
transform: translate(-50%, -50%) scale(1.3)
|
||||
to
|
||||
transform: translate(-50%, -50%) scale(1.0)
|
||||
|
||||
.pulse
|
||||
-webkit-animation: pulse 0.5s infinite
|
||||
-moz-animation: pulse 0.5s infinite
|
||||
-o-animation: pulse 0.5s infinite
|
||||
animation: pulse 0.5s infinite
|
||||
|
||||
|
||||
//- Footer
|
||||
|
||||
.modal-content
|
||||
height: 650px // so the footer appears at the bottom
|
||||
|
||||
.modal-footer
|
||||
position: absolute
|
||||
bottom: 20px
|
||||
left: 20px
|
||||
right: 20px
|
||||
|
||||
#totals
|
||||
color: white
|
|
@ -15,7 +15,6 @@
|
|||
strong.tip(data-i18n='play_level.tip_guide_exists') Click the guide at the top of the page for useful info.
|
||||
strong.tip(data-i18n='play_level.tip_open_source') CodeCombat is 100% open source!
|
||||
strong.tip(data-i18n='play_level.tip_beta_launch') CodeCombat launched its beta in October, 2013.
|
||||
strong.tip(data-i18n='play_level.tip_js_beginning') JavaScript is just the beginning.
|
||||
strong.tip(data-i18n='play_level.tip_think_solution') Think of the solution, not the problem.
|
||||
strong.tip(data-i18n='play_level.tip_theory_practice') In theory there is no difference between theory and practice; in practice there is. - Yogi Berra
|
||||
strong.tip(data-i18n='play_level.tip_error_free') There are two ways to write error-free programs; only the third one works. - Alan Perlis
|
||||
|
|
|
@ -1,34 +1,54 @@
|
|||
extends /templates/modal/modal_base
|
||||
block modal-header-content
|
||||
h3
|
||||
span(data-i18n="play_level.victory_title_prefix")
|
||||
span= levelName
|
||||
span(data-i18n="play_level.victory_title_suffix") Complete
|
||||
img(src="/images/pages/play/level/modal/victory_word.png")#victory-header
|
||||
|
||||
block modal-body-content
|
||||
h4 Achievements Unlocked
|
||||
|
||||
|
||||
for achievement in achievements
|
||||
.panel
|
||||
img(src=achievement.getImageURL())
|
||||
h5= achievement.get('name')
|
||||
p= achievement.get('description')
|
||||
if achievement.completed
|
||||
strong Completed
|
||||
else
|
||||
strong Incomplete
|
||||
p Earned #{achievement.get('worth')} xp.
|
||||
- var animate = achievement.completed && !achievement.completedAWhileAgo
|
||||
.achievement-panel(class=achievement.completedAWhileAgo ? 'earned' : '' data-achievement-id=achievement.id data-animate=animate)
|
||||
- var rewards = achievement.get('rewards') || {};
|
||||
if rewards.gems
|
||||
p Earned #{achievement.get('rewards').gems} gems.
|
||||
if rewards.heroes
|
||||
for hero in rewards.heroes
|
||||
- var hero = thangTypes[hero];
|
||||
img(src=hero.getPortraitURL())
|
||||
if rewards.items
|
||||
for item in rewards.items
|
||||
- var item = thangTypes[item];
|
||||
img(src=item.getPortraitURL())
|
||||
|
||||
div.achievement-description= achievement.get('description')
|
||||
|
||||
div.achievement-rewards
|
||||
- var worth = achievement.get('worth', true);
|
||||
if worth
|
||||
.reward-panel.numerical(data-number=worth, data-number-unit='xp')
|
||||
.reward-image-container(class=animate?'':'show')
|
||||
img(src="/images/pages/play/level/modal/reward_icon_xp.png")
|
||||
.reward-text= animate ? 'x0' : '+'+worth
|
||||
|
||||
if rewards.gems
|
||||
.reward-panel.numerical(data-number=rewards.gems, data-number-unit='gem')
|
||||
.reward-image-container(class=animate?'':'show')
|
||||
img(src="/images/pages/play/level/modal/reward_icon_gems.png")
|
||||
.reward-text= animate ? 'x0' : '+'+rewards.gems
|
||||
|
||||
if rewards.heroes
|
||||
for hero in rewards.heroes
|
||||
- var hero = thangTypes[hero];
|
||||
.reward-panel
|
||||
.reward-image-container(class=animate?'':'show')
|
||||
img(src=hero.getPortraitURL())
|
||||
.reward-text= hero.get('name')
|
||||
|
||||
if rewards.items
|
||||
for item in rewards.items
|
||||
- var item = thangTypes[item];
|
||||
.reward-panel
|
||||
.reward-image-container(class=animate?'':'show')
|
||||
img(src=item.getPortraitURL())
|
||||
.reward-text= item.get('name')
|
||||
|
||||
|
||||
block modal-footer-content
|
||||
| footer
|
||||
div#totals.pull-left
|
||||
span.spr Experience Gained:
|
||||
span#xp-total +0
|
||||
br
|
||||
span.spr Gems Gained:
|
||||
span#gem-total +0
|
||||
|
||||
button.btn.btn-warning.hide#saving-progress-label(disabled, data-i18n="play_level.victory_saving_progress") Saving Progress
|
||||
a.btn.btn-success.world-map-button.hide#continue-button(href="/play-hero", data-dismiss="modal", data-i18n="play_level.victory_play_continue") Continue
|
||||
|
|
|
@ -206,10 +206,6 @@ module.exports = class PlayLevelView extends RootView
|
|||
@initVolume()
|
||||
@listenTo(@session, 'change:multiplayer', @onMultiplayerChanged)
|
||||
|
||||
# testing
|
||||
# modal = new HeroVictoryModal({session: @session, level: @level})
|
||||
# @openModalView(modal)
|
||||
|
||||
@originalSessionState = $.extend(true, {}, @session.get('state'))
|
||||
@register()
|
||||
@controlBar.setBus(@bus)
|
||||
|
@ -459,9 +455,8 @@ module.exports = class PlayLevelView extends RootView
|
|||
|
||||
showVictory: ->
|
||||
options = {level: @level, supermodel: @supermodel, session: @session}
|
||||
# ModalClass = if @level.get('type', true) is 'hero' then HeroVictoryModal else VictoryModal
|
||||
# victoryModal = new ModalClass(options)
|
||||
victoryModal = new VictoryModal(options)
|
||||
ModalClass = if @level.get('type', true) is 'hero' then HeroVictoryModal else VictoryModal
|
||||
victoryModal = new ModalClass(options)
|
||||
@openModalView(victoryModal)
|
||||
if me.get('anonymous')
|
||||
window.nextLevelURL = @getNextLevelURL() # Signup will go here on completion instead of reloading.
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
ModalView = require 'views/kinds/ModalView'
|
||||
template = require 'templates/play/level/modal/hero-victory-modal'
|
||||
Achievement = require 'models/Achievement'
|
||||
EarnedAchievement = require 'models/EarnedAchievement'
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
LocalMongo = require 'lib/LocalMongo'
|
||||
utils = require 'lib/utils'
|
||||
ThangType = require 'models/ThangType'
|
||||
|
||||
module.exports = class UnnamedView extends ModalView
|
||||
module.exports = class HeroVictoryModal extends ModalView
|
||||
id: 'hero-victory-modal'
|
||||
template: template
|
||||
closeButton: false
|
||||
|
||||
constructor: (options) ->
|
||||
super(options)
|
||||
|
@ -21,27 +23,123 @@ module.exports = class UnnamedView extends ModalView
|
|||
@thangTypes = {}
|
||||
@achievements = @supermodel.loadCollection(achievements, 'achievements').model
|
||||
@listenToOnce @achievements, 'sync', @onAchievementsLoaded
|
||||
@readyToContinue = false
|
||||
|
||||
onAchievementsLoaded: ->
|
||||
thangTypeOriginals = []
|
||||
achievementIDs = []
|
||||
for achievement in @achievements.models
|
||||
rewards = achievement.get('rewards')
|
||||
console.log 'rewards', rewards
|
||||
thangTypeOriginals.push rewards.heroes or []
|
||||
thangTypeOriginals.push rewards.items or []
|
||||
achievement.completed = LocalMongo.matchesQuery(@session.attributes, achievement.get('query'))
|
||||
achievementIDs.push(achievement.id) if achievement.completed
|
||||
|
||||
thangTypeOriginals = _.uniq _.flatten thangTypeOriginals
|
||||
console.log 'thang type originals?', thangTypeOriginals
|
||||
for thangTypeOriginal in thangTypeOriginals
|
||||
thangType = new ThangType()
|
||||
thangType.url = "/db/thang.type/#{thangTypeOriginal}/version"
|
||||
thangType.project = ['original', 'rasterIcon']
|
||||
thangType.project = ['original', 'rasterIcon', 'name']
|
||||
@thangTypes[thangTypeOriginal] = @supermodel.loadModel(thangType, 'thang').model
|
||||
|
||||
if achievementIDs.length
|
||||
url = "/db/earned_achievement?view=get-by-achievement-ids&achievementIDs=#{achievementIDs.join(',')}"
|
||||
earnedAchievements = new CocoCollection([], {
|
||||
url: url
|
||||
model: EarnedAchievement
|
||||
})
|
||||
earnedAchievements.sizeShouldBe = achievementIDs.length
|
||||
res = @supermodel.loadCollection(earnedAchievements, 'earned_achievements')
|
||||
@earnedAchievements = res.model
|
||||
@listenTo @earnedAchievements, 'sync', ->
|
||||
if @earnedAchievements.models.length < @earnedAchievements.sizeShouldBe
|
||||
@earnedAchievements.fetch()
|
||||
else
|
||||
@listenToOnce me, 'sync', ->
|
||||
@readyToContinue = true
|
||||
@updateSavingProgressStatus()
|
||||
me.fetch() unless me.loading
|
||||
else
|
||||
@readyToContinue = true
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
c.levelName = utils.i18n @level.attributes, 'name'
|
||||
earnedAchievementMap = _.indexBy(@earnedAchievements?.models or [], (ea) -> ea.get('achievement'))
|
||||
for achievement in @achievements.models
|
||||
achievement.completed = LocalMongo.matchesQuery(@session.attributes, achievement.get('query'))
|
||||
earnedAchievement = earnedAchievementMap[achievement.id]
|
||||
if earnedAchievement
|
||||
achievement.completedAWhileAgo = new Date() - Date.parse(earnedAchievement.get('created')) > 30 * 1000
|
||||
c.achievements = @achievements.models
|
||||
|
||||
# for testing the three states
|
||||
# if c.achievements.length
|
||||
# c.achievements = [c.achievements[0].clone(), c.achievements[0].clone(), c.achievements[0].clone()]
|
||||
# for achievement, index in c.achievements
|
||||
# achievement.completed = index > 0
|
||||
# achievement.completedAWhileAgo = index > 1
|
||||
|
||||
c.thangTypes = @thangTypes
|
||||
return c
|
||||
return c
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
return unless @supermodel.finished()
|
||||
@updateSavingProgressStatus()
|
||||
complete = _.once(_.bind(@beginAnimateNumbers, @))
|
||||
@animatedPanels = $()
|
||||
panels = @$el.find('.achievement-panel')
|
||||
for panel in panels
|
||||
panel = $(panel)
|
||||
continue unless panel.data('animate')
|
||||
@animatedPanels = @animatedPanels.add(panel)
|
||||
panel.delay(500)
|
||||
panel.queue(->
|
||||
$(this).addClass('earned') # animate out the grayscale
|
||||
$(this).dequeue()
|
||||
)
|
||||
panel.delay(500)
|
||||
panel.queue(->
|
||||
$(this).find('.reward-image-container').addClass('show')
|
||||
$(this).dequeue()
|
||||
)
|
||||
panel.delay(500)
|
||||
panel.queue(-> complete())
|
||||
@animationComplete = !@animatedPanels.length
|
||||
|
||||
beginAnimateNumbers: ->
|
||||
@numericalItemPanels = _.map(@animatedPanels.find('.numerical'), (panel) -> {
|
||||
number: $(panel).data('number')
|
||||
textEl: $(panel).find('.reward-text')
|
||||
rootEl: $(panel)
|
||||
unit: $(panel).data('number-unit')
|
||||
})
|
||||
|
||||
# TODO: mess with this more later. Doesn't seem to work, often times will pulse background red rather than animate
|
||||
# itemPanel.rootEl.find('.reward-image-container img').addClass('pulse') for itemPanel in @numericalItemPanels
|
||||
@numberAnimationStart = new Date()
|
||||
@totalXP = 0
|
||||
@totalXP += panel.number for panel in @numericalItemPanels when panel.unit is 'xp'
|
||||
@totalGems = 0
|
||||
@totalGems += panel.number for panel in @numericalItemPanels when panel.unit is 'gem'
|
||||
@gemEl = $('#gem-total')
|
||||
@XPEl = $('#xp-total')
|
||||
@numberAnimationInterval = setInterval(@tickNumberAnimation, 15 / 1000)
|
||||
|
||||
tickNumberAnimation: =>
|
||||
pct = Math.min(1, (new Date() - @numberAnimationStart) / 1500)
|
||||
panel.textEl.text('+'+parseInt(panel.number*pct)) for panel in @numericalItemPanels
|
||||
@XPEl.text('+'+parseInt(@totalXP * pct))
|
||||
@gemEl.text('+'+parseInt(@totalGems * pct))
|
||||
@endAnimateNumbers() if pct is 1
|
||||
|
||||
endAnimateNumbers: ->
|
||||
@$el.find('.pulse').removeClass('pulse')
|
||||
clearInterval(@numberAnimationInterval)
|
||||
@animationComplete = true
|
||||
@updateSavingProgressStatus()
|
||||
|
||||
updateSavingProgressStatus: ->
|
||||
return unless @animationComplete
|
||||
@$el.find('#saving-progress-label').toggleClass('hide', @readyToContinue)
|
||||
@$el.find('#continue-button').toggleClass('hide', !@readyToContinue)
|
|
@ -10,6 +10,7 @@ module.exports = class Problem
|
|||
@buildAnnotation()
|
||||
@buildAlertView() if withAlert
|
||||
@buildMarkerRange() if isCast
|
||||
Backbone.Mediator.publish("problem:problem-created", line:@annotation.row, text: @annotation.text) if application.isIPadApp
|
||||
@saveUserCodeProblem() if isCast
|
||||
|
||||
destroy: ->
|
||||
|
|
|
@ -640,6 +640,7 @@ module.exports = class SpellView extends CocoView
|
|||
@aceSession.removeGutterDecoration start.row, @decoratedGutter[start.row] if @decoratedGutter[start.row] isnt ''
|
||||
@aceSession.addGutterDecoration start.row, clazz
|
||||
@decoratedGutter[start.row] = clazz
|
||||
Backbone.Mediator.publish("tome:highlight-line", line:start.row) if application.isIPadApp
|
||||
@debugView?.setVariableStates {} unless gotVariableStates
|
||||
null
|
||||
|
||||
|
|
37
scripts/mongodb/queries/all-code-for-users.js
Normal file
37
scripts/mongodb/queries/all-code-for-users.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Finds all sessions for given usernames and grab all the code by level.
|
||||
|
||||
var usernames = ['Nick'];
|
||||
usernames.sort(Math.random);
|
||||
var users = db.users.find({name: {$in: usernames}, anonymous: false}).toArray();
|
||||
var userIDs = [];
|
||||
for (var userIndex = 0; userIndex < users.length; ++userIndex) {
|
||||
userIDs.push('' + users[userIndex]._id);
|
||||
}
|
||||
var sessions = db.level.sessions.find({creator: {$in: userIDs}}).toArray();
|
||||
var levels = {};
|
||||
for (var i = 0; i < sessions.length; ++i) {
|
||||
var session = sessions[i];
|
||||
if (!session) continue;
|
||||
if (!session.code || !session.levelName) continue;
|
||||
var userCode = {};
|
||||
if (session.teamSpells && session.team) {
|
||||
for (spellName in session.teamSpells[session.team]) {
|
||||
var spellNameElements = spellName.split('/');
|
||||
var thangName = spellNameElements[0];
|
||||
var spellName = spellNameElements[1];
|
||||
if (thangName && spellName && session.code[thangName] && session.code[thangName][spellName]) {
|
||||
userCode[thangName] = session.code[thangName] || {};
|
||||
userCode[thangName][spellName] = session.code[thangName][spellName];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
userCode = session.code;
|
||||
var anonymizedUsername = 'user' + userIDs.indexOf(session.creator);
|
||||
var codeLanguage = session.codeLanguage || 'javascript';
|
||||
levels[codeLanguage] = levels[codeLanguage] || {};
|
||||
levels[codeLanguage][session.levelName] = levels[codeLanguage][session.levelName] || {};
|
||||
levels[codeLanguage][session.levelName][anonymizedUsername] = userCode;
|
||||
}
|
||||
levels;
|
||||
|
|
@ -14,6 +14,26 @@ class EarnedAchievementHandler extends Handler
|
|||
hasAccess: (req) ->
|
||||
req.method is 'GET' # or req.user.isAdmin()
|
||||
|
||||
get: (req, res) ->
|
||||
return @getByAchievementIDs(req, res) if req.query.view is 'get-by-achievement-ids'
|
||||
super(arguments...)
|
||||
|
||||
getByAchievementIDs: (req, res) ->
|
||||
query = { user: req.user._id+''}
|
||||
ids = req.query.achievementIDs
|
||||
if (not ids) or (ids.length is 0)
|
||||
return @sendBadInputError(res, 'For a get-by-achievement-ids request, need to provide ids.')
|
||||
|
||||
ids = ids.split(',')
|
||||
for id in ids
|
||||
if not Handler.isID(id)
|
||||
return @sendBadInputError(res, "Not a MongoDB ObjectId: #{id}")
|
||||
|
||||
query.achievement = {$in: ids}
|
||||
EarnedAchievement.find query, (err, earnedAchievements) ->
|
||||
return @sendDatabaseError(res, err) if err
|
||||
res.send(earnedAchievements)
|
||||
|
||||
recalculate: (req, res) ->
|
||||
onSuccess = (data) => log.debug 'Finished recalculating achievements'
|
||||
if 'achievements' of req.body # Support both slugs and IDs separated by commas
|
||||
|
|
Loading…
Reference in a new issue