mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-25 08:38:09 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
837cc94f38
42 changed files with 144 additions and 438 deletions
|
@ -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 = @
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
## 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']
|
||||
|
@ -25,17 +25,18 @@ module.exports = class God
|
|||
@createWorld()
|
||||
|
||||
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) ->
|
||||
|
@ -91,8 +92,11 @@ module.exports = class God
|
|||
Backbone.Mediator.publish('god:new-world-created', world: @world, firstWorld: @firstWorld, errorCount: errorCount, goalStates: @latestGoalStates)
|
||||
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 = {}
|
||||
|
@ -171,6 +175,7 @@ class Angel
|
|||
@busy = true
|
||||
@started = new Date()
|
||||
@purgatoryTimer = setInterval @testWorker, @infiniteLoopIntervalDuration
|
||||
@spawnWorker() unless @worker
|
||||
@
|
||||
|
||||
free: ->
|
||||
|
@ -178,6 +183,8 @@ class Angel
|
|||
@started = null
|
||||
clearInterval @purgatoryTimer
|
||||
@purgatoryTimer = null
|
||||
@worker?.terminate()
|
||||
@worker = null
|
||||
@
|
||||
|
||||
abort: ->
|
||||
|
@ -185,9 +192,9 @@ class Angel
|
|||
@worker.postMessage {func: 'abort'}
|
||||
|
||||
terminate: =>
|
||||
@worker.terminate()
|
||||
@worker?.terminate()
|
||||
@worker = null
|
||||
return if @dead
|
||||
@spawnWorker()
|
||||
@free()
|
||||
@god.angelAborted @
|
||||
|
||||
|
@ -219,7 +226,9 @@ class Angel
|
|||
clearTimeout @abortTimeout
|
||||
@free()
|
||||
@god.angelAborted @
|
||||
@worker.terminate() if @god.dead
|
||||
if @god.dead
|
||||
@worker.terminate()
|
||||
@worker = null
|
||||
when 'reportIn'
|
||||
clearTimeout @condemnTimeout
|
||||
else
|
||||
|
|
|
@ -116,7 +116,8 @@ module.exports = class LevelLoader extends CocoClass
|
|||
# World init
|
||||
|
||||
initWorld: ->
|
||||
return if @world
|
||||
return if @initialized
|
||||
@initialized = true
|
||||
@world = new World @level.get('name')
|
||||
serializedLevel = @level.serialize(@supermodel)
|
||||
@world.loadFromLevel serializedLevel, false
|
||||
|
@ -203,9 +204,9 @@ module.exports = class LevelLoader extends CocoClass
|
|||
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: ->
|
||||
@world = null # don't hold onto garbage
|
||||
@supermodel.off 'loaded-one', @onSupermodelLoadedOne
|
||||
super()
|
||||
|
|
|
@ -26,6 +26,7 @@ module.exports = class Tracker
|
|||
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}"
|
||||
|
|
|
@ -83,7 +83,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
toString: -> "<CocoSprite: #{@thang?.id}>"
|
||||
|
||||
buildSpriteSheet: ->
|
||||
options = @thang?.getSpriteOptions?() or {}
|
||||
options = @thang?.getSpriteOptions?() or @options
|
||||
options.colorConfig = @options.colorConfig if @options.colorConfig
|
||||
options.async = false
|
||||
@thangType.getSpriteSheet options
|
||||
|
@ -131,6 +131,8 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
|
||||
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
|
||||
|
@ -142,6 +144,14 @@ 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()
|
||||
|
||||
update: ->
|
||||
# Gets the sprite to reflect what the current state of the thangs and surface are
|
||||
return if @stillLoading
|
||||
|
@ -193,6 +203,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
|||
@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
|
||||
|
|
|
@ -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,7 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
'level-suppress-selection-sounds': 'onSuppressSelectionSounds'
|
||||
'level-lock-select': 'onSetLockSelect'
|
||||
'level:restarted': 'onLevelRestarted'
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
|
||||
constructor: (@options) ->
|
||||
super()
|
||||
|
@ -87,7 +88,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
|
||||
|
@ -195,6 +196,9 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
|
||||
spriteFor: (thangID) -> @sprites[thangID]
|
||||
|
||||
onNewWorld: (e) ->
|
||||
@world = @options.world = e.world
|
||||
|
||||
# Selection
|
||||
|
||||
onSuppressSelectionSounds: (e) -> @suppressSelectionSounds = e.suppress
|
||||
|
|
|
@ -90,6 +90,7 @@ module.exports = class GoalManager extends CocoClass
|
|||
# passes the word along
|
||||
onNewWorldCreated: (e) =>
|
||||
@updateGoalStates(e.goalStates) if e.goalStates?
|
||||
@world = e.world
|
||||
|
||||
updateGoalStates: (newGoalStates) ->
|
||||
for goalID, goalState of newGoalStates
|
||||
|
|
|
@ -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
|
||||
|
@ -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)."
|
||||
|
@ -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]
|
||||
|
|
|
@ -27,7 +27,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
admin: "Admin"
|
||||
home: "Accueil"
|
||||
contribute: "Contribuer"
|
||||
legal: "Mention légales"
|
||||
legal: "Mentions légales"
|
||||
about: "À propos"
|
||||
contact: "Contact"
|
||||
twitter_follow: "Suivre"
|
||||
|
@ -37,7 +37,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
save_version_title: "Enregistrer une nouvelle version"
|
||||
new_major_version: "Nouvelle version majeure"
|
||||
cla_prefix: "Pour enregistrer vos modifications vous devez d'abord accepter notre"
|
||||
cla_url: "Licence de Copyright"
|
||||
cla_url: "Copyright"
|
||||
cla_suffix: "."
|
||||
cla_agree: "J'accepte"
|
||||
|
||||
|
@ -54,7 +54,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
signup:
|
||||
create_account_title: "Créer un compte pour sauvegarder votre progression"
|
||||
description: "C'est gratuit. Simplement quelques informations et vous pourrez commencer :"
|
||||
email_announcements: "Recevoir les annonces par courriel"
|
||||
email_announcements: "Recevoir les annonces par email"
|
||||
coppa: "13+ ou hors É-U"
|
||||
coppa_why: "(Pourquoi?)"
|
||||
creating: "Création du compte en cours..."
|
||||
|
@ -62,7 +62,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
log_in: "se connecter avec votre mot de passe"
|
||||
|
||||
home:
|
||||
slogan: "Apprenez à coder en JavaScript en jouant"
|
||||
slogan: "Apprenez à coder en JavaScript tout en jouant"
|
||||
no_ie: "CodeCombat ne fonctionnera pas sous Internet Explorer 9 ou moins. Désolé !"
|
||||
no_mobile: "CodeCombat n'a pas été créé pour les plateformes mobiles donc il est possible qu'il ne fonctionne pas correctement ! "
|
||||
play: "Jouer"
|
||||
|
@ -77,16 +77,16 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
campaign_dev: "Niveaux aléatoires plus difficiles"
|
||||
campaign_dev_description: "... dans lesquels vous apprendrez à utiliser l'interface en faisant quelque chose d'un petit peu plus dur."
|
||||
campaign_multiplayer: "Campagne multi-joueurs"
|
||||
campaign_multiplayer_description: "... dans laquelle vous codez en face à face contre d'autre joueurs."
|
||||
campaign_multiplayer_description: "... dans laquelle vous coderez en face à face contre d'autre joueurs."
|
||||
campaign_player_created: "Niveaux créés par les joueurs"
|
||||
campaign_player_created_description: "... Dans laquelle vous serz confrontés à la créativité des votres.<a href=\"/contribute#artisan\">Artisan Wizards</a>."
|
||||
campaign_player_created_description: "... Dans laquelle vous serez confrontés à la créativité des votres.<a href=\"/contribute#artisan\">Artisan Wizards</a>."
|
||||
level_difficulty: "Difficulté: "
|
||||
|
||||
contact:
|
||||
contact_us: "Contacter CodeCombat"
|
||||
welcome: "Ravi d'avoir de vos nouvelles! Utilisez ce formulaire pour nous envoyer un mail."
|
||||
contribute_prefix: "Si vous voulez contribuer, consultez notre "
|
||||
contribute_page: "page des contributions"
|
||||
contribute_page: "page de contributions"
|
||||
contribute_suffix: "!"
|
||||
forum_prefix: "Pour tout sujet d'ordre publique, merci d'utiliser "
|
||||
forum_page: "notre forum"
|
||||
|
@ -99,10 +99,10 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
pitch_body: "Nous développons CodeCombat en Anglais, mais nous avons déjà des joueurs de partout dans le monde. Beaucoup d'entre eux veulent jouer en Français mais ne parlent pas l'anglais, donc si vous parlez aussi bien l'anglais que le français, aidez-nous en devenant traducteur et aidez à traduire aussi bien le site que tous les niveaux en français."
|
||||
missing_translations: "Jusqu'à ce que nous ayons tout traduit en français, vous verrez de l'anglais quand le français ne sera pas disponible."
|
||||
learn_more: "Apprenez en plus sur les Traducteurs"
|
||||
subscribe_as_diplomat: "Souscrire en tant que traducteur"
|
||||
subscribe_as_diplomat: "S'inscrire en tant que traducteur"
|
||||
|
||||
wizard_settings:
|
||||
title: "Paramètres du Wizard"
|
||||
title: "Paramètres du Magicien"
|
||||
customize_avatar: "Personnaliser votre avatar"
|
||||
|
||||
account_settings:
|
||||
|
@ -126,7 +126,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
email_announcements_description: "Recevoir des mails sur les dernières actualités et sur le développement de CodeCombat."
|
||||
contributor_emails: "Emails des contributeurs"
|
||||
contribute_prefix: "Nous recherchons des personnes pour se joindre à notre groupe! Consultez la "
|
||||
contribute_page: "page de contribution"
|
||||
contribute_page: "page de contributions"
|
||||
contribute_suffix: " pour en savoir plus."
|
||||
email_toggle: "Tout basculer"
|
||||
error_saving: "Probleme d'enregistrement"
|
||||
|
@ -190,7 +190,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
tome_select_spell: "Choisissez un sort"
|
||||
tome_select_a_thang: "Sélectionnez une unité pour"
|
||||
tome_available_spells: "Sorts diponibles"
|
||||
hud_continue: "Continuer (appuie sur shift-espace)"
|
||||
hud_continue: "Continuer (appuie sur shift ou espace)"
|
||||
# spell_saved: "Spell Saved"
|
||||
|
||||
admin:
|
||||
|
@ -205,13 +205,13 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
|
||||
editor:
|
||||
main_title: "Éditeurs CodeCombat"
|
||||
main_description: "Crée tes propres niveaux, campagnes, unités et contenu éducatif. Nous vous fournissons tous les outils dont vous avez besoin!"
|
||||
main_description: "Créé tes propres niveaux, campagnes, unités et contenus éducatifs. Nous vous fournissons tous les outils dont vous avez besoin!"
|
||||
article_title: "Éditeur d'article"
|
||||
article_description: "Écris des articles qui donnent aux joueurs un aperçu des concepts de programmation qui peuvent être utilisés dans différents niveaux et campagnes."
|
||||
thang_title: "Éditeur Thang"
|
||||
thang_description: "Crée des unités, définis leur comportement de base, graphisme et son. Pour l'instant ne supporte que l'importation d'images vectorielles exportées de Flash."
|
||||
thang_description: "Créé des unités, définis leur comportement de base, graphisme et son. Pour l'instant cette fonctionnalité ne supporte que l'importation d'images vectorielles exportées depuis Flash."
|
||||
level_title: "Éditeur de niveau"
|
||||
level_description: "Inclut les outils de script, le téléversement de vidéos, et l'élaboration de logiques personnalisées pour créer toutes sortes de niveaux. Tout ce que nous utilisons nous-mêmes!"
|
||||
level_description: "Inclut les outils de script, l'upload de vidéos, et l'élaboration de logiques personnalisées pour créer toutes sortes de niveaux. Tout ce que nous utilisons nous-mêmes!"
|
||||
security_notice: "Plusieurs caractéristiques majeures de cet éditeur ne sont pas encore activées par défaut. Quand nous aurons amélioré la sécurité de ces éléments, ils seront rendus disponibles. Si vous voulez les utiliser plus rapidement, "
|
||||
contact_us: "contactez nous!"
|
||||
hipchat_prefix: "Vous pouvez aussi nous trouver dans notre "
|
||||
|
@ -253,7 +253,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
# version_history_for: "Version History for: "
|
||||
results: "Résultats"
|
||||
description: "Description"
|
||||
email: "Courriel"
|
||||
email: "Email"
|
||||
message: "Message"
|
||||
|
||||
about:
|
||||
|
@ -262,13 +262,13 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
who_description_prefix: "ont lancé CodeCombat ensemble en 2013. Nous avons aussi créé "
|
||||
who_description_suffix: "en 2008, l'améliorant jusqu'au rang de première application web et iOS pour apprendre à écrire les caractères chinois et japonais."
|
||||
who_description_ending: "Maintenant nous apprenons aux gens à coder."
|
||||
why_paragraph_1: "En développant Skritter, George ne savait pas programmer et était frustré de ne pas pouvoir implémenter ses idées. Ensuite, il essaya d'apprendre, mais les cours n'étaient pas assez rapides. Son colocataire, voulant se requalifier et arrêter d'apprendre, essaya Codecademy, mais \"s'ennuya.\" Chaque semaine un nouvel ami commença Codecademy, puis abandonna. Nous nous sommes rendus compte que nous avions résolu le même problème avec Skritter: les gens apprennant grâce à des cours lents et intensifs quand nous avons besoin d'expérience rapide et intensive. Nous savons comment remédier à ça."
|
||||
why_paragraph_1: "En développant Skritter, George ne savait pas programmer et était frustré de ne pas pouvoir implémenter ses idées. Ensuite, il essaya d'apprendre, mais les cours n'étaient pas assez rapides. Son colocataire, voulant se requalifier et arrêter d'apprendre, essaya Codecademy, mais \"s'ennuya.\" Chaque semaine un nouvel ami commençait Codecademy, puis abandonnait. Nous nous sommes rendus compte que nous avions résolu le même problème avec Skritter: les gens apprennant grâce à des cours lents et intensifs quand nous avons besoin d'expérience rapide et intensive. Nous savons comment remédier à ça."
|
||||
why_paragraph_2: "Besoin d'apprendre à développer? Vous n'avez pas besoin de cours. Vous avez besoin d'écrire beaucoup de code et de vous amuser en le faisant."
|
||||
why_paragraph_3_prefix: "C'est ce dont il s'agit en programmation. Ca doit être amusant. Pas amusant comme"
|
||||
why_paragraph_3_prefix: "C'est ce dont il s'agit en programmation. Ça doit être amusant. Pas amusant comme"
|
||||
why_paragraph_3_italic: "génial un badge"
|
||||
why_paragraph_3_center: "mais amusant comme"
|
||||
why_paragraph_3_italic_caps: "NAN MAMAN JE DOIS FINIR MON NIVEAU!"
|
||||
why_paragraph_3_suffix: "C'est pourquoi CodeCombat est un jeu multijoueur, pas un cours avec une leçon jouée. Nous n'arrêterons pas avant que vous ne puissiez plus arrêter--mais cette fois, c'est une bonne chose."
|
||||
why_paragraph_3_suffix: "C'est pourquoi CodeCombat est un jeu multijoueur, pas un cours avec une leçon jouée. Nous n'arrêterons pas avant que vous ne puissiez plus arrêter — mais cette fois, c'est une bonne chose."
|
||||
why_paragraph_4: "Si vous devez devenir accro à un jeu, accrochez-vous à celui-ci et devenez un des mages de l'âge de la technologie."
|
||||
why_ending: "Et oh, c'est gratuit. "
|
||||
why_ending_url: "Commence ton apprentissage maintenant!"
|
||||
|
@ -279,7 +279,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
michael_description: "Programmeur, administrateur réseau, et l'enfant prodige du premier cycle, Michael est la personne qui maintient nos serveurs en ligne."
|
||||
|
||||
legal:
|
||||
page_title: "Judiciaire"
|
||||
page_title: "Légal"
|
||||
opensource_intro: "CodeCombat est complètement gratuit et open source."
|
||||
opensource_description_prefix: "Regardez "
|
||||
github_url: "notre GitHub"
|
||||
|
@ -301,16 +301,16 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
recruitment_title: "Recrutement"
|
||||
recruitment_description_prefix: "Ici chez CodeCombat, vous allez devenir un magicien puissant, pas seulement dans le jeu, mais aussi dans la vie réelle."
|
||||
url_hire_programmers: "Personne ne peut recruter des développeurs aussi vite"
|
||||
recruitment_description_suffix: "donc une fois que vous aurez aiguisé votre savoir-faire et si vous l'acceptez, nous montrerons vos meilleurs codes aux milliers d'employeurs qui attendent une chance de vous recruter. Ils nous payent un peu pour ensuite vous payer"
|
||||
recruitment_description_suffix: "donc une fois que vous aurez aiguisé votre savoir-faire et si vous l'acceptez, nous montrerons vos meilleurs bouts de code aux milliers d'employeurs qui attendent une chance de vous recruter. Ils nous payent un peu pour ensuite vous payer"
|
||||
recruitment_description_italic: "beaucoup"
|
||||
recruitment_description_ending: "le site reste gratuit et tout le monde est content. C'est le plan."
|
||||
recruitment_description_ending: "le site reste gratuit et tout le monde est content. C'est le but."
|
||||
copyrights_title: "Copyrights et Licences"
|
||||
contributor_title: "Contributor License Agreement"
|
||||
contributor_description_prefix: "Toute contribution, sur le site et sur le répertoire GitHub, est sujette à nos"
|
||||
cla_url: "CLA"
|
||||
contributor_description_suffix: "auxquels vous devez agréer avant de contribuer."
|
||||
contributor_description_suffix: "auxquelles vous devez vous soumettre avant de contribuer."
|
||||
code_title: "Code - MIT"
|
||||
code_description_prefix: "Tout code possédé CodeCombat ou hébergé sur codecombat.com, sur le répertoire GitHub ou dans la base de donnée de codecombat.com, est sous la licence"
|
||||
code_description_prefix: "Tout code siglé CodeCombat ou hébergé sur codecombat.com, sur le répertoire GitHub ou dans la base de données de codecombat.com, est sous la licence"
|
||||
mit_license_url: "MIT"
|
||||
code_description_suffix: "Cela inclut le code dans Systèmes et Composants qui est rendu disponible par CodeCombat dans le but de créer des niveaux."
|
||||
art_title: "Art/Musique - Creative Commons "
|
||||
|
@ -323,7 +323,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
art_sprites: "les sprites"
|
||||
art_other: "tout le reste du contenu non-code qui est rendu accessible lors de la création de niveaux."
|
||||
art_access: "Pour l'instant il n'y a aucun système universel et facile pour rassembler ces ressources. En général, accédez y par les URL comme le fait le site, contactez-nous pour de l'aide, ou aidez-nous à agrandir le site pour rendre ces ressources plus facilement accessibles."
|
||||
art_paragraph_1: "Pour l'attribution, s'il vous plait, nommez et liez codecombat.com près de la source utilisée ou dans un endroit approprié. Par exemple:"
|
||||
art_paragraph_1: "Pour l'attribution, s'il vous plait, nommez et référencez codecombat.com près de la source utilisée ou dans un endroit approprié. Par exemple:"
|
||||
use_list_1: "Si utilisé dans un film ou un autre jeu, incluez codecombat.com dans le générique."
|
||||
use_list_2: "Si utilisé sur un site web, incluez un lien près de l'utilisation, par exemple sous une image, ou sur une page d'attribution générale où vous pourrez aussi mentionner les autres travaux en Creative Commons et les logiciels open source utilisés sur votre site. Quelque chose qui fait clairement référence à CodeCombat, comme un article de blog mentionnant CodeCombat, n'a pas besoin d'attribution séparée."
|
||||
art_paragraph_2: "Si le contenu utilisé n'est pas créé par CodeCombat mais par un autre utilisateur de codecombat.com, attribuez le à cet utilisateur, et suivez les recommandations fournies dans la ressource de la description s'il y en a."
|
||||
|
@ -334,10 +334,10 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
rights_description: "la description"
|
||||
rights_writings: "l'écriture"
|
||||
rights_media: "les médias (sons, musiques) et tous les autres contenus créatifs créés spécialement pour ce niveau et non rendus généralement accessibles en créant des niveaux."
|
||||
rights_clarification: "Pour clarifier, tout ce qui est rendu accessible dans l'éditeur de niveaux dans le but de créer des niveaux est sous licence CC, tandis que le contenu créé avec l'éditeur de niveaux ou téléversé dans le but de créer un niveau ne l'est pas."
|
||||
rights_clarification: "Pour clarifier, tout ce qui est rendu accessible dans l'éditeur de niveaux dans le but de créer des niveaux est sous licence CC, tandis que le contenu créé avec l'éditeur de niveaux ou uploadé dans le but de créer un niveau ne l'est pas."
|
||||
nutshell_title: "En un mot"
|
||||
nutshell_description: "Chaque ressource que nous fournissons dans l'éditeur de niveau est libre d'utilisation pour créer des niveaux. Mais nous nous réservons le droit de restreindre la distribution des niveaux créés (qui sont créés sur codecombat.com) ils peuvent donc devenir payants dans le futur, si c'est ce qui doit arriver."
|
||||
canonical: "La version de ce document est la version définitive et canonique. En cas d'irrégularités dans les traductions, le document anglais l'emporte."
|
||||
canonical: "La version de ce document est la version définitive et canonique. En cas d'irrégularité dans les traductions, le document anglais fait foi."
|
||||
|
||||
contribute:
|
||||
page_title: "Contribution"
|
||||
|
@ -381,38 +381,38 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
adventurer_introduction: "Soyons clair à propos de votre rôle : vous êtes le tank. Vous allez subir beaucoup de dommages. Nous avons besoin de gens pour essayer les nouveaux niveaux et aider à identifier comment améliorer les choses. La douleur sera énorme; faire de bons jeux est une longue tâche et personne n'y arrive du premier coup. Si vous pouvez résister et avez un gros score de constitution, alors cette classe est faite pour vous."
|
||||
adventurer_attribute_1: "Une soif d'apprendre. Vous voulez apprendre à développer et nous voulons vous apprendre. Vous allez toutefois faire la plupart de l'apprentissage."
|
||||
adventurer_attribute_2: "Charismatique. Soyez doux mais exprimez-vous sur ce qui a besoin d'être amélioré, et faites des propositions sur comment l'améliorer."
|
||||
adventurer_join_pref: "Soit être ensemble avec (ou recruter!) un artisan et travailler avec lui, ou cocher la case ci-dessous pour recevoir un email quand il y aura de nouveaux niveaux à tester. Nous parlons aussi des niveaux à réviser sur notre réseau"
|
||||
adventurer_join_pref: "Soit faire équipe avec (ou recruter!) un artisan et travailler avec lui, ou cocher la case ci-dessous pour recevoir un email quand il y aura de nouveaux niveaux à tester. Nous parlons aussi des niveaux à réviser sur notre réseau"
|
||||
adventurer_forum_url: "notre forum"
|
||||
adventurer_join_suf: "si vous préférez être avertis ainsi, inscrivez-vous ici!"
|
||||
more_about_adventurer: "En apprendre plus sur devenir un Aventurier brave"
|
||||
more_about_adventurer: "En apprendre plus sur devenir un brave Aventurier"
|
||||
adventurer_subscribe_desc: "Recevoir un email lorsqu'il y a de nouveaux niveaux à tester."
|
||||
scribe_introduction_pref: "CodeCombat n'est pas seulement un paquet de niveaux. Il contiendra aussi des ressources pour la connaissance, un wiki des concepts de programmation que les niveaux pourront illustrer. Dans ce but, chaque Artisan pourra, au lieu d'avoir à décrire en détail ce qu'est un opérateur de comparaison, seulement lier son niveau à l'article qui le décrit et qui a été écrit pour aider les joueurs. Quelque chose dans le sens de ce que le "
|
||||
scribe_introduction_pref: "CodeCombat n'est pas seulement un ensemble de niveaux. Il contiendra aussi des ressources pour la connaissance, un wiki des concepts de programmation que les niveaux pourront illustrer. Dans ce but, chaque Artisan pourra, au lieu d'avoir à décrire en détail ce qu'est un opérateur de comparaison, seulement lier son niveau à l'article qui le décrit et qui a été écrit pour aider les joueurs. Quelque chose dans le sens de ce que le "
|
||||
scribe_introduction_url_mozilla: "Mozilla Developer Network"
|
||||
scribe_introduction_suf: " a développé. Si votre représentation de l'amusement est l'articulation des concepts de programmation au format Markdown, alors cette classe est pour vous."
|
||||
scribe_attribute_1: "Les compétences rédactionnelles sont quasiment la seule chose dont vous aurez besoin. Pas seulement la grammaire et l'orthographe, mais être capable de lier des idées ensembles."
|
||||
scribe_introduction_suf: " a développé. Si votre définition de l'amusement passe par le format Markdown, alors cette classe est pour vous."
|
||||
scribe_attribute_1: "Les compétences rédactionnelles sont quasiment la seule chose dont vous aurez besoin. Pas seulement la grammaire et l'orthographe, mais être également capable de lier des idées ensembles."
|
||||
contact_us_url: "Contactez-nous"
|
||||
scribe_join_description: "parlez nous un peu de vous, de votre expérience en programmation et de quels sujets vous souhaitez traiter. Nous partirons de là!"
|
||||
more_about_scribe: "En apprendre plus sur comment devenir un Scribe assidu"
|
||||
scribe_subscribe_desc: "Recevoir un email sur les annonces d'écriture d'article."
|
||||
diplomat_introduction_pref: "Si nous avons appris quelque chose du "
|
||||
diplomat_launch_url: "lancement en octobre"
|
||||
diplomat_introduction_suf: "c'est qu'il y a un intérêt considérable pour CodeCombat dans d'autres pays, particulièrement au Brésil! Nous créons une équipe de traducteurs pour changer une liste de mots en une autre pour que CodeCombat soit le plus accessible possible à travers le monde. Si vous aimez avoir des aperçus des prochains contenus et avoir les niveaux dans votre langue le plus tôt possible, alors cette classe est faite pour vous."
|
||||
diplomat_attribute_1: "Des facilités en anglais et dans la langue que vous souhaitez traduire. Pour transmettre des idées complexes, c'est important d'avoir une solide compréhension des deux!"
|
||||
diplomat_introduction_suf: "c'est qu'il y a un intérêt considérable pour CodeCombat dans d'autres pays, particulièrement au Brésil! Nous créons une équipe de traducteurs pour changer une liste de mots en une autre pour que CodeCombat soit le plus accessible possible à travers le monde. Si vous souhaitez avoir un aperçu des prochains contenus et avoir les niveaux dans votre langue le plus tôt possible, alors cette classe est faite pour vous."
|
||||
diplomat_attribute_1: "Des facilités en anglais et dans la langue que vous souhaitez traduire. Pour transmettre des idées complexes, il est important d'avoir une solide compréhension des deux!"
|
||||
diplomat_join_pref: "Nous avons commencé plusieurs traductions sur "
|
||||
diplomat_doc_url: "ce post du forum"
|
||||
diplomat_join_suf: "regardez les et ajoutez des choses à votre langue. Aussi, cochez la case ci-dessous pour rester à jour sur les nouveaux développement d'i18n!"
|
||||
more_about_diplomat: "En apprendre plus sur comment devenir un bon diplomate"
|
||||
diplomat_subscribe_desc: "Recevoir un email sur le développement i18n et les niveaux à traduire."
|
||||
ambassador_introduction: "C'est la communauté que nous avons construite, et vous en êtes les connexions. Nous avons une discussion Olark, des emails et les réseaux sociaux avec plusieurs personnes avec qui parler, et l'aide vient à la fois du jeu lui-même et grâce à lui. Si vous voulez aider les gens, prendre part à l'aventure et vous amusez, avec un bon feeling de CodeCombat et de là où nous allons, alors cette classe est faite pour vous."
|
||||
ambassador_attribute_1: "Compétences en communication. Être capable d'identifier les problèmes que les joueurs ont et les aider à les résoudre. Mais aussi nous garder informés de ce que les joueurs disent, ce qu'ils aiment et n'aiment pas et d'autres choses de ce type!"
|
||||
ambassador_introduction: "C'est la communauté que nous construisons, et vous en êtes les connexions. Nous avons des discussions via le chat Olark, emails et les réseaux sociaux avec plusieurs personnes, et l'aide vient à la fois du jeu lui-même et grâce à lui. Si vous voulez aider les gens, prendre part à l'aventure et vous amuser, avec un bon feeling de CodeCombat et ce vers quoi nous allons, alors cette classe est faite pour vous."
|
||||
ambassador_attribute_1: "Compétences en communication. Être capable d'identifier les problèmes que les joueurs ont et les aider à les résoudre. Mais aussi nous tenir informés de ce que les joueurs disent, ce qu'ils aiment et n'aiment pas et d'autres choses de ce genre!"
|
||||
ambassador_join_desc: "parlez-nous un peu de vous, de ce que vous avez fait et ce qui vous aimeriez faire. Nous partirons de ça!"
|
||||
ambassador_join_note_strong: "Note"
|
||||
ambassador_join_note_desc: "Une de nos priorités est de développer un jeu multijoueur où les joueurs qui ont du mal à réussir un niveau peuvent demander de l'aide à un joueur de plus haut niveau. Ce sera un bon moyen pour que les ambassadeurs fassent leur travail. Nous vous garderons en ligne!"
|
||||
more_about_ambassador: "En apprendre plus sur comment devenir un Ambassadeur serviable"
|
||||
more_about_ambassador: "En apprendre plus sur comment devenir un serviable Ambassadeur"
|
||||
ambassador_subscribe_desc: "Recevoir un email sur les mises à jour de l'aide et les développements multijoueur."
|
||||
counselor_introduction_1: "Avez-vous une expérience de vie? Ou toute autre expérience qui peut nous aider à décider comment diriger CodeCombat? De tous ces rôles, ce sera probablement celui qui prend le moins de temps, mais vous ferez la différence. Nous recherchons des sages, particulièrement dans les domaines de : l'apprentissage, le développement de jeux, la gestion de projets open source, le recrutement technique, l'entreprenariat, ou la conception."
|
||||
counselor_introduction_2: "Ou vraiment toute chose en rapport avec le développement de CodeCombat. Si vous avez des connaissances et que vous voulez les partager pour aider le projet à avancer, alors cette classe est faite pour vous."
|
||||
counselor_attribute_1: "De l'expérience, dans un des domaines ci-dessus ou quelque chose que vous pensez utile."
|
||||
counselor_introduction_1: "Avez-vous de l'expérience dans la vie? Ou toute autre expérience qui peut nous aider à décider comment diriger CodeCombat? De tous ces rôles, ce sera probablement celui qui prend le moins de temps, mais vous ferez la différence. Nous recherchons des sages, particulièrement dans les domaines de : l'apprentissage, le développement de jeux, la gestion de projets open source, le recrutement technique, l'entreprenariat, ou la conception."
|
||||
counselor_introduction_2: "Ou vraiment toutes choses en rapport avec le développement de CodeCombat. Si vous avez des connaissances et que vous voulez les partager pour aider le projet à avancer, alors cette classe est faite pour vous."
|
||||
counselor_attribute_1: "De l'expérience, dans un des domaines ci-dessus ou quelque chose que vous pensez être utile."
|
||||
counselor_attribute_2: "Un peu de temps libre!"
|
||||
counselor_join_desc: "parlez-nous un peu de vous, de ce que vous avez fait et ce que vous aimeriez faire. Nous vous mettrons dans notre liste de contacts et ferons appel à vous quand nous aurons besoin de conseils (pas trop souvent)."
|
||||
more_about_counselor: "En apprendre plus sur devenir un précieux Conseiller"
|
||||
|
@ -421,8 +421,8 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
powerful_archmages: "Nos puissants Archimages :"
|
||||
creative_artisans: "Nos Artisans créatifs :"
|
||||
brave_adventurers: "Nos braves Aventuriers :"
|
||||
translating_diplomats: "Nos Diplomates traduteurs :"
|
||||
helpful_ambassadors: "Nos Ambassadeurs serviables :"
|
||||
translating_diplomats: "Nos Diplomates traducteurs :"
|
||||
helpful_ambassadors: "Nos serviables Ambassadeurs :"
|
||||
|
||||
classes:
|
||||
archmage_title: "Archimage"
|
||||
|
@ -430,12 +430,13 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
|
|||
artisan_title: "Artisan"
|
||||
artisan_title_description: "(Créateur de niveau)"
|
||||
adventurer_title: "Aventurier"
|
||||
adventurer_title_description: "(Testeur de jouabilité)"
|
||||
adventurer_title_description: "(Testeur de niveau)"
|
||||
scribe_title: "Scribe"
|
||||
scribe_title_description: "(Éditeur d'article)"
|
||||
scribe_title_description: "(Rédacteur d'articles)"
|
||||
diplomat_title: "Diplomate"
|
||||
diplomat_title_description: "(Traducteur)"
|
||||
ambassador_title: "Ambassadeur"
|
||||
ambassador_title_description: "(Aide)"
|
||||
counselor_title: "Conseiller"
|
||||
counselor_title_description: "(Expert/Professeur)"
|
||||
|
||||
|
|
|
@ -57,14 +57,14 @@
|
|||
box-sizing: border-box
|
||||
|
||||
|
||||
#thang-components-edit-view
|
||||
position: absolute
|
||||
top: 45px
|
||||
bottom: 0
|
||||
|
||||
.treema-root
|
||||
background-color: white
|
||||
border-radius: 4px
|
||||
#thang-components-edit-view
|
||||
position: absolute
|
||||
top: 130px
|
||||
bottom: 0
|
||||
|
||||
.treema-root
|
||||
background-color: white
|
||||
border-radius: 4px
|
||||
|
||||
#spritesheets
|
||||
border: 1px solid green
|
||||
|
|
|
@ -79,7 +79,7 @@ block content
|
|||
li Greek - Stergios
|
||||
li Latin American Spanish - Jesús Ruppel, Matthew Burt, Mariano Luzza
|
||||
li Spain Spanish - Matthew Burt, DanielRodriguezRivero, Anon
|
||||
li French - Xeonarno, Elfisen, Armaldio, MartinDelille, pstweb, veritable, jaybi, Anon
|
||||
li French - Xeonarno, Elfisen, Armaldio, MartinDelille, pstweb, veritable, jaybi, xavismeh, Anon
|
||||
li Hungarian - ferpeter, csuvsaregal, atlantisguru, Anon
|
||||
li Japanese - g1itch, kengos
|
||||
li Chinese - Adam23, spacepope
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
span(data-i18n="play_level.multiplayer_hint") Click the link to select all, then press ⌘-C or Ctrl-C to copy the link.
|
||||
|
||||
p(data-i18n="play_level.multiplayer_coming_soon") More multiplayer features to come!
|
||||
|
||||
if playableTeams.length > 1
|
||||
#multiplayer-team-selection
|
||||
for team in playableTeams
|
||||
label(for="multiplayer_team_"+team)= team
|
||||
input(id="multiplayer_team_"+team, type="radio", name="multiplayer", value=team)
|
||||
|
||||
.modal-footer
|
||||
a(href='#', data-dismiss="modal", aria-hidden="true", data-i18n="modal.close").btn.btn-primary Close
|
||||
|
|
|
@ -52,7 +52,6 @@ module.exports = class EditorLevelView extends View
|
|||
@files.fetch()
|
||||
|
||||
onAllLoaded: =>
|
||||
@originalLevelAttributes = _.cloneDeep @level.attributes
|
||||
@level.unset('nextLevel') if _.isString(@level.get('nextLevel'))
|
||||
@initWorld()
|
||||
@startsLoading = false
|
||||
|
@ -93,7 +92,7 @@ module.exports = class EditorLevelView extends View
|
|||
@childWindow.focus()
|
||||
|
||||
startCommittingLevel: (e) ->
|
||||
levelSaveView = new LevelSaveView level: @level, supermodel: @supermodel, originalLevelAttributes: @originalLevelAttributes
|
||||
levelSaveView = new LevelSaveView level: @level, supermodel: @supermodel
|
||||
@openModalView levelSaveView
|
||||
Backbone.Mediator.publish 'level:view-switched', e
|
||||
|
||||
|
|
|
@ -16,13 +16,11 @@ module.exports = class LevelSaveView extends SaveVersionModal
|
|||
constructor: (options) ->
|
||||
super options
|
||||
@level = options.level
|
||||
@originalLevelAttributes = options.originalLevelAttributes
|
||||
@levelNeedsSave = not _.isEqual @level.attributes, @originalLevelAttributes
|
||||
|
||||
|
||||
getRenderData: (context={}) =>
|
||||
context = super(context)
|
||||
context.level = @level
|
||||
context.levelNeedsSave = @levelNeedsSave
|
||||
context.levelNeedsSave = @level.hasLocalChanges()
|
||||
context.modifiedComponents = _.filter @supermodel.getModels(LevelComponent), @shouldSaveEntity
|
||||
context.modifiedSystems = _.filter @supermodel.getModels(LevelSystem), @shouldSaveEntity
|
||||
context
|
||||
|
|
|
@ -31,6 +31,7 @@ module.exports = class ControlBarView extends View
|
|||
@worldName = options.worldName
|
||||
@session = options.session
|
||||
@level = options.level
|
||||
@playableTeams = options.playableTeams
|
||||
super options
|
||||
|
||||
setBus: (@bus) ->
|
||||
|
@ -55,7 +56,7 @@ module.exports = class ControlBarView extends View
|
|||
@openModalView(new DocsModal(options))
|
||||
|
||||
showMultiplayerModal: ->
|
||||
@openModalView(new MultiplayerModal(session: @session))
|
||||
@openModalView(new MultiplayerModal(session: @session, playableTeams: @playableTeams))
|
||||
|
||||
showRestartModal: ->
|
||||
@openModalView(new ReloadModal())
|
||||
|
|
|
@ -301,6 +301,7 @@ module.exports = class HUDView extends View
|
|||
[newFrame, newAction] = [hist.frame, hist.name]
|
||||
continue if newAction is lastAction
|
||||
if newFrame > lastFrame
|
||||
# TODO: don't push it if it didn't exist until then
|
||||
(@timespans[lastAction] ?= []).push [lastFrame * dt, newFrame * dt]
|
||||
[lastFrame, lastAction] = [newFrame, newAction]
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
View = require 'views/kinds/ModalView'
|
||||
template = require 'templates/play/level/modal/multiplayer'
|
||||
{me} = require('lib/auth')
|
||||
|
||||
module.exports = class MultiplayerModal extends View
|
||||
id: 'level-multiplayer-modal'
|
||||
|
@ -13,6 +14,7 @@ module.exports = class MultiplayerModal extends View
|
|||
super(options)
|
||||
@session = options.session
|
||||
@session.on 'change:multiplayer', @updateLinkSection
|
||||
@playableTeams = options.playableTeams
|
||||
|
||||
getRenderData: ->
|
||||
c = super()
|
||||
|
@ -20,13 +22,17 @@ module.exports = class MultiplayerModal extends View
|
|||
'?session=' +
|
||||
@session.id)
|
||||
c.multiplayer = @session.get('multiplayer')
|
||||
c.playableTeams = @playableTeams
|
||||
c
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
@updateLinkSection()
|
||||
@$el.find('#multiplayer-team-selection input')
|
||||
.prop('checked', -> $(@).val() is me.team)
|
||||
.bind('change', -> Backbone.Mediator.publish 'level:set-team', team: $(@).val())
|
||||
|
||||
onClickLink: (e) =>
|
||||
onClickLink: (e) ->
|
||||
e.target.select()
|
||||
|
||||
updateLinkSection: =>
|
||||
|
|
|
@ -28,7 +28,10 @@ module.exports = class Spell
|
|||
@tabView.render()
|
||||
|
||||
addThang: (thang) ->
|
||||
@thangs[thang.id] ?= {thang: thang, aether: @createAether(thang), castAether: null}
|
||||
if @thangs[thang.id]
|
||||
@thangs[thang.id].thang = thang
|
||||
else
|
||||
@thangs[thang.id] = {thang: thang, aether: @createAether(thang), castAether: null}
|
||||
|
||||
removeThangID: (thangID) ->
|
||||
delete @thangs[thangID]
|
||||
|
|
|
@ -134,3 +134,7 @@ module.exports = class ThangListEntryView extends View
|
|||
return unless currentThang = e.world.thangMap[@thang.id]
|
||||
@$el.toggle Boolean(currentThang.exists)
|
||||
@$el.toggleClass 'dead', currentThang.health <= 0 if currentThang.exists
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@avatar.destroy()
|
||||
|
|
|
@ -65,6 +65,7 @@ module.exports = class TomeView extends View
|
|||
else
|
||||
@cast()
|
||||
console.warn "Warning: There are no Programmable Thangs in this level, which makes it unplayable."
|
||||
delete @options.thangs
|
||||
|
||||
onNewWorld: (e) ->
|
||||
thangs = _.filter e.world.thangs, 'isSelectable'
|
||||
|
@ -95,7 +96,7 @@ module.exports = class TomeView extends View
|
|||
@spells[spellKey].addThang thang for spellKey in spellKeys
|
||||
else
|
||||
delete @thangSpells[thangID]
|
||||
@spells[spellKey].removeThangID thangID for spellKey in spellKeys
|
||||
spell.removeThangID thangID for spell in @spells
|
||||
null
|
||||
|
||||
onSpellLoaded: (e) ->
|
||||
|
|
|
@ -50,13 +50,14 @@ module.exports = class PlayLevelView extends View
|
|||
'level-focus-dom': 'onFocusDom'
|
||||
'level-disable-controls': 'onDisableControls'
|
||||
'level-enable-controls': 'onEnableControls'
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
'god:infinite-loop': 'onInfiniteLoop'
|
||||
'bus:connected': 'onBusConnected'
|
||||
'level-reload-from-data': 'onLevelReloadFromData'
|
||||
'play-next-level': 'onPlayNextLevel'
|
||||
'edit-wizard-settings': 'showWizardSettingsModal'
|
||||
'surface:world-set-up': 'onSurfaceSetUpNewWorld'
|
||||
'level:session-will-save': 'onSessionWillSave'
|
||||
'level:set-team': 'setTeam'
|
||||
|
||||
events:
|
||||
'click #level-done-button': 'onDonePressed'
|
||||
|
@ -102,7 +103,6 @@ module.exports = class PlayLevelView extends View
|
|||
|
||||
load: ->
|
||||
@levelLoader = new LevelLoader(@levelID, @supermodel, @sessionID)
|
||||
@levelLoader.once 'ready-to-init-world', @onReadyToInitWorld
|
||||
@levelLoader.once 'loaded-all', @onLevelLoaderLoaded
|
||||
|
||||
getRenderData: ->
|
||||
|
@ -120,8 +120,10 @@ module.exports = class PlayLevelView extends View
|
|||
@session = @levelLoader.session
|
||||
@level = @levelLoader.level
|
||||
@world = @levelLoader.world
|
||||
@levelLoader.destroy()
|
||||
@levelLoader = null
|
||||
@loadingScreen.destroy()
|
||||
@setTeam @world.teamForPlayer 1 # We don't know which player we are; this will go away--temp TODO
|
||||
@setTeam @world.teamForPlayer _.size @session.get 'players' # TODO: players aren't initialized yet?
|
||||
@initSurface()
|
||||
@initGod()
|
||||
@initGoalManager()
|
||||
|
@ -155,7 +157,7 @@ module.exports = class PlayLevelView extends View
|
|||
@insertSubView new HUDView {}
|
||||
@insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session
|
||||
worldName = @level.get('i18n')?[me.lang()]?.name ? @level.get('name')
|
||||
@controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel}
|
||||
@controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel, playableTeams: @world.playableTeams}
|
||||
#Backbone.Mediator.publish('level-set-debug', debug: true) if me.displayName() is 'Nick!'
|
||||
|
||||
afterInsert: ->
|
||||
|
@ -206,6 +208,9 @@ module.exports = class PlayLevelView extends View
|
|||
$('#level-done-button', @$el).hide()
|
||||
window.tracker?.trackEvent 'Confirmed Restart', level: @world.name, label: @world.name
|
||||
|
||||
onNewWorld: (e) ->
|
||||
@world = e.world
|
||||
|
||||
onInfiniteLoop: (e) ->
|
||||
return unless e.firstWorld
|
||||
@openModalView new InfiniteLoopModal()
|
||||
|
@ -355,13 +360,6 @@ module.exports = class PlayLevelView extends View
|
|||
@bus.setSession(@session)
|
||||
@bus.connect() if @session.get('multiplayer')
|
||||
|
||||
onBusConnected: ->
|
||||
# Need to set this team stuff before the Tome loads... let's think about this with Scott.
|
||||
#@setTeam @world.teamForPlayer(@bus.countPlayers()) unless me.team
|
||||
#$('#multiplayer-team-selection').toggle(@world.playableTeams.length > 1)
|
||||
# .find('input').prop('checked', -> $(@).val() is me.team)
|
||||
# .bind('change', @setTeam)
|
||||
|
||||
onSessionWillSave: (e) ->
|
||||
# Something interesting has happened, so (at a lower frequency), we'll save a screenshot.
|
||||
@saveScreenshot e.session
|
||||
|
@ -372,13 +370,14 @@ module.exports = class PlayLevelView extends View
|
|||
session.save {screenshot: screenshot}, {patch: true}
|
||||
|
||||
setTeam: (team) ->
|
||||
team = $(@).val() unless _.isString team
|
||||
team = team?.team unless _.isString team
|
||||
team ?= 'humans'
|
||||
me.team = team
|
||||
Backbone.Mediator.publish 'level:team-set', team: team
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@levelLoader.destroy()
|
||||
@levelLoader?.destroy()
|
||||
@surface?.destroy()
|
||||
@god?.destroy()
|
||||
@goalManager?.destroy()
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
mongoose = require('mongoose')
|
||||
plugins = require('../plugins/plugins')
|
||||
|
||||
NestedLevelSchema = new mongoose.Schema(
|
||||
name: String
|
||||
description: String
|
||||
thumbnail: Buffer
|
||||
original: {type: mongoose.Schema.ObjectId, ref: 'level'}
|
||||
majorVersion: Number
|
||||
)
|
||||
|
||||
CampaignSchema = new mongoose.Schema(
|
||||
description: String
|
||||
levels: [NestedLevelSchema]
|
||||
)
|
||||
|
||||
CampaignSchema.plugin(plugins.NamedPlugin)
|
||||
CampaignSchema.plugin(plugins.PermissionsPlugin)
|
||||
CampaignSchema.plugin(plugins.SearchablePlugin, {searchable: ['name', 'description']})
|
||||
|
||||
module.exports = Campaign = mongoose.model('campaign', CampaignSchema)
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
mongoose = require('mongoose')
|
||||
|
||||
LevelStatusSchema = new mongoose.Schema(
|
||||
lastPlayed: Date
|
||||
victorious: Boolean
|
||||
original: {type: mongoose.Schema.ObjectId, ref: 'level'}
|
||||
majorVersion: Number
|
||||
)
|
||||
|
||||
CampaignStatusSchema = new mongoose.Schema(
|
||||
user: {type: mongoose.Schema.ObjectId, ref: 'User'}
|
||||
campaign: {type: mongoose.Schema.ObjectId, ref: 'campaign'}
|
||||
levelStatuses: [LevelStatusSchema]
|
||||
)
|
||||
CampaignStatusSchema.index {user: 1, campaign: 1}, {unique: true}
|
||||
|
||||
module.exports = CampaignStatus = mongoose.model('campaign.status', CampaignStatusSchema)
|
|
@ -1,10 +0,0 @@
|
|||
Campaign = require('./Campaign')
|
||||
Handler = require('../commons/Handler')
|
||||
|
||||
CampaignHandler = class CampaignHandler extends Handler
|
||||
modelClass: Campaign
|
||||
editableProperties: ['name', 'description', 'levels']
|
||||
|
||||
|
||||
|
||||
module.exports = new CampaignHandler()
|
|
@ -1,13 +0,0 @@
|
|||
CampaignStatus = require('./CampaignStatus')
|
||||
Handler = require('../commons/Handler')
|
||||
|
||||
CampaignStatusHandler = class CampaignStatusHandler extends Handler
|
||||
modelClass: CampaignStatus
|
||||
editableProperties: ['levelStatuses']
|
||||
postEditableProperties: ['campaign', 'user']
|
||||
|
||||
post: (req, res) ->
|
||||
req.body.user = req.user._id
|
||||
super(req, res)
|
||||
|
||||
module.exports = new CampaignStatusHandler()
|
|
@ -1,12 +1,8 @@
|
|||
|
||||
module.exports.handlers =
|
||||
'article': 'articles/article_handler'
|
||||
'campaign': 'campaigns/campaign_handler'
|
||||
'campaign_status': 'campaigns/campaign_status_handler'
|
||||
'file': 'files/file_handler'
|
||||
'level': 'levels/level_handler'
|
||||
'level_component': 'levels/components/level_component_handler'
|
||||
'level_draft': 'levels/drafts/level_draft_handler'
|
||||
'level_feedback': 'levels/feedbacks/level_feedback_handler'
|
||||
'level_session': 'levels/sessions/level_session_handler'
|
||||
'level_system': 'levels/systems/level_system_handler'
|
||||
|
@ -16,7 +12,6 @@ module.exports.handlers =
|
|||
module.exports.schemas =
|
||||
'article': 'articles/article_schema'
|
||||
'common': 'commons/schemas'
|
||||
#'file': 'files/file_schema'
|
||||
'i18n': 'commons/i18n_schema'
|
||||
'level': 'levels/level_schema'
|
||||
'level_component': 'levels/components/level_component_schema'
|
||||
|
@ -38,4 +33,4 @@ module.exports.routes =
|
|||
'routes/languages'
|
||||
'routes/mail'
|
||||
'routes/sprites'
|
||||
]
|
||||
]
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
mongoose = require('mongoose')
|
||||
plugins = require('../plugins/plugins')
|
||||
|
||||
FileSchema = new mongoose.Schema()
|
||||
|
||||
FileSchema.plugin(plugins.SearchablePlugin, {searchable: ['metadata.description', 'metadata.name']})
|
||||
|
||||
module.exports = mongoose.model('media.files', FileSchema)
|
|
@ -1,13 +0,0 @@
|
|||
File = require('./File')
|
||||
Handler = require('../commons/Handler')
|
||||
|
||||
FileHandler = class FileHandler extends Handler
|
||||
modelClass: File
|
||||
editableProperties: ['metadata']
|
||||
|
||||
hasAccess: (req) ->
|
||||
req.method is 'GET'
|
||||
|
||||
# TODO: once we're building the clients, need special GET handler, search handler
|
||||
|
||||
module.exports = new FileHandler()
|
|
@ -1,25 +0,0 @@
|
|||
c = require '../commons/schemas'
|
||||
|
||||
FileSchema = c.baseSchema()
|
||||
|
||||
_.extend(FileSchema.properties, {
|
||||
filename: c.shortStringProp()
|
||||
contentType: c.shortStringProp()
|
||||
length: { type: 'number' }
|
||||
chunkSize: { type: 'number', format: 'hidden' }
|
||||
uploadDate: { type: 'string' }
|
||||
aliases: {}
|
||||
metadata:
|
||||
type: 'object'
|
||||
additionalProperties: false
|
||||
name: c.shortStringArrayProp()
|
||||
description: { type: 'string' }
|
||||
createdFor: { type: 'array', items: {}}
|
||||
path: { type: 'string' }
|
||||
creator: { type: 'string' }
|
||||
})
|
||||
|
||||
c.extendSearchableProperties(FileSchema.properties.metadata)
|
||||
FileSchema.format = 'file'
|
||||
|
||||
module.exports = FileSchema
|
|
@ -1,9 +0,0 @@
|
|||
mongoose = require('mongoose')
|
||||
Level = require('../Level')
|
||||
|
||||
LevelDraftSchema = new mongoose.Schema(
|
||||
user: {type: mongoose.Schema.ObjectId, ref: 'User'}
|
||||
level: {}
|
||||
)
|
||||
|
||||
module.exports = LevelDraft = mongoose.model('level.draft', LevelDraftSchema)
|
|
@ -1,13 +0,0 @@
|
|||
LevelDraft = require('./LevelDraft')
|
||||
Handler = require('../../commons/Handler')
|
||||
|
||||
LevelDraftHandler = class LevelDraftHandler extends Handler
|
||||
modelClass: LevelDraft
|
||||
editableProperties: ['level']
|
||||
postEditableProperties: ['user']
|
||||
|
||||
post: (req, res) ->
|
||||
req.body.user = req.user._id
|
||||
super(req, res)
|
||||
|
||||
module.exports = new LevelDraftHandler()
|
|
@ -30,6 +30,7 @@ GoalSchema = c.object {title: "Goal", description: "A goal that the player can a
|
|||
worldEndsAfter: {title: 'World Ends After', description: "When included, ends the world this many seconds after this goal succeeds or fails.", type: 'number', minimum: 0, exclusiveMinimum: true, maximum: 300, default: 3}
|
||||
howMany: {title: "How Many", description: "When included, require only this many of the listed goal targets instead of all of them.", type: 'integer', minimum: 1}
|
||||
hiddenGoal: {title: "Hidden", description: "Hidden goals don't show up in the goals area for the player until they're failed. (Usually they're obvious, like 'don't die'.)", 'type': 'boolean', default: false}
|
||||
team: c.shortString(title: 'Team', description: 'Name of the team this goal is for, if it is not for all of the playable teams.')
|
||||
killThangs: c.array {title: "Kill Thangs", description: "A list of Thang IDs the player should kill, or team names.", uniqueItems: true, minItems: 1, "default": ["ogres"]}, thang
|
||||
saveThangs: c.array {title: "Save Thangs", description: "A list of Thang IDs the player should save, or team names", uniqueItems: true, minItems: 1, "default": ["humans"]}, thang
|
||||
getToLocations: c.object {title: "Get To Locations", description: "TODO: explain", required: ["who", "targets"]},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
describe 'editor/level/thangs_tab', ->
|
||||
describe 'editor/level/systems_tab', ->
|
||||
SystemsTabView = require 'views/editor/level/systems_tab_view'
|
||||
|
||||
it 'does stuff', ->
|
||||
|
|
|
@ -10,12 +10,9 @@ path = require('path')
|
|||
|
||||
models_path = [
|
||||
'../../server/articles/Article'
|
||||
'../../server/campaigns/Campaign'
|
||||
'../../server/campaigns/CampaignStatus'
|
||||
'../../server/levels/Level'
|
||||
'../../server/levels/components/LevelComponent'
|
||||
'../../server/levels/systems/LevelSystem'
|
||||
'../../server/levels/drafts/LevelDraft'
|
||||
'../../server/levels/sessions/LevelSession'
|
||||
'../../server/levels/thangs/LevelThangType'
|
||||
'../../server/users/User'
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
require '../common'
|
||||
|
||||
describe '/db/campaign', ->
|
||||
request = require 'request'
|
||||
it 'clears the db first', (done) ->
|
||||
clearModels [User, Campaign], (err) ->
|
||||
throw err if err
|
||||
done()
|
||||
|
||||
campaign = {name: 'A', description:'B'}
|
||||
url = getURL('/db/campaign')
|
||||
campaigns = {}
|
||||
|
||||
it 'allows making Campaigns.', (done) ->
|
||||
loginJoe (user) ->
|
||||
campaign.permissions = [access: 'owner', target: user._id]
|
||||
request.post {uri:url, json:campaign}, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(body.permissions).toBeDefined()
|
||||
campaigns[0] = body
|
||||
done()
|
||||
|
||||
it 'does not allow other users access', (done) ->
|
||||
loginSam ->
|
||||
request.get {uri:url+'/'+campaigns[0]._id}, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(403)
|
||||
done()
|
||||
|
||||
it 'allows editing permissions.', (done) ->
|
||||
loginJoe ->
|
||||
campaigns[0].permissions.push(access: 'read', target: 'public')
|
||||
request.put {uri:url, json:campaigns[0]}, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(body.permissions.length).toBe(2)
|
||||
campaigns[0] = body
|
||||
done()
|
||||
|
||||
it 'allows anyone to access it through public permissions', (done) ->
|
||||
loginSam ->
|
||||
request.get {uri:url+'/'+campaigns[0]._id}, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(200)
|
||||
done()
|
|
@ -1,21 +0,0 @@
|
|||
require '../common'
|
||||
|
||||
describe '/db/campaign_status', ->
|
||||
request = require 'request'
|
||||
it 'clears the db first', (done) ->
|
||||
clearModels [Campaign, CampaignStatus], (err) ->
|
||||
throw err if err
|
||||
done()
|
||||
|
||||
user = new User(name:'sup')
|
||||
campaign = new Campaign(name:'Project Vengeance.', permissions: simplePermissions)
|
||||
stat = {campaign: campaign._id, user: user._id}
|
||||
url = getURL('/db/campaign_status')
|
||||
|
||||
it 'can make a CampaignStatus, and ignores the user property given.', (done) ->
|
||||
loginJoe (joe) ->
|
||||
request.post {uri:url, json:stat}, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(body.user).toBe(joe._id.toString())
|
||||
expect(body.user).not.toBe(user._id.toString())
|
||||
done()
|
|
@ -1,23 +0,0 @@
|
|||
require '../common'
|
||||
|
||||
describe '/db/campaign_draft', ->
|
||||
|
||||
draft = {
|
||||
level: {}
|
||||
user: 'yoyoyo'
|
||||
}
|
||||
|
||||
request = require 'request'
|
||||
it 'clears the db first', (done) ->
|
||||
clearModels [LevelDraft], (err) ->
|
||||
throw err if err
|
||||
done()
|
||||
|
||||
url = getURL('/db/level_draft')
|
||||
|
||||
it 'can make a LevelDraft, and ignores the user property given.', (done) ->
|
||||
loginJoe (joe) ->
|
||||
request.post {uri:url, json:draft}, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(body.user).toBe(joe._id.toString())
|
||||
done()
|
|
@ -1,34 +0,0 @@
|
|||
require '../../common'
|
||||
|
||||
describe 'CampaignStatus', ->
|
||||
|
||||
user = new User(name:'sup')
|
||||
campaign = new Campaign(name:'Project Vengeance.', permissions: simplePermissions)
|
||||
stat = new CampaignStatus(user: user._id, campaign: campaign._id)
|
||||
|
||||
it 'clears things first', (done) ->
|
||||
clearModels [User, Campaign, CampaignStatus], (err) ->
|
||||
expect(err).toBeNull()
|
||||
done()
|
||||
|
||||
it 'can be saved', (done) ->
|
||||
saveModels [user, campaign, stat], (err) ->
|
||||
expect(err).toBeNull()
|
||||
done()
|
||||
|
||||
it 'can populate', (done) ->
|
||||
CampaignStatus
|
||||
.findOne({_id:stat._id})
|
||||
.populate('user')
|
||||
.populate('campaign')
|
||||
.exec (err, c) ->
|
||||
expect(err).toBe(null)
|
||||
expect(c.user.get('name')).toBeDefined()
|
||||
expect(c.campaign.get('name')).toBeDefined()
|
||||
done()
|
||||
|
||||
it 'rejects duplicates', (done) ->
|
||||
stat2 = new CampaignStatus(user: user._id, campaign: campaign._id)
|
||||
stat2.save (err) ->
|
||||
expect(err).not.toBe(null)
|
||||
done()
|
|
@ -1,31 +0,0 @@
|
|||
require '../../common'
|
||||
|
||||
describe 'LevelDraft', ->
|
||||
|
||||
level = new Level(
|
||||
name: "King's Peak Redux"
|
||||
description: 'Climb a mountain.'
|
||||
permissions: simplePermissions
|
||||
original: new ObjectId()
|
||||
)
|
||||
|
||||
it 'clears things first', (done) ->
|
||||
clearModels [Level, LevelDraft], (err) ->
|
||||
expect(err).toBeNull()
|
||||
done()
|
||||
|
||||
it 'saves', (done) ->
|
||||
level.save (err) ->
|
||||
throw err if err
|
||||
|
||||
draft = new LevelDraft(
|
||||
user: new ObjectId()
|
||||
level: level
|
||||
)
|
||||
|
||||
draft.save (err) ->
|
||||
throw err if err
|
||||
|
||||
LevelDraft.findOne {_id:draft._id}, (err, fetched) ->
|
||||
expect(fetched.level.original).toBeDefined()
|
||||
done()
|
|
@ -1,26 +0,0 @@
|
|||
require '../../common'
|
||||
|
||||
describe 'Campaign', ->
|
||||
|
||||
raw =
|
||||
name:'Battlefield 1942'
|
||||
description:'Vacation all over the world!'
|
||||
levels: []
|
||||
permissions:[
|
||||
target:'not_the_public'
|
||||
access:'owner'
|
||||
]
|
||||
|
||||
campaign = new Campaign(raw)
|
||||
|
||||
it 'clears things first', (done) ->
|
||||
Campaign.remove {}, (err) ->
|
||||
expect(err).toBeNull()
|
||||
done()
|
||||
|
||||
it 'can be saved', (done) ->
|
||||
campaign.save (err) ->
|
||||
expect(err).toBeNull()
|
||||
done()
|
||||
|
||||
|
|
@ -328,27 +328,3 @@ describe 'SearchablePlugin', ->
|
|||
target:'not_the_public'
|
||||
access:'owner'
|
||||
]
|
||||
|
||||
campaign = new Campaign(raw)
|
||||
|
||||
it 'clears things first', (done) ->
|
||||
Campaign.remove {}, (err) ->
|
||||
expect(err).toBeNull()
|
||||
done()
|
||||
|
||||
it 'hides private entities from public searches', (done) ->
|
||||
campaign.save (err) ->
|
||||
throw err if err
|
||||
done()
|
||||
|
||||
Campaign.textSearch 'battlefield', {filter:{ index: true}}, (err, results) ->
|
||||
expect(results.results.length).toBe(0)
|
||||
done()
|
||||
|
||||
it 'allows private searches for owning users', (done) ->
|
||||
campaign.save (err) ->
|
||||
throw err if err
|
||||
|
||||
Campaign.textSearch 'battlefield', {filter: { index: 'not_the_public' }}, (err, results) ->
|
||||
expect(results.results.length).toBeGreaterThan(0)
|
||||
done()
|
||||
|
|
Loading…
Reference in a new issue