From 03e39c3f5cef92c337a5cb5a67b18d14fe5bb40e Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Fri, 15 Aug 2014 11:15:48 -0700 Subject: [PATCH 01/16] Fixed Level denormalize test. --- test/app/models/Level.spec.coffee | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/app/models/Level.spec.coffee b/test/app/models/Level.spec.coffee index db90afd8d..3db7cabe1 100644 --- a/test/app/models/Level.spec.coffee +++ b/test/app/models/Level.spec.coffee @@ -17,6 +17,7 @@ describe 'Level', -> ] } ] + type: 'hero' }) thangType = new ThangType({ @@ -28,17 +29,17 @@ describe 'Level', -> {"original": "d", "majorVersion": 0, "config": {i: 1}} ] }) - + supermodel = new SuperModel() supermodel.registerModel(thangType) - + result = level.denormalize(supermodel) tharinThangComponents = result.thangs[0].components - + it 'adds default configs to thangs without any config', -> aComp = _.find tharinThangComponents, {original:'a'} expect(_.isEqual(aComp.config, {i:1})).toBeTruthy() - + it 'leaves alone configs for components the level thang has but the thang type does not', -> bComp = _.find tharinThangComponents, {original:'b'} expect(_.isEqual(bComp.config, {i:2})).toBeTruthy() @@ -46,7 +47,8 @@ describe 'Level', -> it 'merges configs where both the level thang and thang type have one, giving priority to the level thang', -> cComp = _.find tharinThangComponents, {original:'c'} expect(_.isEqual(cComp.config, {i: 1, ii: 2, nest: {iii: 3, iv: 4}})).toBeTruthy() - + it 'adds components from the thang type that do not exist in the level thang', -> dComp = _.find tharinThangComponents, {original:'d'} - expect(_.isEqual(dComp.config, {i: 1})).toBeTruthy() \ No newline at end of file + expect(dComp).toBeTruthy() + expect(_.isEqual(dComp?.config, {i: 1})).toBeTruthy() From 5f20e6f05e97f7c059793daf503df8ca9af6f830 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Fri, 15 Aug 2014 12:09:56 -0700 Subject: [PATCH 02/16] Thangs get inserted into hero levels without any Components for easy defaulting. Working on moving Hero Placeholder ThangType swapping from LevelLoader to Level, but it's not there yet. --- app/lib/LevelLoader.coffee | 2 ++ app/models/Level.coffee | 3 +++ app/views/editor/level/thangs/ThangsTabView.coffee | 12 +++++++++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index 7c7ead9ea..c4c3103ab 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -153,6 +153,7 @@ module.exports = class LevelLoader extends CocoClass @worldNecessities = @worldNecessities.concat worldNecessities populateHero: -> + return return if @inLevelEditor return unless @level.get('type') is 'hero' and hero = _.find @level.get('thangs'), id: 'Hero Placeholder' heroConfig = @session.get('heroConfig') @@ -218,6 +219,7 @@ module.exports = class LevelLoader extends CocoClass for thangTypeName in thangsToLoad thangType = nameModelMap[thangTypeName] + console.log 'found ThangType', thangType, 'for', thangTypeName, 'of nameModelMap', nameModelMap unless thangType continue if thangType.isFullyLoaded() thangType.fetch() thangType = @supermodel.loadModel(thangType, 'thang').model diff --git a/app/models/Level.coffee b/app/models/Level.coffee index 2d4ff0ff3..ad3458692 100644 --- a/app/models/Level.coffee +++ b/app/models/Level.coffee @@ -46,6 +46,9 @@ module.exports = class Level extends CocoModel for thangComponent in levelThang.components ? [] placeholders[thangComponent.original] = thangComponent levelThang.components = [] + heroThangType = session?.get('heroConfig')?.thangType + console.log "got thang type", heroThangType + levelThang.thangType = heroThangType if heroThangType configs = {} for thangComponent in levelThang.components diff --git a/app/views/editor/level/thangs/ThangsTabView.coffee b/app/views/editor/level/thangs/ThangsTabView.coffee index 2d1ddf0de..0c2b030d8 100644 --- a/app/views/editor/level/thangs/ThangsTabView.coffee +++ b/app/views/editor/level/thangs/ThangsTabView.coffee @@ -311,10 +311,14 @@ module.exports = class ThangsTabView extends CocoView else @addThangSprite = null - createEssentialComponents: -> + createEssentialComponents: (defaultComponents) -> + physicalConfig = {pos: {x: 10, y: 10, z: 1}} + if physicalOriginal = _.find(defaultComponents ? [], original: componentOriginals['physics.Physical']) + physicalConfig.pos.z = physicalOriginal.config.pos.z # Get the z right + console.log physicalOriginal, defaultComponents, componentOriginals['physics.Physical'], physicalConfig [ {original: componentOriginals['existence.Exists'], majorVersion: 0, config: {}} - {original: componentOriginals['physics.Physical'], majorVersion: 0, config: {pos: {x: 10, y: 10, z: 1}, width: 2, height: 2, depth: 2, shape: 'box'}} + {original: componentOriginals['physics.Physical'], majorVersion: 0, config: physicalConfig} ] createAddThang: -> @@ -424,9 +428,11 @@ module.exports = class ThangsTabView extends CocoView if @cloneSourceThang components = _.cloneDeep @thangsTreema.get "id=#{@cloneSourceThang.id}/components" @selectAddThang null + else if @level.get('type') is 'hero' + components = [] # Load them all from default ThangType Components else components = _.cloneDeep thangType.get('components') ? [] - components = @createEssentialComponents() unless components.length + components = @createEssentialComponents(thangType.get('components')) unless components.length physical = _.find components, (c) -> c.config?.pos? physical.config.pos = x: pos.x, y: pos.y, z: physical.config.pos.z if physical thang = thangType: thangType.get('original'), id: thangID, components: components From 3b083e15f597ae86f1774b0dd56377c37cdc445a Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Fri, 15 Aug 2014 12:27:56 -0700 Subject: [PATCH 03/16] Don't require any Component default properties in hero levels, for maximum defaultability. --- .../editor/component/ThangComponentConfigView.coffee | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/views/editor/component/ThangComponentConfigView.coffee b/app/views/editor/component/ThangComponentConfigView.coffee index 39717ef6b..b27ddb177 100644 --- a/app/views/editor/component/ThangComponentConfigView.coffee +++ b/app/views/editor/component/ThangComponentConfigView.coffee @@ -37,10 +37,14 @@ module.exports = class ThangComponentConfigView extends CocoView teams = _.filter(_.pluck(thangs, 'team')) superteams = _.filter(_.pluck(thangs, 'superteam')) superteams = _.union(teams, superteams) + config = $.extend true, {}, @config + schema = $.extend true, {}, @component.get('configSchema') + if @level?.get('type') is 'hero' + schema.required = [] treemaOptions = supermodel: @supermodel - schema: @component.attributes.configSchema - data: _.cloneDeep @config + schema: schema + data: config callbacks: {change: @onConfigEdited} world: @world view: @ @@ -75,4 +79,4 @@ module.exports = class ThangComponentConfigView extends CocoView data: -> @editThangTreema.data class ComponentConfigNode extends TreemaObjectNode - nodeDescription: 'Component Property' \ No newline at end of file + nodeDescription: 'Component Property' From c52503f6824672a8612ce2c3c7c456121ff5cfaf Mon Sep 17 00:00:00 2001 From: Dominik Kundel Date: Fri, 15 Aug 2014 23:49:19 +0200 Subject: [PATCH 04/16] bump up zatanna version --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 06a1d55b4..8ac33ff3c 100644 --- a/bower.json +++ b/bower.json @@ -44,7 +44,7 @@ "bootstrap": "~3.1.1", "validated-backbone-mediator": "~0.1.3", "jquery.browser": "~0.0.6", - "zatanna": "~0.0.5", + "zatanna": "~0.0.6", "modernizr": "~2.8.3" }, "overrides": { From 89e8d523c5e0edbac75686876b93f0e46066d3c9 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 Date: Sat, 16 Aug 2014 09:35:34 +0100 Subject: [PATCH 05/16] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 122 ++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 61bf857aa..70496e7f8 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -49,9 +49,9 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: blog: "Blog" forum: "Fórum" account: "Conta" -# profile: "Profile" -# stats: "Stats" -# code: "Code" + profile: "Perfil" + stats: "Estatísticas" + code: "Código" admin: "Administrador" home: "Início" contribute: "Contribuir" @@ -212,15 +212,15 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: profile_for_suffix: "" # featured: "Featured" # not_featured: "Not Featured" -# looking_for: "Looking for:" + looking_for: "À procura de:" # last_updated: "Last updated:" # contact: "Contact" -# active: "Looking for interview offers now" -# inactive: "Not looking for offers right now" + active: "Estou à procura de ofertas de intrevistas agora" + inactive: "Não estou à procura de ofertas neste momento" # complete: "complete" next: "Seguinte" next_city: "cidade?" -# next_country: "pick your country." + next_country: "escolha o seu país." next_name: "nome?" # next_short_description: "write a short description." # next_long_description: "describe your desired position." @@ -244,9 +244,9 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # basics_job_title: "Desired Job Title" # basics_job_title_help: "What role are you looking for?" basics_city: "Cidade" -# basics_city_help: "City you want to work in (or live in now)." + basics_city_help: "Cidade na qual quer trabalhar (ou onde vive agora)." basics_country: "País" -# basics_country_help: "Country you want to work in (or live in now)." + basics_country_help: "País no qual quer trabalhar (ou onde vive agora)." # basics_visa: "US Work Status" # basics_visa_help: "Are you authorized to work in the US, or do you need visa sponsorship? (If you live in Canada or Australia, mark authorized.)" basics_looking_for: "À Procura De" @@ -295,17 +295,17 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # education_description_help: "Highlight anything about this educational experience. (140 chars; optional)" # our_notes: "CodeCombat's Notes" # remarks: "Remarks" -# projects: "Projects" -# projects_header: "Add 3 projects" + projects: "Projetos" + projects_header: "Adicione 3 projetos" # projects_header_2: "Projects (Top 3)" # projects_blurb: "Highlight your projects to amaze employers." -# project_name: "Project Name" + project_name: "Nome do Projeto" # project_name_help: "What was the project called?" -# project_description: "Description" + project_description: "Descrição" # project_description_help: "Briefly describe the project." -# project_picture: "Picture" + project_picture: "Imagem" # project_picture_help: "Upload a 230x115px or larger image showing off the project." -# project_link: "Link" + project_link: "Ligação" # project_link_help: "Link to the project." # player_code: "Player Code" @@ -325,18 +325,18 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: filter_experience: "Experiência" filter_experience_senior: "Sénior" filter_experience_junior: "Júnior" -# filter_experience_recent_grad: "Recent Grad" + filter_experience_recent_grad: "Graduado Recentemente" filter_experience_student: "Estudante Universitário" filter_results: "resultados" start_hiring: "Começar a contratar." -# reasons: "Three reasons you should hire through us:" -# everyone_looking: "Everyone here is looking for their next opportunity." -# everyone_looking_blurb: "Forget about 20% LinkedIn InMail response rates. Everyone that we list on this site wants to find their next position and will respond to your request for an introduction." -# weeding: "Sit back; we've done the weeding for you." -# weeding_blurb: "Every player that we list has been screened for technical ability. We also perform phone screens for select candidates and make notes on their profiles to save you time." -# pass_screen: "They will pass your technical screen." -# pass_screen_blurb: "Review each candidate's code before reaching out. One employer found that 5x as many of our devs passed their technical screen than hiring from Hacker News." -# make_hiring_easier: "Make my hiring easier, please." + reasons: "Três razões pelas quais deve contratar através de nós:" + everyone_looking: "Aqui todos estão à procura da próxima oportunidade deles." + everyone_looking_blurb: "Esqueça os cerca de 20% de taxas de respostta do LinkedIn InMail. Todos os que nós listamos neste sítio quer encontrar a nova posição deles e responderá ao seu pedido para uma introdução." + weeding: "Relaxe; fizemos a parte mais difícil por si." + weeding_blurb: "Cada jogador que listamos foi sujeito a um teste das habilidades técnicas. Também fazemos testes por telefone para selecionar candidatos e fazer anotações nos perfis deles para lhe poupar tempo." + pass_screen: "Eles passarão o seu teste técnico." + pass_screen_blurb: "Reveja o código de cada candidato antes de chegar a ele. Um funcionário descobriu que 5x mais programadores nossos passaram o teste técnico deles do que os contratados através do Hacker News." + make_hiring_easier: "Torne a minha contratação mais fácil, por favor." what: "O que é o CodeCombat?" what_blurb: "O CodeCombat é um jogo de programação, no navegador e multijogador. Os jogadores escrevem código para controlar as forças deles em batalha contra outros programadores. Os nossos jogadores têm experiência com todos os conceitos tecnológicos principais." cost: "Quanto é que cobramos?" @@ -430,7 +430,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: time_goto: "Ir para:" infinite_loop_try_again: "Tentar Novamente" infinite_loop_reset_level: "Reiniciar Nível" -# infinite_loop_comment_out: "Comment Out My Code" + infinite_loop_comment_out: "Comentar o Meu Código" game_menu: inventory_tab: "Inventário" @@ -499,16 +499,16 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: enter: "Enter" escape: "Esc" cast_spell: "Lançar feitiço atual." -# continue_script: "Continue past current script." -# skip_scripts: "Skip past all skippable scripts." + continue_script: "Saltar o script atual." + skip_scripts: "Saltar todos os scripts saltáveis." toggle_playback: "Alternar entre Jogar e Pausar." scrub_playback: "Andar para a frente e para trás no tempo." single_scrub_playback: "Andar para a frente e para trás no tempo um único frame." -# scrub_execution: "Scrub through current spell execution." -# toggle_debug: "Toggle debug display." -# toggle_grid: "Toggle grid overlay." -# toggle_pathfinding: "Toggle pathfinding overlay." -# beautify: "Beautify your code by standardizing its formatting." + scrub_execution: "Analisar a execução do feitiço atual." + toggle_debug: "Ativar/desativar a janela de depuração." + toggle_grid: "Ativar/desativar a sobreposição da grelha." + toggle_pathfinding: "Ativar/desativar a sobreposição do encontrador de caminho." + beautify: "Embelezar o código ao estandardizar a formatação." move_wizard: "Mover o seu Feiticeiro pelo nível." admin: @@ -525,13 +525,13 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: community: main_title: "Comunidade do CodeCombat" -# introduction: "Check out the ways you can get involved below and decide what sounds the most fun. We look forward to working with you!" -# level_editor_prefix: "Use the CodeCombat" -# level_editor_suffix: "to create and edit levels. Users have created levels for their classes, friends, hackathons, students, and siblings. If create a new level sounds intimidating you can start by forking one of ours!" -# thang_editor_prefix: "We call units within the game 'thangs'. Use the" -# thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites." -# article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the" -# article_editor_suffix: "and help CodeCombat players get the most out of their playtime." + introduction: "Confira abaixo as formas de se envolver e decida o que lhe parece melhor. Estamos ansiosos por trabalhar consigo!" + level_editor_prefix: "Use o" + level_editor_suffix: "do CodeCombat para criar e editar níveis. Os utilizadores já criaram níveis para aulas, amigos, maratonas hacker, estudantes e familiares. Se criar um nível parece intimidante, pode começar por bifurcar um dos nossos!" + thang_editor_prefix: "Chamamos 'thangs' às unidades do jogo. Use o" + thang_editor_suffix: "para modificar a arte do CodeCombat. Permita às unidades lançar projéteis, altere a direção de uma animação, altere os pontos de vida de uma unidade ou anexe as suas próprias unidades." + article_editor_prefix: "Vê um erro em alguns dos nossos documentos? Quer escrever algumas instruções para as suas criações? Confira o" + article_editor_suffix: "e ajude os jogadores do CodeCombat a obter o máximo do tempo de jogo deles." find_us: "Encontre-nos nestes sítios" contribute_to_the_project: "Contribua para o projeto" @@ -703,9 +703,9 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # art_description_prefix: "All common content is available under the" # cc_license_url: "Creative Commons Attribution 4.0 International License" # art_description_suffix: "Common content is anything made generally available by CodeCombat for the purpose of creating Levels. This includes:" -# art_music: "Music" -# art_sound: "Sound" -# art_artwork: "Artwork" + art_music: "Música" + art_sound: "Som" + art_artwork: "Arte" # art_sprites: "Sprites" # art_other: "Any and all other non-code creative works that are made available when creating Levels." # art_access: "Currently there is no universal, easy system for fetching these assets. In general, fetch them from the URLs as used by the site, contact us for assistance, or help us in extending the site to make these assets more easily accessible." @@ -713,11 +713,11 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # use_list_1: "If used in a movie or another game, include codecombat.com in the credits." # use_list_2: "If used on a website, include a link near the usage, for example underneath an image, or in a general attributions page where you might also mention other Creative Commons works and open source software being used on the site. Something that's already clearly referencing CodeCombat, such as a blog post mentioning CodeCombat, does not need some separate attribution." # art_paragraph_2: "If the content being used is created not by CodeCombat but instead by a user of codecombat.com, attribute them instead, and follow attribution directions provided in that resource's description if there are any." -# rights_title: "Rights Reserved" + rights_title: "Direitos Reservados" # rights_desc: "All rights are reserved for Levels themselves. This includes" -# rights_scripts: "Scripts" -# rights_unit: "Unit configuration" -# rights_description: "Description" + rights_scripts: "Scripts" + rights_unit: "Configuração da unidade" + rights_description: "Descrição" # rights_writings: "Writings" # rights_media: "Media (sounds, music) and any other creative content made specifically for that Level and not made generally available when creating Levels." # rights_clarification: "To clarify, anything that is made available in the Level Editor for the purpose of making levels is under CC, whereas the content created with the Level Editor or uploaded in the course of creation of Levels is not." @@ -727,22 +727,22 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: contribute: page_title: "Contribuir" - character_classes_title: "Classes de Personagens" + character_classes_title: "Classes das Personagens" introduction_desc_intro: "Temos esperanças elevadas para o CodeCombat." # introduction_desc_pref: "We want to be where programmers of all stripes come to learn and play together, introduce others to the wonderful world of coding, and reflect the best parts of the community. We can't and don't want to do that alone; what makes projects like GitHub, Stack Overflow and Linux great are the people who use them and build on them. To that end, " introduction_desc_github_url: "o CodeCombat é totalmente open source" # introduction_desc_suf: ", and we aim to provide as many ways as possible for you to take part and make this project as much yours as ours." - introduction_desc_ending: "Esperemos que se junte a nós!" + introduction_desc_ending: "Esperamos que se junte a nós!" introduction_desc_signature: "- Nick, George, Scott, Michael, Jeremy e Matt" -# alert_account_message_intro: "Hey there!" -# alert_account_message: "To subscribe for class emails, you'll need to be logged in first." + alert_account_message_intro: "Hey, você!" + alert_account_message: "Para se subscrever para receber e-mails de classes, antes precisará de iniciar sessão." # archmage_summary: "Interested in working on game graphics, user interface design, database and server organization, multiplayer networking, physics, sound, or game engine performance? Want to help build a game to help other people learn what you are good at? We have a lot to do and if you are an experienced programmer and want to develop for CodeCombat, this class is for you. We would love your help building the best programming game ever." # archmage_introduction: "One of the best parts about building games is they synthesize so many different things. Graphics, sound, real-time networking, social networking, and of course many of the more common aspects of programming, from low-level database management, and server administration to user facing design and interface building. There's a lot to do, and if you're an experienced programmer with a hankering to really dive into the nitty-gritty of CodeCombat, this class might be for you. We would love to have your help building the best programming game ever." -# class_attributes: "Class Attributes" + 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." -# how_to_join: "How To Join" + how_to_join: "Como Me Junto" # join_desc_1: "Anyone can help out! Just check out our " # join_desc_2: "to get started, and check the box below to mark yourself as a brave Archmage and get the latest news by email. Want to chat about what to do or how to get more deeply involved? " # join_desc_3: ", or find us in our " @@ -750,7 +750,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # join_url_email: "Email us" # join_url_hipchat: "public HipChat room" more_about_archmage: "Aprenda Mais Sobre Tornar-se um Arcomago" -# archmage_subscribe_desc: "Get emails on new coding opportunities and announcements." + archmage_subscribe_desc: "Receber e-mails relativos a novas oportunidades de programação e anúncios." # artisan_summary_pref: "Want to design levels and expand CodeCombat's arsenal? People are playing through our content at a pace faster than we can build! Right now, our level editor is barebone, so be wary. Making levels will be a little challenging and buggy. If you have visions of campaigns spanning for-loops to" # artisan_summary_suf: ", then this class is for you." # artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to" @@ -764,7 +764,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # artisan_join_step3: "Find us in our public HipChat room for help." # artisan_join_step4: "Post your levels on the forum for feedback." more_about_artisan: "Aprenda Mais Sobre Tornar-se um Artesão" -# artisan_subscribe_desc: "Get emails on level editor updates and announcements." + artisan_subscribe_desc: "Receber e-mails relativos a novidades do editor de níveis e anúncios." # adventurer_summary: "Let us be clear about your role: you are the tank. You are going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class is for you." # adventurer_introduction: "Let's be clear about your role: you are the tank. You're going to take heavy damage. We need people to try out brand-new levels and help identify how to make things better. The pain will be enormous; making good games is a long process and no one gets it right the first time. If you can endure and have a high constitution score, then this class might be for you." # adventurer_attribute_1: "A thirst for learning. You want to learn how to code and we want to teach you how to code. You'll probably be doing most of the teaching in this case, though." @@ -773,7 +773,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # adventurer_forum_url: "our forum" # adventurer_join_suf: "so if you prefer to be notified those ways, sign up there!" more_about_adventurer: "Aprenda Mais Sobre Tornar-se um Aventureiro" -# adventurer_subscribe_desc: "Get emails when there are new levels to test." + adventurer_subscribe_desc: "Receber e-mails quando houver novos níveis para testar." # scribe_summary_pref: "CodeCombat is not just going to be a bunch of levels. It will also be a resource of programming knowledge that players can hook into. That way, each Artisan can link to a detailed article that for the player's edification: documentation akin to what the " # scribe_summary_suf: " has built. If you enjoy explaining programming concepts, then this class is for you." # scribe_introduction_pref: "CodeCombat isn't just going to be a bunch of levels. It will also include a resource for knowledge, a wiki of programming concepts that levels can hook into. That way rather than each Artisan having to describe in detail what a comparison operator is, they can simply link their level to the Article describing them that is already written for the player's edification. Something along the lines of what the " @@ -783,7 +783,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # contact_us_url: "Contact us" # scribe_join_description: "tell us a little about yourself, your experience with programming and what sort of things you'd like to write about. We'll go from there!" more_about_scribe: "Aprenda Mais Sobre Tornar-se um Escrivão" -# scribe_subscribe_desc: "Get emails about article writing announcements." + 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" @@ -793,7 +793,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # diplomat_github_url: "on GitHub" # diplomat_join_suf_github: ", edit it online, and submit a pull request. Also, check this box below to keep up-to-date on new internationalization developments!" more_about_diplomat: "Aprenda Mais Sobre Tornar-se um Diplomata" -# diplomat_subscribe_desc: "Get emails about i18n developments and levels to translate." + diplomat_subscribe_desc: "Receber e-mails sobre desenvolvimentos da i18n e níveis para traduzir." # ambassador_summary: "We are trying to build a community, and every community needs a support team when there are troubles. We have got chats, emails, and social networks so that our users can get acquainted with the game. If you want to help people get involved, have fun, and learn some programming, then this class is for you." # ambassador_introduction: "This is a community we're building, and you are the connections. We've got Olark chats, emails, and social networks with lots of people to talk with and help get acquainted with the game and learn from. If you want to help people get involved and have fun, and get a good feel of the pulse of CodeCombat and where we're going, then this class might be for you." # ambassador_attribute_1: "Communication skills. Be able to identify the problems players are having and help them solve them. Also, keep the rest of us informed about what players are saying, what they like and don't like and want more of!" @@ -801,7 +801,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # ambassador_join_note_strong: "Note" # ambassador_join_note_desc: "One of our top priorities is to build multiplayer where players having difficulty solving levels can summon higher level wizards to help them. This will be a great way for ambassadors to do their thing. We'll keep you posted!" more_about_ambassador: "Aprenda Mais Sobre Tornar-se um Embaixador" -# ambassador_subscribe_desc: "Get emails on support updates and multiplayer developments." + ambassador_subscribe_desc: "Receber e-mails relativos a novidades do suporte e desenvolvimentos do modo multijogador." changes_auto_save: "As alterações são guardadas automaticamente quando clica nas caixas." diligent_scribes: "Os Nossos Dedicados Escrivões:" powerful_archmages: "Os Nossos Poderosos Arcomagos:" @@ -830,7 +830,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: simulate: "Simular" simulation_explanation: "Ao simular jogos pode ter o seu jogo classificado mais rapidamente!" simulate_games: "Simular Jogos!" -# simulate_all: "RESET AND SIMULATE GAMES" + simulate_all: "REINICIAR E SIMULAR JOGOS" games_simulated_by: "Jogos simulados por si:" games_simulated_for: "Jogos simulados para si:" games_simulated: "Jogos simulados" @@ -934,8 +934,8 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: level_session: "A Sua Sessão" opponent_session: "Sessão do Adversário" article: "Artigo" -# user_names: "User Names" -# thang_names: "Thang Names" + user_names: "Nomes de Utilizador" + thang_names: "Nomes de Thangs" files: "Ficheiros" # top_simulators: "Top Simulators" source_document: "Documento Fonte" From 8f6d1625426c92c304b552acdfe685d65652c2f4 Mon Sep 17 00:00:00 2001 From: Pete DiSalvo Date: Thu, 31 Jul 2014 22:11:48 -0400 Subject: [PATCH 06/16] Beginning work on edge detection --- app/lib/surface/CoordinateDisplay.coffee | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee index bb3e233f8..29ca949f9 100644 --- a/app/lib/surface/CoordinateDisplay.coffee +++ b/app/lib/surface/CoordinateDisplay.coffee @@ -30,6 +30,7 @@ module.exports = class CoordinateDisplay extends createjs.Container @label.shadow = new createjs.Shadow('#000000', 1, 1, 0) @background.name = 'Coordinate Display Background' @pointMarker.name = 'Point Marker' + @containerOverlay = new createjs.Shape() # FOR TESTING - REMOVE BEFORE COMMIT onMouseOver: (e) -> @mouseInBounds = true onMouseOut: (e) -> @mouseInBounds = false @@ -63,6 +64,7 @@ module.exports = class CoordinateDisplay extends createjs.Container @removeChild @label @removeChild @background @removeChild @pointMarker + @removeChild @containerOverlay # FOR TESTING - REMOVE BEFORE COMMIT @uncache() updateSize: -> @@ -82,6 +84,15 @@ module.exports = class CoordinateDisplay extends createjs.Container totalWidth = contentWidth + contributionsToTotalSize.reduce (a, b) -> a + b totalHeight = contentHeight + contributionsToTotalSize.reduce (a, b) -> a + b + @containerOverlay.graphics + .clear() + .beginFill('rgba(255,0,0,0.4)') # Actual position + .drawRect(0, 0, totalWidth, totalHeight) + .endFill() + .beginFill('rgba(0,0,255,0.4)') # Cache position + .drawRect(-pointMarkerLength, -totalHeight + pointMarkerLength, totalWidth, totalHeight) + .endFill() + @cache -pointMarkerLength, -totalHeight + pointMarkerLength, totalWidth, totalHeight updateCoordinates: (contentWidth, contentHeight, initialXYOffset) -> @@ -123,5 +134,6 @@ module.exports = class CoordinateDisplay extends createjs.Container @addChild @background @addChild @label @addChild @pointMarker + @addChild @containerOverlay # FOR TESTING - REMOVE BEFORE COMMIT @updateCache() Backbone.Mediator.publish 'surface:coordinates-shown', {} From dc7529344cc09415732402af7b4b37d4a0ff7ec1 Mon Sep 17 00:00:00 2001 From: Pete DiSalvo Date: Fri, 1 Aug 2014 00:14:54 -0400 Subject: [PATCH 07/16] Working on orientation --- app/lib/surface/CoordinateDisplay.coffee | 32 +++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee index 29ca949f9..3a8538f31 100644 --- a/app/lib/surface/CoordinateDisplay.coffee +++ b/app/lib/surface/CoordinateDisplay.coffee @@ -72,28 +72,48 @@ module.exports = class CoordinateDisplay extends createjs.Container contentWidth = @label.getMeasuredWidth() + (2 * margin) contentHeight = @label.getMeasuredHeight() + (2 * margin) - # Shift all contents up so marker is at pointer (affects container cache position) - @label.regY = @background.regY = @pointMarker.regY = contentHeight + # Shift pointmarker up so it centers at pointer (affects container cache position) + @pointMarker.regY = contentHeight pointMarkerStroke = 2 pointMarkerLength = 8 + fullPointMarkerLength = pointMarkerLength + (pointMarkerStroke / 2) contributionsToTotalSize = [] - contributionsToTotalSize = contributionsToTotalSize.concat @updateCoordinates contentWidth, contentHeight, pointMarkerLength + contributionsToTotalSize = contributionsToTotalSize.concat @updateCoordinates contentWidth, contentHeight, fullPointMarkerLength contributionsToTotalSize = contributionsToTotalSize.concat @updatePointMarker 0, contentHeight, pointMarkerLength, pointMarkerStroke totalWidth = contentWidth + contributionsToTotalSize.reduce (a, b) -> a + b totalHeight = contentHeight + contributionsToTotalSize.reduce (a, b) -> a + b + # All below is orientation dependent... + # Effected by orientation: + # background and label: regY and regX + # Caching position + # Crosshair stays in same place + # let e := edge + # if the :e: edge of coordinate display is outside camera :e: view, then show :e: edge orientation + + orientationVerticalModifier = 1 + cacheY = fullPointMarkerLength + + if true # near top edge + orientationVerticalModifier = -orientationVerticalModifier + cacheY = cacheY * orientationVerticalModifier + else + cacheY = -totalHeight + cacheY + @containerOverlay.graphics .clear() .beginFill('rgba(255,0,0,0.4)') # Actual position .drawRect(0, 0, totalWidth, totalHeight) .endFill() .beginFill('rgba(0,0,255,0.4)') # Cache position - .drawRect(-pointMarkerLength, -totalHeight + pointMarkerLength, totalWidth, totalHeight) + .drawRect(-fullPointMarkerLength, cacheY, totalWidth, totalHeight) .endFill() - @cache -pointMarkerLength, -totalHeight + pointMarkerLength, totalWidth, totalHeight + @label.regY = @background.regY = (totalHeight - contentHeight) * orientationVerticalModifier + + #@cache -fullPointMarkerLength, -totalHeight + fullPointMarkerLength, totalWidth, totalHeight updateCoordinates: (contentWidth, contentHeight, initialXYOffset) -> offsetForPointMarker = initialXYOffset @@ -135,5 +155,5 @@ module.exports = class CoordinateDisplay extends createjs.Container @addChild @label @addChild @pointMarker @addChild @containerOverlay # FOR TESTING - REMOVE BEFORE COMMIT - @updateCache() + #@updateCache() Backbone.Mediator.publish 'surface:coordinates-shown', {} From 31e609c0c85e5f03d342b0c7cedd08bfdc4a100a Mon Sep 17 00:00:00 2001 From: Pete DiSalvo Date: Mon, 4 Aug 2014 00:14:27 -0400 Subject: [PATCH 08/16] Added edge detection to camera, and worked on orientations --- app/lib/surface/Camera.coffee | 6 +++ app/lib/surface/CoordinateDisplay.coffee | 49 ++++++++++++------------ 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/app/lib/surface/Camera.coffee b/app/lib/surface/Camera.coffee index 4a65f52db..844086066 100644 --- a/app/lib/surface/Camera.coffee +++ b/app/lib/surface/Camera.coffee @@ -150,6 +150,12 @@ module.exports = class Camera extends CocoClass #zv = Math.min(Math.max(0, worldPos.z - 5), cPos.z - 5) / (cPos.z - 5) #zv * ratioWithY + (1 - zv) * ratioWithoutY + distanceToTopEdge: (y) -> + @worldViewport.y - y + + distanceToRightEdge: (x) -> + (@worldViewport.x + @worldViewport.width) - x + # SUBSCRIPTIONS onZoomIn: (e) -> @zoomTo @target, @zoom * 1.15, 300 diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee index 3a8538f31..0045d8168 100644 --- a/app/lib/surface/CoordinateDisplay.coffee +++ b/app/lib/surface/CoordinateDisplay.coffee @@ -85,22 +85,25 @@ module.exports = class CoordinateDisplay extends createjs.Container totalWidth = contentWidth + contributionsToTotalSize.reduce (a, b) -> a + b totalHeight = contentHeight + contributionsToTotalSize.reduce (a, b) -> a + b - # All below is orientation dependent... - # Effected by orientation: - # background and label: regY and regX - # Caching position - # Crosshair stays in same place - # let e := edge - # if the :e: edge of coordinate display is outside camera :e: view, then show :e: edge orientation + # Orientation + #find the current orientation and store it in an instance variable + # i.e.: topright, bottomright, bottomleft, topleft (default is topright) + #can be done separately: + # -use regx and y to adjust label and background position + # -adjust the cache position + # both can use the current orientation to do their work without knowing about the other - orientationVerticalModifier = 1 - cacheY = fullPointMarkerLength + startPos = + x: -fullPointMarkerLength + y: -totalHeight + fullPointMarkerLength + posShift = + x: 0 + y: contentHeight - if true # near top edge - orientationVerticalModifier = -orientationVerticalModifier - cacheY = cacheY * orientationVerticalModifier - else - cacheY = -totalHeight + cacheY + @orient startPos, posShift, totalHeight, totalWidth + + orient: (startPos, posShift, totalHeight, totalWidth) -> + @label.regY = @background.regY = posShift.y @containerOverlay.graphics .clear() @@ -108,29 +111,25 @@ module.exports = class CoordinateDisplay extends createjs.Container .drawRect(0, 0, totalWidth, totalHeight) .endFill() .beginFill('rgba(0,0,255,0.4)') # Cache position - .drawRect(-fullPointMarkerLength, cacheY, totalWidth, totalHeight) + .drawRect(startPos.x, startPos.y, totalWidth, totalHeight) .endFill() - @label.regY = @background.regY = (totalHeight - contentHeight) * orientationVerticalModifier - - #@cache -fullPointMarkerLength, -totalHeight + fullPointMarkerLength, totalWidth, totalHeight - - updateCoordinates: (contentWidth, contentHeight, initialXYOffset) -> - offsetForPointMarker = initialXYOffset + #@cache orientationX, orientationY, totalWidth, totalHeight + updateCoordinates: (contentWidth, contentHeight, offset) -> # Center label horizontally and vertically - @label.x = contentWidth / 2 - (@label.getMeasuredWidth() / 2) + offsetForPointMarker - @label.y = contentHeight / 2 - (@label.getMeasuredHeight() / 2) - offsetForPointMarker + @label.x = contentWidth / 2 - (@label.getMeasuredWidth() / 2) + offset + @label.y = contentHeight / 2 - (@label.getMeasuredHeight() / 2) - offset @background.graphics .clear() .beginFill('rgba(0,0,0,0.4)') .beginStroke('rgba(0,0,0,0.6)') .setStrokeStyle(backgroundStroke = 1) - .drawRoundRect(offsetForPointMarker, -offsetForPointMarker, contentWidth, contentHeight, radius = 2.5) + .drawRoundRect(offset, -offset, contentWidth, contentHeight, radius = 2.5) .endFill() .endStroke() - contributionsToTotalSize = [offsetForPointMarker, backgroundStroke] + contributionsToTotalSize = [offset, backgroundStroke] updatePointMarker: (centerX, centerY, length, strokeSize) -> strokeStyle = 'square' From eed68c0a1ce45d7fa7aae13f138626089e407e74 Mon Sep 17 00:00:00 2001 From: Pete DiSalvo Date: Wed, 13 Aug 2014 00:01:35 -0400 Subject: [PATCH 09/16] Working orientation. Doesn't account for camera zoom --- app/lib/surface/CoordinateDisplay.coffee | 40 +++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee index 0045d8168..e12b78177 100644 --- a/app/lib/surface/CoordinateDisplay.coffee +++ b/app/lib/surface/CoordinateDisplay.coffee @@ -93,17 +93,35 @@ module.exports = class CoordinateDisplay extends createjs.Container # -adjust the cache position # both can use the current orientation to do their work without knowing about the other - startPos = - x: -fullPointMarkerLength - y: -totalHeight + fullPointMarkerLength - posShift = - x: 0 - y: contentHeight + if @isNearTopEdge() + verticalEdge = + startPos: -fullPointMarkerLength + posShift: -contentHeight + 4 + else + verticalEdge = + startPos: -totalHeight + fullPointMarkerLength + posShift: contentHeight - @orient startPos, posShift, totalHeight, totalWidth + if @isNearRightEdge() + horizontalEdge = + startPos: -totalWidth + fullPointMarkerLength + posShift: totalWidth + else + horizontalEdge = + startPos: -fullPointMarkerLength + posShift: 0 - orient: (startPos, posShift, totalHeight, totalWidth) -> - @label.regY = @background.regY = posShift.y + @orient verticalEdge, horizontalEdge, totalHeight, totalWidth + + isNearTopEdge: -> + @camera.distanceToTopEdge(@lastPos.y) <= 1 + + isNearRightEdge: -> + @camera.distanceToRightEdge(@lastPos.x) <= 4 + + orient: (verticalEdge, horizontalEdge, totalHeight, totalWidth) -> + @label.regY = @background.regY = verticalEdge.posShift + @label.regX = @background.regX = horizontalEdge.posShift @containerOverlay.graphics .clear() @@ -111,10 +129,10 @@ module.exports = class CoordinateDisplay extends createjs.Container .drawRect(0, 0, totalWidth, totalHeight) .endFill() .beginFill('rgba(0,0,255,0.4)') # Cache position - .drawRect(startPos.x, startPos.y, totalWidth, totalHeight) + .drawRect(horizontalEdge.startPos, verticalEdge.startPos, totalWidth, totalHeight) .endFill() - #@cache orientationX, orientationY, totalWidth, totalHeight + #@cache horizontalEdge.startPos, verticalEdge.startPos, totalWidth, totalHeight updateCoordinates: (contentWidth, contentHeight, offset) -> # Center label horizontally and vertically From a011f118e3487e4ab7e29343940b211341d6830c Mon Sep 17 00:00:00 2001 From: Pete DiSalvo Date: Sat, 16 Aug 2014 18:29:31 -0400 Subject: [PATCH 10/16] Added CoordinateDisplay edge detection. Doesn't account for camera zoom. --- app/lib/surface/CoordinateDisplay.coffee | 25 ++---------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee index e12b78177..83c7501b5 100644 --- a/app/lib/surface/CoordinateDisplay.coffee +++ b/app/lib/surface/CoordinateDisplay.coffee @@ -30,7 +30,6 @@ module.exports = class CoordinateDisplay extends createjs.Container @label.shadow = new createjs.Shadow('#000000', 1, 1, 0) @background.name = 'Coordinate Display Background' @pointMarker.name = 'Point Marker' - @containerOverlay = new createjs.Shape() # FOR TESTING - REMOVE BEFORE COMMIT onMouseOver: (e) -> @mouseInBounds = true onMouseOut: (e) -> @mouseInBounds = false @@ -64,7 +63,6 @@ module.exports = class CoordinateDisplay extends createjs.Container @removeChild @label @removeChild @background @removeChild @pointMarker - @removeChild @containerOverlay # FOR TESTING - REMOVE BEFORE COMMIT @uncache() updateSize: -> @@ -85,14 +83,6 @@ module.exports = class CoordinateDisplay extends createjs.Container totalWidth = contentWidth + contributionsToTotalSize.reduce (a, b) -> a + b totalHeight = contentHeight + contributionsToTotalSize.reduce (a, b) -> a + b - # Orientation - #find the current orientation and store it in an instance variable - # i.e.: topright, bottomright, bottomleft, topleft (default is topright) - #can be done separately: - # -use regx and y to adjust label and background position - # -adjust the cache position - # both can use the current orientation to do their work without knowing about the other - if @isNearTopEdge() verticalEdge = startPos: -fullPointMarkerLength @@ -122,17 +112,7 @@ module.exports = class CoordinateDisplay extends createjs.Container orient: (verticalEdge, horizontalEdge, totalHeight, totalWidth) -> @label.regY = @background.regY = verticalEdge.posShift @label.regX = @background.regX = horizontalEdge.posShift - - @containerOverlay.graphics - .clear() - .beginFill('rgba(255,0,0,0.4)') # Actual position - .drawRect(0, 0, totalWidth, totalHeight) - .endFill() - .beginFill('rgba(0,0,255,0.4)') # Cache position - .drawRect(horizontalEdge.startPos, verticalEdge.startPos, totalWidth, totalHeight) - .endFill() - - #@cache horizontalEdge.startPos, verticalEdge.startPos, totalWidth, totalHeight + @cache horizontalEdge.startPos, verticalEdge.startPos, totalWidth, totalHeight updateCoordinates: (contentWidth, contentHeight, offset) -> # Center label horizontally and vertically @@ -171,6 +151,5 @@ module.exports = class CoordinateDisplay extends createjs.Container @addChild @background @addChild @label @addChild @pointMarker - @addChild @containerOverlay # FOR TESTING - REMOVE BEFORE COMMIT - #@updateCache() + @updateCache() Backbone.Mediator.publish 'surface:coordinates-shown', {} From 48a79ad48c708f3dc1aa805a82770ea11d1fde36 Mon Sep 17 00:00:00 2001 From: Ruben Vereecken Date: Mon, 18 Aug 2014 14:35:57 +0200 Subject: [PATCH 11/16] New achievement modal fills in level.original query bit --- app/views/editor/level/RelatedAchievementsView.coffee | 2 +- app/views/editor/level/modals/NewAchievementModal.coffee | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/editor/level/RelatedAchievementsView.coffee b/app/views/editor/level/RelatedAchievementsView.coffee index e0ff97d54..ccb9969eb 100644 --- a/app/views/editor/level/RelatedAchievementsView.coffee +++ b/app/views/editor/level/RelatedAchievementsView.coffee @@ -16,7 +16,7 @@ module.exports = class RelatedAchievementsView extends CocoView constructor: (options) -> super options @level = options.level - @relatedID = @level.id + @relatedID = @level.get('original') @achievements = new RelatedAchievementsCollection @relatedID @supermodel.loadCollection @achievements, 'achievements' diff --git a/app/views/editor/level/modals/NewAchievementModal.coffee b/app/views/editor/level/modals/NewAchievementModal.coffee index a666bd239..dba9a0e93 100644 --- a/app/views/editor/level/modals/NewAchievementModal.coffee +++ b/app/views/editor/level/modals/NewAchievementModal.coffee @@ -37,6 +37,7 @@ module.exports = class NewAchievementModal extends NewModelModal query = subQueries[0] else query = $or: subQueries + query['level.original'] = @level.get 'original' query makeNewModel: -> @@ -50,5 +51,6 @@ module.exports = class NewAchievementModal extends NewModelModal achievement.set 'query', query achievement.set 'collection', 'level.sessions' achievement.set 'userField', 'creator' + achievement.set 'related', @level.get('original') achievement From 1f51eabe48b5227cf0738f446343c935fa7d3f67 Mon Sep 17 00:00:00 2001 From: Darredevil Date: Mon, 18 Aug 2014 18:39:16 +0300 Subject: [PATCH 12/16] Added new 'Minimax Tic-Tac-Toe' level --- app/views/play/MainPlayView.coffee | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/views/play/MainPlayView.coffee b/app/views/play/MainPlayView.coffee index c46f906c4..c2e557d1a 100644 --- a/app/views/play/MainPlayView.coffee +++ b/app/views/play/MainPlayView.coffee @@ -229,6 +229,13 @@ module.exports = class MainPlayView extends RootView image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png' description: 'Learn Quicksort while sorting a spiral of ogres! - by Alexandru Caciulescu' } + { + name: 'Minimax Tic-Tac-Toe' + difficulty: 4 + id: 'minimax-tic-tac-toe' + image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png' + description: 'Learn how to make a game AI with the Minimax algorithm. - by Alexandru Caciulescu' + } ] playerCreated = [ From 69ab1777022da3d2b72ccbc2b561fc4996bc17b6 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Fri, 15 Aug 2014 12:28:32 -0700 Subject: [PATCH 13/16] Trying to get rid of debug logs in karma. Tried to do it with the conf, didn't seem to work, did a hack instead. --- app/assets/javascripts/run-tests.js | 1 + karma.conf.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/run-tests.js b/app/assets/javascripts/run-tests.js index ad1de1989..5165dd49d 100644 --- a/app/assets/javascripts/run-tests.js +++ b/app/assets/javascripts/run-tests.js @@ -2,5 +2,6 @@ // Hooks into the test view logic for running tests. require('initialize'); +console.debug = function() {}; // Karma conf doesn't seem to work? Debug messages are still emitted when they shouldn't be. TestView = require('views/TestView'); TestView.runTests(); \ No newline at end of file diff --git a/karma.conf.js b/karma.conf.js index bf0924f77..5a4224edf 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -43,7 +43,7 @@ module.exports = function(config) { // level of logging // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG - logLevel : config.LOG_INFO, + logLevel : config.LOG_ERROR, // doesn't seem to work? // enable / disable watching file and executing tests whenever any file changes autoWatch : true, From 86ba46b64c1ecd4e4ff6baf5d105c3f44a85c861 Mon Sep 17 00:00:00 2001 From: Scott Erickson Date: Fri, 15 Aug 2014 12:41:29 -0700 Subject: [PATCH 14/16] Refactored LevelLoader's loading of session dependencies a bit so it's easy to have it load them on demand. --- app/lib/LevelLoader.coffee | 13 ++--- test/app/lib/LevelLoader.spec.coffee | 71 ++++++++++++++++++---------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index c4c3103ab..95edc1852 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -67,16 +67,17 @@ module.exports = class LevelLoader extends CocoClass session = new LevelSession().setURL url @sessionResource = @supermodel.loadModel(session, 'level_session', {cache: false}) @session = @sessionResource.model - @listenToOnce @session, 'sync', @onSessionLoaded - + @listenToOnce @session, 'sync', -> + @session.url = -> '/db/level.session/' + @id + @loadDependenciesForSession(@session) + if @opponentSessionID opponentSession = new LevelSession().setURL "/db/level_session/#{@opponentSessionID}" @opponentSessionResource = @supermodel.loadModel(opponentSession, 'opponent_session') @opponentSession = @opponentSessionResource.model - @listenToOnce @opponentSession, 'sync', @onSessionLoaded - - onSessionLoaded: (session) -> - session.url = -> '/db/level.session/' + @id + @listenToOnce @opponentSession, 'sync', @loadDependenciesForSession + + loadDependenciesForSession: (session) -> if heroConfig = session.get('heroConfig') url = "/db/thang.type/#{heroConfig.thangType}/version?project=name,components,original" @worldNecessities.push @maybeLoadURL(url, ThangType, 'thang') diff --git a/test/app/lib/LevelLoader.spec.coffee b/test/app/lib/LevelLoader.spec.coffee index d9102a299..e3cb98dd1 100644 --- a/test/app/lib/LevelLoader.spec.coffee +++ b/test/app/lib/LevelLoader.spec.coffee @@ -41,6 +41,8 @@ levelWithShamanWithSuperWand = { sessionWithTharinWithHelmet = { heroConfig: { thangType: 'tharin', inventory: { 'head': 'helmet' }}} +sessionWithAnyaWithGloves = { heroConfig: { thangType: 'anya', inventory: { 'head': 'gloves' }}} + # THANG TYPES thangTypeOgreWithPhysicalComponent = { @@ -80,35 +82,56 @@ thangTypeWand = { }] } +thangTypeAnyaWithJumpsComponent = { + name: 'Anya' + original: 'anya' + components: [{ + original: 'jumps' + majorVersion: 0 + }] +} + describe 'LevelLoader', -> - it 'loads hero and item thang types from heroConfig in the LevelSession', -> - new LevelLoader({supermodel:new SuperModel(), sessionID: 'id', levelID: 'id'}) - - responses = { - '/db/level_session/id': sessionWithTharinWithHelmet - } - - jasmine.Ajax.requests.sendResponses(responses) - requests = jasmine.Ajax.requests.all() - urls = (r.url for r in requests) - expect('/db/thang.type/helmet/version?project=name,components,original' in urls).toBeTruthy() - expect('/db/thang.type/tharin/version?project=name,components,original' in urls).toBeTruthy() - - it 'loads components for the hero in the heroConfig in the LevelSession', -> - new LevelLoader({supermodel:new SuperModel(), sessionID: 'id', levelID: 'id'}) + describe 'loadDependenciesForSession', -> + it 'loads hero and item thang types from heroConfig in the given session', -> + levelLoader = new LevelLoader({supermodel:new SuperModel(), sessionID: 'id', levelID: 'id'}) + session = new LevelSession(sessionWithAnyaWithGloves) + levelLoader.loadDependenciesForSession(session) + requests = jasmine.Ajax.requests.all() + urls = (r.url for r in requests) + expect('/db/thang.type/gloves/version?project=name,components,original' in urls).toBeTruthy() + expect('/db/thang.type/anya/version?project=name,components,original' in urls).toBeTruthy() - responses = { - '/db/level_session/id': sessionWithTharinWithHelmet - '/db/thang.type/tharin/version?project=name,components,original': thangTypeTharinWithHealsComponent - } + it 'loads components for the hero in the heroConfig in the given session', -> + levelLoader = new LevelLoader({supermodel:new SuperModel(), sessionID: 'id', levelID: 'id'}) + session = new LevelSession(sessionWithAnyaWithGloves) + levelLoader.loadDependenciesForSession(session) + responses = { + '/db/thang.type/anya/version?project=name,components,original': thangTypeAnyaWithJumpsComponent + } + jasmine.Ajax.requests.sendResponses(responses) + requests = jasmine.Ajax.requests.all() + urls = (r.url for r in requests) + expect('/db/level.component/jumps/version/0' in urls).toBeTruthy() + + it 'is idempotent', -> + levelLoader = new LevelLoader({supermodel:new SuperModel(), sessionID: 'id', levelID: 'id'}) - jasmine.Ajax.requests.sendResponses(responses) - requests = jasmine.Ajax.requests.all() - urls = (r.url for r in requests) - expect('/db/level.component/heals/version/0' in urls).toBeTruthy() - + # first load Tharin by the 'normal' session load + responses = { '/db/level_session/id': sessionWithTharinWithHelmet } + jasmine.Ajax.requests.sendResponses(responses) + numRequestsBefore = jasmine.Ajax.requests.count() + + # then try to load Tharin some more + session = new LevelSession(sessionWithTharinWithHelmet) + levelLoader.loadDependenciesForSession(session) + levelLoader.loadDependenciesForSession(session) + levelLoader.loadDependenciesForSession(session) + numRequestsAfter = jasmine.Ajax.requests.count() + expect(numRequestsBefore).toBe(numRequestsAfter) + it 'loads thangs for items that the level thangs have in their Equips component configs', -> new LevelLoader({supermodel:supermodel = new SuperModel(), sessionID: 'id', levelID: 'id'}) From 8ca9374de070c147528dea65355d70934ec059a2 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Mon, 18 Aug 2014 14:08:54 -0700 Subject: [PATCH 15/16] Zoom-aware, ratio-based edge avoidance (polish for #1448). --- app/lib/surface/Camera.coffee | 6 ------ app/lib/surface/CoordinateDisplay.coffee | 8 +++++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/lib/surface/Camera.coffee b/app/lib/surface/Camera.coffee index 844086066..4a65f52db 100644 --- a/app/lib/surface/Camera.coffee +++ b/app/lib/surface/Camera.coffee @@ -150,12 +150,6 @@ module.exports = class Camera extends CocoClass #zv = Math.min(Math.max(0, worldPos.z - 5), cPos.z - 5) / (cPos.z - 5) #zv * ratioWithY + (1 - zv) * ratioWithoutY - distanceToTopEdge: (y) -> - @worldViewport.y - y - - distanceToRightEdge: (x) -> - (@worldViewport.x + @worldViewport.width) - x - # SUBSCRIPTIONS onZoomIn: (e) -> @zoomTo @target, @zoom * 1.15, 300 diff --git a/app/lib/surface/CoordinateDisplay.coffee b/app/lib/surface/CoordinateDisplay.coffee index 83c7501b5..f650e09b1 100644 --- a/app/lib/surface/CoordinateDisplay.coffee +++ b/app/lib/surface/CoordinateDisplay.coffee @@ -84,7 +84,7 @@ module.exports = class CoordinateDisplay extends createjs.Container totalHeight = contentHeight + contributionsToTotalSize.reduce (a, b) -> a + b if @isNearTopEdge() - verticalEdge = + verticalEdge = startPos: -fullPointMarkerLength posShift: -contentHeight + 4 else @@ -104,10 +104,12 @@ module.exports = class CoordinateDisplay extends createjs.Container @orient verticalEdge, horizontalEdge, totalHeight, totalWidth isNearTopEdge: -> - @camera.distanceToTopEdge(@lastPos.y) <= 1 + yRatio = 1 - (@camera.worldViewport.y - @lastPos.y) / @camera.worldViewport.height + yRatio > 0.9 isNearRightEdge: -> - @camera.distanceToRightEdge(@lastPos.x) <= 4 + xRatio = (@lastPos.x - @camera.worldViewport.x) / @camera.worldViewport.width + xRatio > 0.85 orient: (verticalEdge, horizontalEdge, totalHeight, totalWidth) -> @label.regY = @background.regY = verticalEdge.posShift From 2588ec67ffa7f166a433c386ac8f3c74d8f69e38 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Mon, 18 Aug 2014 14:09:28 -0700 Subject: [PATCH 16/16] Fix for buildLoop still trying to loop after LevelLoader destruction for some reason. --- app/lib/LevelLoader.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index 95edc1852..48a980831 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -229,7 +229,7 @@ module.exports = class LevelLoader extends CocoClass res.markLoading() @spriteSheetsToBuild.push res - @buildLoopInterval = setInterval @buildLoop, 5 + @buildLoopInterval = setInterval @buildLoop, 5 if @spriteSheetsToBuild.length maybeLoadURL: (url, Model, resourceName) -> return if @supermodel.getModel(url)