From 95afb6c4d31446758fc778c5ce8f1ac1041ffa14 Mon Sep 17 00:00:00 2001 From: George Saines Date: Fri, 10 Oct 2014 16:55:09 -0700 Subject: [PATCH 01/15] playing with FPS --- app/lib/surface/Surface.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee index b96203fd4..e23315bda 100644 --- a/app/lib/surface/Surface.coffee +++ b/app/lib/surface/Surface.coffee @@ -52,7 +52,7 @@ module.exports = Surface = class Surface extends CocoClass coords: null # use world defaults, or set to false/true to override playJingle: false showInvisible: false - frameRate: 30 # Best as a divisor of 60, like 15, 30, 60, with RAF_SYNCHED timing. + frameRate: 60 # Best as a divisor of 60, like 15, 30, 60, with RAF_SYNCHED timing. subscriptions: 'level:disable-controls': 'onDisableControls' From 5016529f6b3442705c859cfef7b4647a647e51f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20T=C3=A1mara?= Date: Sat, 11 Oct 2014 14:09:18 -0500 Subject: [PATCH 02/15] Update es-419.coffee --- app/locale/es-419.coffee | 210 +++++++++++++++++++-------------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index 4a20b00f2..5669aa6ac 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -34,7 +34,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip about: "Sobre" contact: "Contacto" twitter_follow: "Seguir" -# teachers: "Teachers" + teachers: "Profesores" modal: close: "Cerrar" @@ -62,17 +62,17 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip account: "Cuenta" # Tooltip on account button from /play settings: "Configuración" # Tooltip on settings button from /play next: "Próximo" # Go from choose hero to choose inventory before playing a level -# change_hero: "Change Hero" # Go back from choose inventory to choose hero + change_hero: "Cambiar héroe" # Go back from choose inventory to choose hero choose_inventory: "Equipar objetos" -# older_campaigns: "Older Campaigns" -# anonymous: "Anonymous Player" + older_campaigns: "Campañas previas" + anonymous: "Jugador Anónimo" level_difficulty: "Dificultad: " campaign_beginner: "Campaña para principiantes" choose_your_level: "Elige tu nivel" # The rest of this section is the old play view at /play-old and isn't very important. adventurer_prefix: "Puedes saltar a cualquier nivel de abajo, o discutir los niveles en " adventurer_forum: "el foro del aventurero" adventurer_suffix: "." -# campaign_old_beginner: "Old Beginner Campaign" + campaign_old_beginner: "Campaña anterior de principiante" campaign_beginner_description: "... en la que aprendes la hechicería de la programación." campaign_dev: "Niveles aleatorios más difíciles" campaign_dev_description: "... en los que aprendes sobre la interfaz mientras haces algo un poco más difícil." @@ -135,7 +135,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip general: and: "y" name: "Nombre" -# date: "Date" + date: "Fecha" body: "Cuerpo" version: "Versión" commit_msg: "Enviar mensaje" @@ -182,20 +182,20 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip play_level: done: "Listo" home: "Inicio" -# skip: "Skip" + skip: "Omitir" game_menu: "Menu del Juego" guide: "Guia" restart: "Reiniciar" goals: "Objetivos" -# goal: "Goal" + goal: "Objetivo" success: "¡Éxito!" incomplete: "Incompleto" timed_out: "Se te acabo el tiempo" failing: "Fallando" action_timeline: "Cronologia de Accion" click_to_select: "Has click en una unidad para seleccionarla." - reload_title: "¿Recargar Todo el Codigo?" - reload_really: "¿Estas seguro de que quieres empezar este nivel desde el principio?" + reload_title: "¿Recargar Todo el Código?" + reload_really: "¿Estás seguro de que quieres empezar este nivel desde el principio?" reload_confirm: "Recargar Todo" victory_title_prefix: "¡" victory_title_suffix: " Completo!" @@ -204,7 +204,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip victory_rate_the_level: "Valora el nivel: " # Only in old-style levels. victory_return_to_ladder: "Volver a la escalera" victory_play_next_level: "Jugar Próximo Nivel" # Only in old-style levels. -# victory_play_continue: "Continue" + victory_play_continue: "Continuar" victory_go_home: "Ir al Inicio" # Only in old-style levels. victory_review: "¡Cuéntanos más!" # Only in old-style levels. victory_hour_of_code_done: "¿Has acabado?" @@ -216,22 +216,22 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip tome_cast_button_castable: "Invocable" # Temporary, if tome_cast_button_run isn't translated. tome_cast_button_casting: "Invocando" # Temporary, if tome_cast_button_running isn't translated. tome_cast_button_cast: "Invocar" # Temporary, if tome_cast_button_ran isn't translated. -# tome_cast_button_run: "Run" -# tome_cast_button_running: "Running" -# tome_cast_button_ran: "Ran" -# tome_submit_button: "Submit" -# tome_reload_method: "Reload original code for this method" # Title text for individual method reload button. -# tome_select_method: "Select a Method" -# tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methdos). + tome_cast_button_run: "Ejecutar" + tome_cast_button_running: "Ejecutando" + tome_cast_button_ran: "Ejecutado" + tome_submit_button: "Enviar" + tome_reload_method: "Recargar código original para este método" # Title text for individual method reload button. + tome_select_method: "Seleccionar un Método" + tome_see_all_methods: "Ver todos los métodos que puedes editar" # Title text for method list selector (shown when there are multiple programmable methdos). tome_select_a_thang: "Selecciona Alguien para " tome_available_spells: "Hechizos Disponibles" -# tome_your_skills: "Your Skills" + tome_your_skills: "Tus habilidades" hud_continue: "Continuar (presionar shift+space)" spell_saved: "Hechizo Guardado" skip_tutorial: "Saltar (esc)" keyboard_shortcuts: "Atajos de teclado" loading_ready: "¡Listo!" -# loading_start: "Start Level" + loading_start: "Iniciar nivel" time_current: "Ahora:" time_total: "Max:" time_goto: "Ir a:" @@ -264,59 +264,59 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip tip_talk_is_cheap: "Hablar es barato. Muestrame el código. - Linus Torvalds" tip_first_language: "La cosa más desastroza que puedes aprender es tu primer lenguaje de programación. - Alan Kay" tip_hardware_problem: "P: ¿Cuántos programadores son necesarios para cambiar una bombilla eléctrica? R: Ninguno, es un problema de hardware." -# tip_hofstadters_law: "Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law." -# tip_premature_optimization: "Premature optimization is the root of all evil. - Donald Knuth" -# tip_brute_force: "When in doubt, use brute force. - Ken Thompson" + tip_hofstadters_law: "Ley de Hofstadter: Siempre toma más tiempo del que esperas, inclso cuando tienes en cuenta la ley de Hofstadter." + tip_premature_optimization: "La optimización prematura es la raíz de la maldad. - Donald Knuth" + tip_brute_force: "Cuando tengas duda, usa la fuerza bruta. - Ken Thompson" customize_wizard: "Personalizar Hechicero" game_menu: -# inventory_tab: "Inventory" -# choose_hero_tab: "Restart Level" -# save_load_tab: "Save/Load" -# options_tab: "Options" -# guide_tab: "Guide" + inventory_tab: "Inventario" + choose_hero_tab: "Reiniciar Nivel" + save_load_tab: "Guardar/Cargar" + options_tab: "Opciones" + guide_tab: "Guía" multiplayer_tab: "Multijugador" -# inventory_caption: "Equip your hero" -# choose_hero_caption: "Choose hero, language" -# save_load_caption: "... and view history" -# options_caption: "Configure settings" -# guide_caption: "Docs and tips" -# multiplayer_caption: "Play with friends!" + inventory_caption: "Equipar tu héroe" + choose_hero_caption: "Elegir héroe, lenguaje" + save_load_caption: "... y ver historia" + options_caption: "Hacer ajustes" + guide_caption: "Documentos y consejos" + multiplayer_caption: "¡Jugar con amigos!" -# inventory: -# choose_inventory: "Equip Items" + inventory: + choose_inventory: "Elegir artículos" -# choose_hero: -# choose_hero: "Choose Your Hero" -# programming_language: "Programming Language" -# programming_language_description: "Which programming language do you want to use?" -# status: "Status" -# weapons: "Weapons" -# health: "Health" -# speed: "Speed" + choose_hero: + choose_hero: "Elige tu héroe" + programming_language: "Lenguaje de programación" + programming_language_description: "¿Qué lenguaje de programación vas a elegir?" + status: "Estado" + weapons: "Armas" + health: "Salud" + speed: "Velocidad" -# save_load: -# granularity_saved_games: "Saved" -# granularity_change_history: "History" + save_load: + granularity_saved_games: "Almacenado" + granularity_change_history: "Historia" options: -# general_options: "General Options" # Check out the Options tab in the Game Menu while playing a level -# volume_label: "Volume" -# music_label: "Music" -# music_description: "Turn background music on/off." -# autorun_label: "Autorun" -# autorun_description: "Control automatic code execution." + general_options: "Opciones Generales" # Check out the Options tab in the Game Menu while playing a level + volume_label: "Volumen" + music_label: "Música" + music_description: "Música encendida/apagada." + autorun_label: "Autoejecutar" + autorun_description: "Controlar ejecución automática de código." editor_config: "Config. de Editor" editor_config_title: "Configuración del Editor" -# editor_config_level_language_label: "Language for This Level" -# editor_config_level_language_description: "Define the programming language for this particular level." -# editor_config_default_language_label: "Default Programming Language" -# editor_config_default_language_description: "Define the programming language you want to code in when starting new levels." + editor_config_level_language_label: "Lenguaje para este Nivel" + editor_config_level_language_description: "Definir el lenguaje de programación para Este nivel." + editor_config_default_language_label: "Lenguaje de Programación Predeterminado" + editor_config_default_language_description: "Definir el lenguaje de programación que deseas para codificar cuando inicias nuevos niveles." editor_config_keybindings_label: "Atajos de Teclado" editor_config_keybindings_default: "Default (As)" editor_config_keybindings_description: "Añade atajos adicionales conocidos de los editores comunes." -# editor_config_livecompletion_label: "Live Autocompletion" -# editor_config_livecompletion_description: "Displays autocomplete suggestions while typing." + editor_config_livecompletion_label: "Autocompletado automático" + editor_config_livecompletion_description: "Despliega sugerencias de autocompletado mientras escribes." editor_config_invisibles_label: "Mostrar Invisibles" editor_config_invisibles_description: "Visualiza invisibles tales como espacios o tabulaciones." editor_config_indentguides_label: "Mostrar guías de indentación" @@ -324,30 +324,30 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip editor_config_behaviors_label: "Comportamientos Inteligentes" editor_config_behaviors_description: "Autocompleta corchetes, llaves y comillas." -# about: -# why_codecombat: "Why CodeCombat?" -# why_paragraph_1: "If you want to learn to program, you don't need lessons. You need to write a lot of code and have a great time doing it." -# why_paragraph_2_prefix: "That's what programming is about. It's gotta be fun. Not fun like" -# why_paragraph_2_italic: "yay a badge" -# why_paragraph_2_center: "but fun like" -# why_paragraph_2_italic_caps: "NO MOM I HAVE TO FINISH THE LEVEL!" -# why_paragraph_2_suffix: "That's why CodeCombat is a multiplayer game, not a gamified lesson course. We won't stop until you can't stop--but this time, that's a good thing." -# why_paragraph_3: "If you're going to get addicted to some game, get addicted to this one and become one of the wizards of the tech age." -# press_title: "Bloggers/Press" -# press_paragraph_1_prefix: "Want to write about us? Feel free to download and use all of the resources included in our" -# press_paragraph_1_link: "press packet" -# press_paragraph_1_suffix: ". All logos and images may be used without contacting us directly." -# team: "Team" -# george_title: "CEO" -# george_blurb: "Businesser" -# scott_title: "Programmer" -# scott_blurb: "Reasonable One" -# nick_title: "Programmer" -# nick_blurb: "Motivation Guru" -# michael_title: "Programmer" -# michael_blurb: "Sys Admin" -# matt_title: "Programmer" -# matt_blurb: "Bicyclist" + about: + why_codecombat: "¿Por qué CodeCombat?" + why_paragraph_1: "Si quieres aprender a programar, no necesitas lecciones. Necesitas escribir mucho código y disfrutarlo mucho haciéndolo." + why_paragraph_2_prefix: "De eso se trata la programación. Será divertido. No casi divertido" + why_paragraph_2_italic: "bien un premio" + why_paragraph_2_center: "pero algo divertido" + why_paragraph_2_italic_caps: "¡NO MAMÁ, TENGO QUE FINALIZAR EL NIVEL!" + why_paragraph_2_suffix: "Por tal motivo CodeCombat es un juego multiusuario, no un curso con gamificación. No finalizaremos hasta que terminos--pero en esta ocasión, es una buena cosa." + why_paragraph_3: "si te vas a volver adicto a un juego, hazlo a este y conviértete en un de los magos de la era tecnológica." + press_title: "Blogeros/Prensa" + press_paragraph_1_prefix: "¿Quieres escribirnos? Descarga y usa con confianza todos los recursos incluídos en nuestro" + press_paragraph_1_link: "paquete de prensa" + press_paragraph_1_suffix: ". Todos los logos e imágenes pueden ser usados sin contactarnos directamente." + team: "Equipo" + george_title: "CEO" + george_blurb: "Negociante" + scott_title: "Programador" + scott_blurb: "Razonable" + nick_title: "Programador" + nick_blurb: "Gurú motivacional" + michael_title: "Programador" + michael_blurb: "Sys Admin" + matt_title: "Programador" + matt_blurb: "Bicicletero" versions: save_version_title: "Guardar nueva versión" @@ -410,32 +410,32 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip wizard_tab: "Hechicero" wizard_color: "Color de Ropas del Hechicero" -# keyboard_shortcuts: -# keyboard_shortcuts: "Keyboard Shortcuts" -# space: "Space" -# enter: "Enter" -# escape: "Escape" -# shift: "Shift" -# cast_spell: "Cast current spell." -# run_real_time: "Run in real time." -# continue_script: "Continue past current script." -# skip_scripts: "Skip past all skippable scripts." -# toggle_playback: "Toggle play/pause." -# scrub_playback: "Scrub back and forward through time." -# single_scrub_playback: "Scrub back and forward through time by a single frame." + keyboard_shortcuts: + keyboard_shortcuts: "Keyboard Shortcuts" + space: "Barra espaciadora" + enter: "Enter" + escape: "Escape" + shift: "Shift" + cast_spell: "Aplicar hechizo actual." + run_real_time: "Ejecutar en tiempo real." + continue_script: "Continuar hasta finalizado el script." + skip_scripts: "Omitir todos los scripts omitibles." + toggle_playback: "Aplicar ejecutar/pausar." + scrub_playback: "Devolverse y avanzar en el tiempo." + single_scrub_playback: "Devolverse y avanzar en el tiempo de a un cuadro." # scrub_execution: "Scrub through current spell execution." -# toggle_debug: "Toggle debug display." + toggle_debug: "Mostrar ocultar depuración." # toggle_grid: "Toggle grid overlay." # toggle_pathfinding: "Toggle pathfinding overlay." -# beautify: "Beautify your code by standardizing its formatting." -# maximize_editor: "Maximize/minimize code editor." -# move_wizard: "Move your Wizard around the level." + beautify: "Hacer bello tu código estandarizando formato." + maximize_editor: "Maximizar/minimizar editor de código." + move_wizard: "Mover tu hechizero en el nivel." -# community: -# main_title: "CodeCombat Community" -# 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!" + community: + main_title: "Comunidad CodeCombat" + introduction: "Mira las maneras en las que puedes involucrarte adelante y decide qué es más divertido. ¡Queremos trabajar contigo!" + level_editor_prefix: "Usar CodeCombat" + level_editor_suffix: "para crear y editar niveles. Los han creado niveles para sus clases, amigos, hackatones, estudiantes, familiares. Si crear un nuevo juego luce intimidante puedes ¡comenzar con base en uno nuestro!" # 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" From d75a0653c3205bc9da49f4570a0c4418ccd9a47d Mon Sep 17 00:00:00 2001 From: Gabriel Cesar Date: Sun, 12 Oct 2014 02:31:36 -0300 Subject: [PATCH 03/15] added some pt-br translations --- app/locale/pt-BR.coffee | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee index 798f49b25..999311233 100644 --- a/app/locale/pt-BR.coffee +++ b/app/locale/pt-BR.coffee @@ -34,7 +34,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: about: "Sobre" contact: "Contate-nos" twitter_follow: "Seguir" -# teachers: "Teachers" + teachers: "Professores" modal: close: "Fechar" @@ -55,24 +55,24 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: play_as: "Jogar Como " # Ladder page spectate: "Assistir" # Ladder page players: "jogadores" # Hover over a level on /play -# hours_played: "hours played" # Hover over a level on /play -# items: "Items" # Tooltip on item shop button from /play -# heroes: "Heroes" # Tooltip on hero shop button from /play -# achievements: "Achievements" # Tooltip on achievement list button from /play -# account: "Account" # Tooltip on account button from /play -# settings: "Settings" # Tooltip on settings button from /play -# next: "Next" # Go from choose hero to choose inventory before playing a level -# change_hero: "Change Hero" # Go back from choose inventory to choose hero -# choose_inventory: "Equip Items" -# older_campaigns: "Older Campaigns" -# anonymous: "Anonymous Player" + hours_played: "horas jogadas" # Hover over a level on /play + items: "Items" # Tooltip on item shop button from /play + heroes: "Heróis" # Tooltip on hero shop button from /play + achievements: "Conquistas" # Tooltip on achievement list button from /play + account: "Conta" # Tooltip on account button from /play + settings: "Configurações" # Tooltip on settings button from /play + next: "Próximo" # Go from choose hero to choose inventory before playing a level + change_hero: "Alterar Herói" # Go back from choose inventory to choose hero + choose_inventory: "Equipar Items" + older_campaigns: "Campanhas antigas" + anonymous: "Jogador Anônimo" level_difficulty: "Dificuldade: " campaign_beginner: "Campanha Iniciante" choose_your_level: "Escolha seu estágio" # The rest of this section is the old play view at /play-old and isn't very important. adventurer_prefix: "Você pode ir para qualquer um dos estágios abaixo, ou discutir sobre eles no " adventurer_forum: "Fórum do Aventureiro" adventurer_suffix: "." -# campaign_old_beginner: "Old Beginner Campaign" + campaign_old_beginner: "Campanha antiga para Iniciantes" campaign_beginner_description: "... na qual você aprenderá a magia da programação." campaign_dev: "Fases Difíceis Aleatórias" campaign_dev_description: "... nas quais você aprenderá a interface enquanto faz algo um pouco mais difícil." @@ -80,8 +80,8 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: campaign_multiplayer_description: "... nas quais você programará cara-a-cara contra outros jogadores." campaign_player_created: "Criados por Jogadores" campaign_player_created_description: "... nos quais você batalhará contra a criatividade dos seus companheiros feiticeiros Artesãos." -# campaign_classic_algorithms: "Classic Algorithms" -# campaign_classic_algorithms_description: "... in which you learn the most popular algorithms in Computer Science." + campaign_classic_algorithms: "Algoritmos Clássicos" + campaign_classic_algorithms_description: "...onde você aprende os algoritmos mais conhecidos em Ciência da Computação." login: sign_up: "Criar conta" From ee88c0870e0c808045409ad647e5848f6f11065c Mon Sep 17 00:00:00 2001 From: George Saines Date: Mon, 13 Oct 2014 16:24:54 -0700 Subject: [PATCH 04/15] pushing my fix --- app/lib/surface/Surface.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee index 72bbd3a68..617dbd279 100644 --- a/app/lib/surface/Surface.coffee +++ b/app/lib/surface/Surface.coffee @@ -52,7 +52,7 @@ module.exports = Surface = class Surface extends CocoClass coords: null # use world defaults, or set to false/true to override playJingle: false showInvisible: false - frameRate: 60 # Best as a divisor of 60, like 15, 30, 60, with RAF_SYNCHED timing. + frameRate: 30 # Best as a divisor of 60, like 15, 30, 60, with RAF_SYNCHED timing. subscriptions: 'level:disable-controls': 'onDisableControls' From 80537dfac7d65f25a3782d63594115ca4c0e81a7 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Mon, 13 Oct 2014 17:40:16 -0700 Subject: [PATCH 05/15] Experimented with triggering full-screen on first level start. --- app/views/kinds/CocoView.coffee | 26 +++++++++++++++++++++ app/views/kinds/RootView.coffee | 27 ---------------------- app/views/play/modal/PlayLevelModal.coffee | 6 +++++ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee index 524dd13d2..44f2cc082 100644 --- a/app/views/kinds/CocoView.coffee +++ b/app/views/kinds/CocoView.coffee @@ -405,6 +405,32 @@ module.exports = class CocoView extends Backbone.View slider.on('slidechange', changeCallback) slider + toggleFullscreen: (e) -> + # https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode?redirectlocale=en-US&redirectslug=Web/Guide/DOM/Using_full_screen_mode + # Whoa, even cooler: https://developer.mozilla.org/en-US/docs/WebAPI/Pointer_Lock + full = document.fullscreenElement or + document.mozFullScreenElement or + document.mozFullscreenElement or + document.webkitFullscreenElement or + document.msFullscreenElement + d = document.documentElement + if not full + req = d.requestFullScreen or + d.mozRequestFullScreen or + d.mozRequestFullscreen or + d.msRequestFullscreen or + (if d.webkitRequestFullscreen then -> d.webkitRequestFullscreen Element.ALLOW_KEYBOARD_INPUT else null) + req?.call d + Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'full-screen-start', volume: 1 if req + else + nah = document.exitFullscreen or + document.mozCancelFullScreen or + document.mozCancelFullscreen or + document.msExitFullscreen or + document.webkitExitFullscreen + nah?.call document + Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'full-screen-end', volume: 1 if nah + return mobileRELong = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i mobileREShort = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i diff --git a/app/views/kinds/RootView.coffee b/app/views/kinds/RootView.coffee index 07a0db486..4f443c83e 100644 --- a/app/views/kinds/RootView.coffee +++ b/app/views/kinds/RootView.coffee @@ -126,30 +126,3 @@ module.exports = class RootView extends CocoView console.warn 'Error saving language:', errors res.success (model, response, options) -> #console.log 'Saved language:', newLang - - toggleFullscreen: (e) -> - # https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode?redirectlocale=en-US&redirectslug=Web/Guide/DOM/Using_full_screen_mode - # Whoa, even cooler: https://developer.mozilla.org/en-US/docs/WebAPI/Pointer_Lock - full = document.fullscreenElement or - document.mozFullScreenElement or - document.mozFullscreenElement or - document.webkitFullscreenElement or - document.msFullscreenElement - d = document.documentElement - if not full - req = d.requestFullScreen or - d.mozRequestFullScreen or - d.mozRequestFullscreen or - d.msRequestFullscreen or - (if d.webkitRequestFullscreen then -> d.webkitRequestFullscreen Element.ALLOW_KEYBOARD_INPUT else null) - req?.call d - Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'full-screen-start', volume: 1 if req - else - nah = document.exitFullscreen or - document.mozCancelFullScreen or - document.mozCancelFullscreen or - document.msExitFullscreen or - document.webkitExitFullscreen - nah?.call document - Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'full-screen-end', volume: 1 if nah - return diff --git a/app/views/play/modal/PlayLevelModal.coffee b/app/views/play/modal/PlayLevelModal.coffee index ea11de1df..167b39c9f 100644 --- a/app/views/play/modal/PlayLevelModal.coffee +++ b/app/views/play/modal/PlayLevelModal.coffee @@ -6,6 +6,8 @@ PlayLevelView = require 'views/play/level/PlayLevelView' LadderView = require 'views/play/ladder/LadderView' LevelSession = require 'models/LevelSession' +hasGoneFullScreenOnce = false + module.exports = class PlayLevelModal extends ModalView className: 'modal fade play-modal' template: template @@ -103,6 +105,10 @@ module.exports = class PlayLevelModal extends ModalView onClickPlayLevel: (e) -> return if @$el.find('#play-level-button').prop 'disabled' @showLoading() + ua = navigator.userAgent.toLowerCase() + unless hasGoneFullScreenOnce or (/safari/.test(ua) and not /chrome/.test(ua)) + @toggleFullscreen() + hasGoneFullScreenOnce = true @updateConfig => @navigatingToPlay = true viewClass = if @options.levelPath is 'ladder' then LadderView else PlayLevelView From 14931100434d276021b0453b9148496e8e4e475b Mon Sep 17 00:00:00 2001 From: Gabriel Cesar Date: Tue, 14 Oct 2014 12:43:44 -0300 Subject: [PATCH 06/15] pt-BR.coffee updated. --- app/locale/pt-BR.coffee | 134 ++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee index 999311233..407e13abf 100644 --- a/app/locale/pt-BR.coffee +++ b/app/locale/pt-BR.coffee @@ -107,13 +107,13 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: send_password: "Recuperar senha" recovery_sent: "Email de recuperação enviado." -# items: -# armor: "Armor" -# hands: "Hands" -# accessories: "Accessories" -# books: "Books" -# minions: "Minions" -# misc: "Misc" + items: + armor: "Armadura" + hands: "Mãos" + accessories: "Accessórios" + books: "Livross" + minions: "Minions" + misc: "Diversos" common: loading: "Carregando..." @@ -128,8 +128,8 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: fork: "Fork" play: "Jogar" # When used as an action verb, like "Play next level" retry: "Tente novamente" -# watch: "Watch" -# unwatch: "Unwatch" + watch: "Observar" + unwatch: "Não Observar" submit_patch: "Enviar arranjo" general: @@ -182,15 +182,15 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: play_level: done: "Pronto" home: "Início" -# skip: "Skip" -# game_menu: "Game Menu" + skip: "Pular" + game_menu: "Menu do Jogo" guide: "Guia" restart: "Reiniciar" goals: "Objetivos" -# goal: "Goal" + goal: "Objetivo" success: "Sucesso!" incomplete: "Incompleto" -# timed_out: "Ran out of time" + timed_out: "Tempo esgotado" failing: "Falta" action_timeline: "Linha do Tempo das Ações" click_to_select: "Clique em um personagem para selecioná-lo." @@ -204,7 +204,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: victory_rate_the_level: "Avalie o estágio: " # Only in old-style levels. victory_return_to_ladder: "Retornar para a Ladder" victory_play_next_level: "Jogar o próximo estágio" # Only in old-style levels. -# victory_play_continue: "Continue" + victory_play_continue: "Continue" victory_go_home: "Ir à página inicial" # Only in old-style levels. victory_review: "Diga-nos mais!" # Only in old-style levels. victory_hour_of_code_done: "Terminou?" @@ -219,23 +219,23 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: # tome_cast_button_run: "Run" # tome_cast_button_running: "Running" # tome_cast_button_ran: "Ran" -# tome_submit_button: "Submit" + tome_submit_button: "Enviar" # tome_reload_method: "Reload original code for this method" # Title text for individual method reload button. -# tome_select_method: "Select a Method" + tome_select_method: "Selecione um Método" # tome_see_all_methods: "See all methods you can edit" # Title text for method list selector (shown when there are multiple programmable methdos). tome_select_a_thang: "Selecione alguém para " tome_available_spells: "Feitiços Disponíveis" -# tome_your_skills: "Your Skills" + tome_your_skills: "Suas habilidades" hud_continue: "Continue (tecle Shift+Space)" spell_saved: "Feitiço Salvo" skip_tutorial: "Pular (esc)" -# keyboard_shortcuts: "Key Shortcuts" + keyboard_shortcuts: "Teclas de atalho" loading_ready: "Pronto!" -# loading_start: "Start Level" -# time_current: "Now:" -# time_total: "Max:" -# time_goto: "Go to:" -# infinite_loop_try_again: "Try Again" + loading_start: "Iniciar fase" + time_current: "Agora:" + time_total: "Máximo:" + time_goto: "Ir para:" + infinite_loop_try_again: "Tentar novamente" # infinite_loop_reset_level: "Reset Level" # infinite_loop_comment_out: "Comment Out My Code" # tip_toggle_play: "Toggle play/paused with Ctrl+P." @@ -270,39 +270,39 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: customize_wizard: "Personalize o feiticeiro" game_menu: -# inventory_tab: "Inventory" -# choose_hero_tab: "Restart Level" -# save_load_tab: "Save/Load" -# options_tab: "Options" -# guide_tab: "Guide" + inventory_tab: "Inventário" + choose_hero_tab: "Reiniciar Nível" + save_load_tab: "Salvar/Carregar" + options_tab: "Opções" + guide_tab: "Guia" multiplayer_tab: "Multijogador" -# inventory_caption: "Equip your hero" + inventory_caption: "Equipar seu herói" # choose_hero_caption: "Choose hero, language" # save_load_caption: "... and view history" # options_caption: "Configure settings" -# guide_caption: "Docs and tips" + guide_caption: "Documentos e dicas" # multiplayer_caption: "Play with friends!" # inventory: # choose_inventory: "Equip Items" -# choose_hero: -# choose_hero: "Choose Your Hero" -# programming_language: "Programming Language" -# programming_language_description: "Which programming language do you want to use?" -# status: "Status" -# weapons: "Weapons" -# health: "Health" -# speed: "Speed" + choose_hero: + choose_hero: "Escolha seu Herói" + programming_language: "Linguagem de Programação" + programming_language_description: "Qual Linguagem de Programação você gostaria de usar?" + status: "Status" + weapons: "Armas" + health: "Vida" + speed: "Velocidade" -# save_load: -# granularity_saved_games: "Saved" -# granularity_change_history: "History" + save_load: + granularity_saved_games: "Salvo" + granularity_change_history: "Histórico" options: # general_options: "General Options" # Check out the Options tab in the Game Menu while playing a level -# volume_label: "Volume" -# music_label: "Music" + volume_label: "Volume" + music_label: "Música" # music_description: "Turn background music on/off." # autorun_label: "Autorun" # autorun_description: "Control automatic code execution." @@ -333,21 +333,21 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: why_paragraph_2_italic_caps: "NÃO MÃE EU PRECISO TERMINAR ESSE NÍVEL!" why_paragraph_2_suffix: "É por isso que o CodeCombat é um jogo multijogador, não uma aula que imita um jogo. Nós não iremos parar até você não conseguir parar--mas agora, isso é uma coisa boa." why_paragraph_3: "Se você vai se viciar em algum jogo, fique viciado nesse e se torne um dos magos da era da tecnologia." -# press_title: "Bloggers/Press" -# press_paragraph_1_prefix: "Want to write about us? Feel free to download and use all of the resources included in our" -# press_paragraph_1_link: "press packet" -# press_paragraph_1_suffix: ". All logos and images may be used without contacting us directly." -# team: "Team" -# george_title: "CEO" -# george_blurb: "Businesser" -# scott_title: "Programmer" -# scott_blurb: "Reasonable One" -# nick_title: "Programmer" -# nick_blurb: "Motivation Guru" -# michael_title: "Programmer" -# michael_blurb: "Sys Admin" -# matt_title: "Programmer" -# matt_blurb: "Bicyclist" + press_title: "Bloggers/Imprensa" + press_paragraph_1_prefix: "Quer escrever sobre nós? Fique à vontade para baixar e usar todos recursos inclusos em nosso" + press_paragraph_1_link: "Midia Kit" + press_paragraph_1_suffix: ". Todas as logomarcas e imagens podem ser usadas sem nos contactar previamente." + team: "Time" + george_title: "CEO" + george_blurb: "Administrador" # Businesser + scott_title: "Programador" + scott_blurb: "O Sensato" + nick_title: "Programador" + nick_blurb: "Guru Motivacional" + michael_title: "Programador" + michael_blurb: "Administrador de Sistemas" + matt_title: "PProgramador" + matt_blurb: "O Ciclista" versions: save_version_title: "Salvar nova versão" @@ -410,12 +410,12 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: wizard_tab: "Feiticeiro" wizard_color: "Cor das Roupas do Feiticeiro" -# keyboard_shortcuts: -# keyboard_shortcuts: "Keyboard Shortcuts" -# space: "Space" -# enter: "Enter" -# escape: "Escape" -# shift: "Shift" + keyboard_shortcuts: + keyboard_shortcuts: "Atalhos do Teclado" + space: "Espaço" + enter: "Enter" + escape: "Esc" + shift: "Shift" # cast_spell: "Cast current spell." # run_real_time: "Run in real time." # continue_script: "Continue past current script." @@ -443,8 +443,8 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: # find_us: "Find us on these sites" # social_blog: "Read the CodeCombat blog on Sett" # social_discource: "Join the discussion on our Discourse forum" -# social_facebook: "Like CodeCombat on Facebook" -# social_twitter: "Follow CodeCombat on Twitter" + social_facebook: "Curta o CodeCombat no Facebook" + social_twitter: "Siga o CodeCombat no Twitter" # social_gplus: "Join CodeCombat on Google+" # social_hipchat: "Chat with us in the public CodeCombat HipChat room" contribute_to_the_project: "Contribuir para o projeto" @@ -472,7 +472,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription: back: "Voltar" revert: "Reverter" revert_models: "Reverter Modelos" -# pick_a_terrain: "Pick A Terrain" + pick_a_terrain: "Escolha um Terreno" small: "Pequeno" # grassy: "Grassy" # fork_title: "Fork New Version" From d79d40b98c7afe872b1dfd2fc3d4ed87927ce7b4 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 14 Oct 2014 09:54:18 -0700 Subject: [PATCH 07/15] Moved spellbooks to right hand. Put full-body hero feature images in. Saved some height on ChooseHeroView and InventoryView for smaller screens. Hid level play counts unless admin. --- app/locale/en.coffee | 1 - app/schemas/models/thang_type.coffee | 1 + app/styles/game-menu/choose-hero-view.sass | 15 ++++++--- app/styles/game-menu/inventory-view.sass | 31 +++++++++---------- app/styles/play/modal/play-level-modal.sass | 2 +- app/templates/game-menu/choose-hero-view.jade | 2 ++ app/templates/game-menu/inventory-view.jade | 25 ++++++++------- app/views/game-menu/ChooseHeroView.coffee | 9 ++++-- app/views/game-menu/InventoryView.coffee | 8 +++-- app/views/play/WorldMapView.coffee | 1 + app/views/play/modal/PlayItemsModal.coffee | 3 +- .../levels/thangs/thang_type_handler.coffee | 1 + 12 files changed, 60 insertions(+), 39 deletions(-) diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 402b5f385..f2c9f83a7 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -111,7 +111,6 @@ armor: "Armor" hands: "Hands" accessories: "Accessories" - books: "Books" minions: "Minions" misc: "Misc" diff --git a/app/schemas/models/thang_type.coffee b/app/schemas/models/thang_type.coffee index 9a7ebcac3..7b7c48ee1 100644 --- a/app/schemas/models/thang_type.coffee +++ b/app/schemas/models/thang_type.coffee @@ -127,6 +127,7 @@ _.extend ThangTypeSchema.properties, positions: PositionsSchema raster: {type: 'string', format: 'image-file', title: 'Raster Image'} rasterIcon: { type: 'string', format: 'image-file', title: 'Raster Image Icon' } + featureImage: { type: 'string', format: 'image-file', title: 'Feature Image' } colorGroups: c.object title: 'Color Groups' additionalProperties: diff --git a/app/styles/game-menu/choose-hero-view.sass b/app/styles/game-menu/choose-hero-view.sass index 49c0fb2bf..79fbd4349 100644 --- a/app/styles/game-menu/choose-hero-view.sass +++ b/app/styles/game-menu/choose-hero-view.sass @@ -4,7 +4,7 @@ $maxHeroPortraitSize: 100px $minHeroPortraitSize: 50px -$heroCanvasHeight: 330px +$heroCanvasHeight: 265px #choose-hero-view @@ -62,13 +62,20 @@ $heroCanvasHeight: 330px &.locked @include opacity(0.6) - canvas, .hero-stats + canvas, .hero-feature-image, .hero-stats width: 45% height: $heroCanvasHeight float: left - canvas + canvas, .hero-feature-image margin-left: 5% + + .hero-feature-image + display: none + text-align: center + + img + height: $heroCanvasHeight .hero-stats text-shadow: 0 1px 1px rgba(255, 255, 255, 0.6) @@ -84,7 +91,7 @@ $heroCanvasHeight: 330px .carousel-control height: 75% - top: 25% + top: 30% width: 10% .select-group diff --git a/app/styles/game-menu/inventory-view.sass b/app/styles/game-menu/inventory-view.sass index ea41db65a..c58051fd8 100644 --- a/app/styles/game-menu/inventory-view.sass +++ b/app/styles/game-menu/inventory-view.sass @@ -1,17 +1,15 @@ @import "app/styles/mixins" $totalWidth: 706px - 2 * 20px -// We get 666px to play with from our parent modals. -$inventoryHeight: 530px +$inventoryHeight: 445px $equippedWidth: 450px $itemSlotMargin: 5px $itemSlotSize: ($equippedWidth - 6 * 2 * $itemSlotMargin) / 6 $itemSlotSizeWithMargin: $itemSlotSize + 2 * $itemSlotMargin $itemSlotBorderWidth: 2px $itemSlotInnerWidth: $itemSlotSize - 2 * $itemSlotBorderWidth -$heroContainerBottomMargin: 10px $heroContainerWidth: 4 * $itemSlotSizeWithMargin -$heroContainerHeight: $inventoryHeight - 2 * $itemSlotSizeWithMargin - $heroContainerBottomMargin +$heroContainerHeight: $inventoryHeight - $itemSlotSizeWithMargin $selectedAreaHeight: 150px $stashMargin: 20px $stashWidth: $totalWidth - $equippedWidth - $stashMargin @@ -50,9 +48,9 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin .item-slot-column //background-color: rgba(112, 124, 35, 0.5) width: $itemSlotSizeWithMargin - height: 4 * $itemSlotSizeWithMargin + height: 5 * $itemSlotSizeWithMargin float: left - margin-top: 30px + //margin-top: 30px .item-slot width: $itemSlotSize @@ -93,11 +91,12 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin background-position: (-1 * $itemSlotInnerWidth) 0px &[data-slot="programming-book"] .placeholder - background-position: (-2 * $itemSlotInnerWidth) 0px - - &[data-slot="spellbook"] .placeholder background-position: (-3 * $itemSlotInnerWidth) 0px + // Only for wizards... + //&[data-slot="spellbook"] .placeholder + // background-position: (-2 * $itemSlotInnerWidth) 0px + &[data-slot="misc-0"] .placeholder background-position: (-4 * $itemSlotInnerWidth) 0px @@ -163,15 +162,15 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin float: left position: relative - .equipped-hero-canvas + .equipped-hero-canvas, .hero-feature-image width: $heroContainerWidth height: $heroContainerHeight - hr.slot-row-separator - clear: both - margin-top: 0 - margin-bottom: $heroContainerBottomMargin / 2 - 1 - border-top: 1px solid #aaa + .hero-feature-image + text-align: center + + img + height: $heroContainerHeight #available-equipment width: $stashWidth @@ -236,7 +235,7 @@ $stashWidth: $totalWidth - $equippedWidth - $stashMargin position: absolute top: $selectedItemsContainerMargin right: $selectedItemsContainerMargin - bottom: $selectedItemsContainerMargin + $heroContainerBottomMargin + bottom: $selectedItemsContainerMargin left: $selectedItemsContainerMargin text-align: center diff --git a/app/styles/play/modal/play-level-modal.sass b/app/styles/play/modal/play-level-modal.sass index 058eb85a8..7b3cf3e5a 100644 --- a/app/styles/play/modal/play-level-modal.sass +++ b/app/styles/play/modal/play-level-modal.sass @@ -9,4 +9,4 @@ .modal-body width: 726px - 20px - height: 550px + height: 435px diff --git a/app/templates/game-menu/choose-hero-view.jade b/app/templates/game-menu/choose-hero-view.jade index 829b9ab27..131023084 100644 --- a/app/templates/game-menu/choose-hero-view.jade +++ b/app/templates/game-menu/choose-hero-view.jade @@ -12,6 +12,8 @@ - var info = heroInfo[hero.get('slug')] div(class="item hero-item" + (hero.locked ? " locked" : ""), data-hero-id=hero.get('original')) canvas.hero-canvas + .hero-feature-image + img .hero-stats h2= info.fullName p diff --git a/app/templates/game-menu/inventory-view.jade b/app/templates/game-menu/inventory-view.jade index 0966ac135..8712bcd2f 100644 --- a/app/templates/game-menu/inventory-view.jade +++ b/app/templates/game-menu/inventory-view.jade @@ -8,7 +8,7 @@ .replace-me(data-item-id=equipment[slot].get('original')) .item-slot-column.pull-left - for slot in ['minion', 'torso', 'gloves', 'left-hand'] + for slot in ['minion', 'torso', 'gloves', 'left-hand', 'misc-0'] .item-slot(data-slot=slot) .placeholder .item-container @@ -17,6 +17,8 @@ .hero-container canvas.equipped-hero-canvas + .hero-feature-image + img #selected-items #selected-equipped-item.well h3(data-i18n="inventory.equipped") Equipped @@ -26,22 +28,23 @@ .item-view-stub .item-slot-column.pull-right - for slot in ['pet', 'waist', 'feet', 'right-hand'] + for slot in ['pet', 'waist', 'feet', 'right-hand', 'programming-book'] .item-slot(data-slot=slot) .placeholder .item-container if equipment[slot] .replace-me(data-item-id=equipment[slot].get('original')) - hr.slot-row-separator - - .item-slot-row.row-4 - for slot in ['programming-book', 'spellbook', 'misc-0', 'misc-1'] - .item-slot(data-slot=slot) - .placeholder - .item-container - if equipment[slot] - .replace-me(data-item-id=equipment[slot].get('original')) + // TODO: work in misc 1 again + //hr.slot-row-separator + // + //.item-slot-row.row-4 + // for slot in ['misc-1'] + // .item-slot(data-slot=slot) + // .placeholder + // .item-container + // if equipment[slot] + // .replace-me(data-item-id=equipment[slot].get('original')) #available-equipment h4#unlocked-description diff --git a/app/views/game-menu/ChooseHeroView.coffee b/app/views/game-menu/ChooseHeroView.coffee index 9903c00f1..07a1988e6 100644 --- a/app/views/game-menu/ChooseHeroView.coffee +++ b/app/views/game-menu/ChooseHeroView.coffee @@ -23,7 +23,7 @@ module.exports = class ChooseHeroView extends CocoView constructor: (options) -> super options @heroes = new CocoCollection([], {model: ThangType}) - @heroes.url = '/db/thang.type?view=heroes&project=original,name,slug,soundTriggers' + @heroes.url = '/db/thang.type?view=heroes&project=original,name,slug,soundTriggers,featureImage' @supermodel.loadCollection(@heroes, 'heroes') @stages = {} @@ -100,6 +100,11 @@ module.exports = class ChooseHeroView extends CocoView loadHero: (hero, heroIndex, preloading=false) -> createjs.Ticker.removeEventListener 'tick', stage for stage in _.values @stages + if featureImage = hero.get 'featureImage' + $(".hero-item[data-hero-id='#{hero.get('original')}'] canvas").hide() + $(".hero-item[data-hero-id='#{hero.get('original')}'] .hero-feature-image").show().find('img').prop('src', '/file/' + featureImage) + @playSelectionSound hero unless preloading + return hero createjs.Ticker.setFPS 30 # In case we paused it from being inactive somewhere else if stage = @stages[heroIndex] unless preloading @@ -109,7 +114,7 @@ module.exports = class ChooseHeroView extends CocoView fullHero = @getFullHero hero.get 'original' onLoaded = => return unless canvas = $(".hero-item[data-hero-id='#{fullHero.get('original')}'] canvas") - canvas.prop width: @canvasWidth, height: @canvasHeight + canvas.show().prop width: @canvasWidth, height: @canvasHeight builder = new SpriteBuilder(fullHero) movieClip = builder.buildMovieClip(fullHero.get('actions').attack?.animation ? fullHero.get('actions').idle.animation) movieClip.scaleX = movieClip.scaleY = canvas.prop('height') / 120 # Average hero height is ~110px tall at normal resolution diff --git a/app/views/game-menu/InventoryView.coffee b/app/views/game-menu/InventoryView.coffee index 649253ea5..26844244f 100644 --- a/app/views/game-menu/InventoryView.coffee +++ b/app/views/game-menu/InventoryView.coffee @@ -10,7 +10,7 @@ module.exports = class InventoryView extends CocoView id: 'inventory-view' className: 'tab-pane' template: template - slots: ['head', 'eyes', 'neck', 'torso', 'wrists', 'gloves', 'left-ring', 'right-ring', 'right-hand', 'left-hand', 'waist', 'feet', 'spellbook', 'programming-book', 'pet', 'minion', 'misc-0', 'misc-1', 'misc-2', 'misc-3', 'misc-4'] + slots: ['head', 'eyes', 'neck', 'torso', 'wrists', 'gloves', 'left-ring', 'right-ring', 'right-hand', 'left-hand', 'waist', 'feet', 'programming-book', 'pet', 'minion', 'misc-0', 'misc-1'] events: 'click .item-slot': 'onItemSlotClick' @@ -379,12 +379,16 @@ module.exports = class InventoryView extends CocoView return unless @supermodel.finished() and @selectedHero and not @$el.hasClass 'secret' @startedLoadingFirstHero = true @stage?.removeAllChildren() + if featureImage = @selectedHero.get 'featureImage' + @$el.find(".equipped-hero-canvas").hide() + @$el.find(".hero-feature-image").show().find('img').prop('src', '/file/' + featureImage) + return if @selectedHero.loaded and movieClip = @movieClips?[@selectedHero.get('original')] @stage.addChild(movieClip) @stage.update() return onLoaded = => - return unless canvas = $(".equipped-hero-canvas") + return unless canvas = @$el.find(".equipped-hero-canvas") @canvasWidth ||= canvas.width() @canvasHeight ||= canvas.height() canvas.prop width: @canvasWidth, height: @canvasHeight diff --git a/app/views/play/WorldMapView.coffee b/app/views/play/WorldMapView.coffee index 7b63c53e9..eea4fa639 100644 --- a/app/views/play/WorldMapView.coffee +++ b/app/views/play/WorldMapView.coffee @@ -48,6 +48,7 @@ module.exports = class WorldMapView extends RootView super() getLevelPlayCounts: -> + return unless me.isAdmin() success = (levelPlayCounts) => return if @destroyed for level in levelPlayCounts diff --git a/app/views/play/modal/PlayItemsModal.coffee b/app/views/play/modal/PlayItemsModal.coffee index 816923dca..e5a0d6e0d 100644 --- a/app/views/play/modal/PlayItemsModal.coffee +++ b/app/views/play/modal/PlayItemsModal.coffee @@ -14,9 +14,8 @@ module.exports = class PlayItemsModal extends ModalView armor: ['torso', 'head', 'gloves', 'feet'] hands: ['right-hand', 'left-hand'] accessories: ['eyes', 'neck', 'left-ring', 'right-ring', 'waist'] - books: ['programming-book', 'spellbook'] minions: ['minion', 'pet'] - misc: ['misc-0', 'misc-1', 'misc-2', 'misc-3', 'misc-4'] + misc: ['programming-book', 'misc-0', 'misc-1'] #events: # 'change input.select': 'onSelectionChanged' diff --git a/server/levels/thangs/thang_type_handler.coffee b/server/levels/thangs/thang_type_handler.coffee index a0c323ac8..7fa07c491 100644 --- a/server/levels/thangs/thang_type_handler.coffee +++ b/server/levels/thangs/thang_type_handler.coffee @@ -33,6 +33,7 @@ ThangTypeHandler = class ThangTypeHandler extends Handler 'kind' 'raster' 'rasterIcon' + 'featureImage' 'spriteType' ] From b7fe9398d5893f11d49882e1c4e752c7fdefccce Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 14 Oct 2014 10:39:13 -0700 Subject: [PATCH 08/15] Don't preload when player hasn't finished typing this or self. --- app/views/play/level/tome/SpellView.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/play/level/tome/SpellView.coffee b/app/views/play/level/tome/SpellView.coffee index 8b6bccb98..09ebfbabd 100644 --- a/app/views/play/level/tome/SpellView.coffee +++ b/app/views/play/level/tome/SpellView.coffee @@ -476,8 +476,9 @@ module.exports = class SpellView extends CocoView currentLine = _.string.rtrim(@aceDoc.$lines[cursorPosition.row].replace(/[ \t]*\/\/[^"']*/g, '')) # trim // unless inside " endOfLine = cursorPosition.column >= currentLine.length # just typed a semicolon or brace, for example beginningOfLine = not currentLine.substr(0, cursorPosition.column).trim().length # uncommenting code, for example + incompleteThis = /^(s|se|sel|self|t|th|thi|this)$/.test currentLine.trim() #console.log 'finished?', valid, endOfLine, beginningOfLine, cursorPosition, currentLine.length, aether, new Date() - 0, currentLine - if valid and (endOfLine or beginningOfLine) + if valid and (endOfLine or beginningOfLine) and not incompleteThis if @autocastDelay > 60000 @preload() else From ee9e32af511a8e4944a70328f239d8110b03e42b Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 14 Oct 2014 11:11:56 -0700 Subject: [PATCH 09/15] Hid play/pause button for first few levels. Hid submit button until run once or won for a few more levels. --- app/schemas/models/level.coffee | 2 +- app/views/play/level/LevelPlaybackView.coffee | 1 + app/views/play/level/PlayLevelView.coffee | 2 +- .../play/level/modal/HeroVictoryModal.coffee | 19 ++++++++++--------- .../play/level/tome/CastButtonView.coffee | 6 +++--- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee index 9e1577b22..ecff5395a 100644 --- a/app/schemas/models/level.coffee +++ b/app/schemas/models/level.coffee @@ -74,7 +74,7 @@ PointSchema = c.object {title: 'Point', description: 'An {x, y} coordinate point x: {title: 'x', description: 'The x coordinate.', type: 'number'} y: {title: 'y', description: 'The y coordinate.', type: 'number'} -SpriteCommandSchema = c.object {title: 'Thang Command', description: 'Make a target Thang move or say something, or select/deselect it.', required: ['id'], default: {id: 'Captain Anya'}}, +SpriteCommandSchema = c.object {title: 'Thang Command', description: 'Make a target Thang move or say something, or select/deselect it.', required: ['id'], default: {id: 'Hero Placeholder'}}, id: thang select: {title: 'Select', description: 'Select or deselect this Thang.', type: 'boolean'} say: c.object {title: 'Say', description: 'Make this Thang say a message.', required: ['text'], default: { mood: 'explain' }}, diff --git a/app/views/play/level/LevelPlaybackView.coffee b/app/views/play/level/LevelPlaybackView.coffee index 4e1b5b55f..b01b7081c 100644 --- a/app/views/play/level/LevelPlaybackView.coffee +++ b/app/views/play/level/LevelPlaybackView.coffee @@ -124,6 +124,7 @@ module.exports = class LevelPlaybackView extends CocoView @goto = t 'play_level.time_goto' @current = t 'play_level.time_current' @total = t 'play_level.time_total' + @$el.find('#play-button').css('visibility', 'hidden') if @options.levelID in ['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'true-names'] # Don't show for first few levels, confuses new players. updatePopupContent: -> @timePopup?.updateContent "

#{@timeToString @newTime}

#{@formatTime(@current, @currentTime)}
#{@formatTime(@total, @totalTime)}" diff --git a/app/views/play/level/PlayLevelView.coffee b/app/views/play/level/PlayLevelView.coffee index d5c47d9bb..14e10428f 100644 --- a/app/views/play/level/PlayLevelView.coffee +++ b/app/views/play/level/PlayLevelView.coffee @@ -268,7 +268,7 @@ module.exports = class PlayLevelView extends RootView insertSubviews: -> @insertSubView @tome = new TomeView levelID: @levelID, session: @session, otherSession: @otherSession, thangs: @world.thangs, supermodel: @supermodel, level: @level - @insertSubView new LevelPlaybackView session: @session + @insertSubView new LevelPlaybackView session: @session, levelID: @levelID @insertSubView new GoalsView {} @insertSubView new LevelFlagsView world: @world if @levelID is 'sky-span' # TODO: figure out when flags are available @insertSubView new GoldView {} diff --git a/app/views/play/level/modal/HeroVictoryModal.coffee b/app/views/play/level/modal/HeroVictoryModal.coffee index 08f8164f6..5f4fe7d83 100644 --- a/app/views/play/level/modal/HeroVictoryModal.coffee +++ b/app/views/play/level/modal/HeroVictoryModal.coffee @@ -11,6 +11,7 @@ module.exports = class HeroVictoryModal extends ModalView id: 'hero-victory-modal' template: template closeButton: false + closesOnClickOutside: false constructor: (options) -> super(options) @@ -24,7 +25,7 @@ module.exports = class HeroVictoryModal extends ModalView @achievements = @supermodel.loadCollection(achievements, 'achievements').model @listenToOnce @achievements, 'sync', @onAchievementsLoaded @readyToContinue = false - + onAchievementsLoaded: -> thangTypeOriginals = [] achievementIDs = [] @@ -34,7 +35,7 @@ module.exports = class HeroVictoryModal extends ModalView thangTypeOriginals.push rewards.items or [] achievement.completed = LocalMongo.matchesQuery(@session.attributes, achievement.get('query')) achievementIDs.push(achievement.id) if achievement.completed - + thangTypeOriginals = _.uniq _.flatten thangTypeOriginals for thangTypeOriginal in thangTypeOriginals thangType = new ThangType() @@ -61,7 +62,7 @@ module.exports = class HeroVictoryModal extends ModalView me.fetch() unless me.loading else @readyToContinue = true - + getRenderData: -> c = super() c.levelName = utils.i18n @level.attributes, 'name' @@ -81,7 +82,7 @@ module.exports = class HeroVictoryModal extends ModalView c.thangTypes = @thangTypes return c - + afterRender: -> super() return unless @supermodel.finished() @@ -105,8 +106,8 @@ module.exports = class HeroVictoryModal extends ModalView ) panel.delay(500) panel.queue(-> complete()) - @animationComplete = !@animatedPanels.length - + @animationComplete = not @animatedPanels.length + beginAnimateNumbers: -> @numericalItemPanels = _.map(@animatedPanels.find('.numerical'), (panel) -> { number: $(panel).data('number') @@ -114,7 +115,7 @@ module.exports = class HeroVictoryModal extends ModalView rootEl: $(panel) unit: $(panel).data('number-unit') }) - + # TODO: mess with this more later. Doesn't seem to work, often times will pulse background red rather than animate # itemPanel.rootEl.find('.reward-image-container img').addClass('pulse') for itemPanel in @numericalItemPanels @numberAnimationStart = new Date() @@ -125,7 +126,7 @@ module.exports = class HeroVictoryModal extends ModalView @gemEl = $('#gem-total') @XPEl = $('#xp-total') @numberAnimationInterval = setInterval(@tickNumberAnimation, 15 / 1000) - + tickNumberAnimation: => pct = Math.min(1, (new Date() - @numberAnimationStart) / 1500) panel.textEl.text('+'+parseInt(panel.number*pct)) for panel in @numericalItemPanels @@ -142,4 +143,4 @@ module.exports = class HeroVictoryModal extends ModalView updateSavingProgressStatus: -> return unless @animationComplete @$el.find('#saving-progress-label').toggleClass('hide', @readyToContinue) - @$el.find('#continue-button').toggleClass('hide', !@readyToContinue) \ No newline at end of file + @$el.find('#continue-button').toggleClass('hide', not @readyToContinue) diff --git a/app/views/play/level/tome/CastButtonView.coffee b/app/views/play/level/tome/CastButtonView.coffee index 650fb801f..7aa1df84d 100644 --- a/app/views/play/level/tome/CastButtonView.coffee +++ b/app/views/play/level/tome/CastButtonView.coffee @@ -42,7 +42,7 @@ module.exports = class CastButtonView extends CocoView #delay = me.get('autocastDelay') # No more autocast delay = 90019001 @setAutocastDelay delay - @$el.find('.submit-button').hide() if @options.levelID is 'dungeons-of-kithgard' + @$el.find('.submit-button').hide() if @options.levelID in ['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'true-names'] attachTo: (spellView) -> @$el.detach().prependTo(spellView.toolbarView.$el).show() @@ -83,7 +83,7 @@ module.exports = class CastButtonView extends CocoView onNewGoalStates: (e) -> @winnable = e.overallStatus is 'success' @$el.toggleClass 'winnable', @winnable - if @winnable + if @winnable or (@hasCastOnce and @options.levelID isnt 'dungeons-of-kithgard') # Show once 1) we think they will win or 2) they have hit “run” once. (Only #1 on the fist level.) @$el.find('.submit-button').show() # In case we hid it, like on the first level. onGoalsCalculated: (e) -> @@ -104,7 +104,7 @@ module.exports = class CastButtonView extends CocoView else if castable s = $.i18n.t('play_level.tome_cast_button_run') s = $.i18n.t('play_level.tome_cast_button_casting') if s is 'Run' and me.get('preferredLanguage').split('-')[0] isnt 'en' # Temporary, if tome_cast_button_running isn't translated. - unless @options.levelID in ['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'true-names'] # Hide for first few. + unless @options.levelID in ['dungeons-of-kithgard', 'gems-in-the-deep', 'shadow-guard', 'true-names', 'the-raised-sword', 'the-first-kithmaze'] # Hide for first few. s += ' ' + @castShortcut else s = $.i18n.t('play_level.tome_cast_button_ran') From 04ec8c5222111fb58d48cbb7c92fa307f385073d Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 14 Oct 2014 11:53:32 -0700 Subject: [PATCH 10/15] Sped up maze levels. Fixed an unhinged world deserialization listener. --- app/lib/Angel.coffee | 2 +- app/lib/world/world.coffee | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/lib/Angel.coffee b/app/lib/Angel.coffee index c2286bd0b..c19104a05 100644 --- a/app/lib/Angel.coffee +++ b/app/lib/Angel.coffee @@ -124,7 +124,7 @@ module.exports = class Angel extends CocoClass @shared.lastSerializedWorldFrames = serialized.frames finishBeholdingWorld: (goalStates) -> (world) => - return if @aborting + return if @aborting or @destroyed finished = world.frames.length is world.totalFrames firstChangedFrame = world.findFirstChangedFrame @shared.world eventType = if finished then 'god:new-world-created' else 'god:streaming-world-updated' diff --git a/app/lib/world/world.coffee b/app/lib/world/world.coffee index 90d1bd3fa..523f706e4 100644 --- a/app/lib/world/world.coffee +++ b/app/lib/world/world.coffee @@ -100,6 +100,8 @@ module.exports = class World @loadFrames(loadedCallback, errorCallback, loadProgressCallback, preloadedCallback, skipDeferredLoading, loadUntilFrame) unless @destroyed if @realTime and not @countdownFinished if @levelID in ['the-first-kithmaze', 'the-second-kithmaze', 'the-final-kithmaze'] + @realTimeSpeedFactor = 5 + else if @levelID in ['kithgard-gates'] @realTimeSpeedFactor = 3 else @realTimeSpeedFactor = 1 From ce14f929796b57f1d79f5bf7c61bc82b2a87d297 Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Tue, 14 Oct 2014 14:02:31 -0700 Subject: [PATCH 11/15] Pass problem context to Aether So Aether can craft better error messages. Bumping Aether to v0.2.39 --- app/lib/aether_utils.coffee | 1 + app/views/play/level/tome/Spell.coffee | 32 +++++++++++++++++++++++++- bower.json | 2 +- package.json | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/app/lib/aether_utils.coffee b/app/lib/aether_utils.coffee index 859926b92..ebc200ae2 100644 --- a/app/lib/aether_utils.coffee +++ b/app/lib/aether_utils.coffee @@ -20,6 +20,7 @@ module.exports.createAetherOptions = (options) -> jshint_E043: {level: 'ignore'} # https://github.com/codecombat/codecombat/issues/813 -- since we can't actually tell JSHint to really ignore things jshint_Unknown: {level: 'ignore'} # E043 also triggers Unknown, so ignore that, too aether_MissingThis: {level: 'error'} + problemContext: options.problemContext #functionParameters: # TODOOOOO executionLimit: 1 * 1000 * 1000 language: options.codeLanguage diff --git a/app/views/play/level/tome/Spell.coffee b/app/views/play/level/tome/Spell.coffee index 20d05bf93..6a86c0551 100644 --- a/app/views/play/level/tome/Spell.coffee +++ b/app/views/play/level/tome/Spell.coffee @@ -132,7 +132,8 @@ module.exports = class Spell aceConfig = me.get('aceConfig') ? {} writable = @permissions.readwrite.length > 0 skipProtectAPI = @skipProtectAPI or not writable - aetherOptions = createAetherOptions functionName: @name, codeLanguage: @language, functionParameters: @parameters, skipProtectAPI: skipProtectAPI, includeFlow: @levelType is 'hero' + problemContext = @createProblemContext thang + aetherOptions = createAetherOptions functionName: @name, codeLanguage: @language, functionParameters: @parameters, skipProtectAPI: skipProtectAPI, includeFlow: @levelType is 'hero', problemContext: problemContext aether = new Aether aetherOptions if @worker workerMessage = @@ -181,3 +182,32 @@ module.exports = class Spell @updateLanguageAether e.codeLanguage else console.error 'Spell onNewOpponentCode did not receive code', e + + createProblemContext: (thang) -> + # Create problemContext Aether can use to craft better error messages + # stringReferences: values that should be referred to as a string instead of a variable (e.g. "Brak", not Brak) + # thisMethods: methods available on the 'this' object + # thisProperties: properties available on the 'this' object + + # NOTE: Assuming the first createProblemContext call has everything we need, and we'll use that forevermore + return @problemContext if @problemContext? + + @problemContext = { stringReferences: [], thisMethods: [], thisProperties: [] } + return @problemContext unless thang? + + # Populate stringReferences + for key, value of thang.world?.thangMap + if (value.isAttackable or value.isSelectable) and value.id not in @problemContext.stringReferences + @problemContext.stringReferences.push value.id + + # Populate thisMethods and thisProperties + if thang.programmableProperties? + for prop in thang.programmableProperties + if _.isFunction(thang[prop]) + @problemContext.thisMethods.push prop + else + @problemContext.thisProperties.push prop + + # TODO: See SpellPaletteView.createPalette() for other interesting contextual properties + + @problemContext diff --git a/bower.json b/bower.json index df4a10cf8..5cea9f10b 100644 --- a/bower.json +++ b/bower.json @@ -32,7 +32,7 @@ "firepad": "~0.1.2", "marked": "~0.3.0", "moment": "~2.5.0", - "aether": "~0.2.32", + "aether": "~0.2.39", "underscore.string": "~2.3.3", "firebase": "~1.0.2", "catiline": "~2.9.3", diff --git a/package.json b/package.json index 8f49ed57e..68e029742 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "redis": "", "webworker-threads": "~0.4.11", "node-gyp": "~0.13.0", - "aether": "~0.2.32", + "aether": "~0.2.39", "JASON": "~0.1.3", "JQDeferred": "~2.1.0" }, From 7cbb5ac45daba4f8aa398aa7596ff337b077d98f Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Tue, 14 Oct 2014 17:53:17 -0700 Subject: [PATCH 12/15] Pass common 'this' methods to Aether --- app/views/play/level/tome/Spell.coffee | 3 +++ app/views/play/level/tome/SpellView.coffee | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/play/level/tome/Spell.coffee b/app/views/play/level/tome/Spell.coffee index 6a86c0551..5335e3645 100644 --- a/app/views/play/level/tome/Spell.coffee +++ b/app/views/play/level/tome/Spell.coffee @@ -188,11 +188,14 @@ module.exports = class Spell # stringReferences: values that should be referred to as a string instead of a variable (e.g. "Brak", not Brak) # thisMethods: methods available on the 'this' object # thisProperties: properties available on the 'this' object + # commonThisMethods: methods that are available sometimes, but not awlays # NOTE: Assuming the first createProblemContext call has everything we need, and we'll use that forevermore return @problemContext if @problemContext? @problemContext = { stringReferences: [], thisMethods: [], thisProperties: [] } + # TODO: These should be read from the database + @problemContext.commonThisMethods = ['moveRight', 'moveLeft', 'moveUp', 'moveDown', 'attackNearbyEnemy', 'say', 'move', 'attackNearestEnemy', 'shootAt', 'rotateTo', 'shoot', 'distance', 'getNearestEnemy', 'getEnemies', 'attack', 'setAction', 'setTarget', 'getFriends', 'patrol'] return @problemContext unless thang? # Populate stringReferences diff --git a/app/views/play/level/tome/SpellView.coffee b/app/views/play/level/tome/SpellView.coffee index 09ebfbabd..69699f249 100644 --- a/app/views/play/level/tome/SpellView.coffee +++ b/app/views/play/level/tome/SpellView.coffee @@ -477,7 +477,7 @@ module.exports = class SpellView extends CocoView endOfLine = cursorPosition.column >= currentLine.length # just typed a semicolon or brace, for example beginningOfLine = not currentLine.substr(0, cursorPosition.column).trim().length # uncommenting code, for example incompleteThis = /^(s|se|sel|self|t|th|thi|this)$/.test currentLine.trim() - #console.log 'finished?', valid, endOfLine, beginningOfLine, cursorPosition, currentLine.length, aether, new Date() - 0, currentLine + # console.log "finished=#{valid and (endOfLine or beginningOfLine) and not incompleteThis}", valid, endOfLine, beginningOfLine, incompleteThis, cursorPosition, currentLine.length, aether, new Date() - 0, currentLine if valid and (endOfLine or beginningOfLine) and not incompleteThis if @autocastDelay > 60000 @preload() From 5c40f99d997331d4adac4fd87077c4f16d11f13b Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Tue, 14 Oct 2014 22:38:22 -0700 Subject: [PATCH 13/15] Hide guide and select-a-thang message when not needed. Updated commonThisMethods. Restricted script IDs a bit. --- app/schemas/models/level.coffee | 2 +- app/templates/play/level/control_bar.jade | 3 ++- app/views/play/level/ControlBarView.coffee | 2 ++ app/views/play/level/LevelHUDView.coffee | 3 ++- app/views/play/level/PlayLevelView.coffee | 2 +- app/views/play/level/tome/Spell.coffee | 4 ++-- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee index ecff5395a..318265cfb 100644 --- a/app/schemas/models/level.coffee +++ b/app/schemas/models/level.coffee @@ -149,7 +149,7 @@ ScriptSchema = c.object { required: ['channel'] 'default': {channel: 'world:won', noteChain: []} }, - id: c.shortString(title: 'ID', description: 'A unique ID that other scripts can rely on in their Happens After prereqs, for sequencing.') # uniqueness? + id: c.shortString(title: 'ID', description: 'A unique ID that other scripts can rely on in their Happens After prereqs, for sequencing.', pattern: '^[a-zA-Z 0-9:\'"_!-]+$') # uniqueness? Ideally this would be just ids-like-this but we have a lot of legacy data. channel: c.shortString(title: 'Event', format: 'event-channel', description: 'Event channel this script might trigger for, like "world:won".') eventPrereqs: c.array {title: 'Event Checks', description: 'Logical checks on the event for this script to trigger.', format: 'event-prereqs'}, EventPrereqSchema repeats: {title: 'Repeats', description: 'Whether this script can trigger more than once during a level.', enum: [true, false, 'session']} diff --git a/app/templates/play/level/control_bar.jade b/app/templates/play/level/control_bar.jade index 4e4aebbb4..2a1c1716d 100644 --- a/app/templates/play/level/control_bar.jade +++ b/app/templates/play/level/control_bar.jade @@ -21,7 +21,8 @@ h4.title button.btn.btn-xs.btn-inverse.banner#game-menu-button(title="Show game menu", data-i18n="play_level.game_menu") Game Menu -button.btn.btn-xs.btn-success.banner#docs-button(title="Show level instructions", data-i18n="play_level.guide") Guide +if showsGuide + button.btn.btn-xs.btn-success.banner#docs-button(title="Show level instructions", data-i18n="play_level.guide") Guide if spectateGame button.btn.btn-xs.btn-inverse.banner#next-game-button(title="Next Game", data-i18n="play_level.next-game") Next game! diff --git a/app/views/play/level/ControlBarView.coffee b/app/views/play/level/ControlBarView.coffee index 5cfaf2922..f5a779e94 100644 --- a/app/views/play/level/ControlBarView.coffee +++ b/app/views/play/level/ControlBarView.coffee @@ -69,6 +69,8 @@ module.exports = class ControlBarView extends CocoView c.multiplayerSession = @multiplayerSession if @multiplayerSession c.multiplayerPlayers = @multiplayerPlayers if @multiplayerPlayers c.meID = me.id + docs = @level.get('documentation') ? {} + c.showsGuide = docs.specificArticles?.length or docs.generalArticles?.length c afterRender: -> diff --git a/app/views/play/level/LevelHUDView.coffee b/app/views/play/level/LevelHUDView.coffee index 5a28cd94c..f315920a1 100644 --- a/app/views/play/level/LevelHUDView.coffee +++ b/app/views/play/level/LevelHUDView.coffee @@ -85,7 +85,8 @@ module.exports = class LevelHUDView extends CocoView clearTimeout @hintNextSelectionTimeout @$el.find('.no-selection-message').hide() if not @thang - @hintNextSelectionTimeout = _.delay((=> @$el.find('.no-selection-message').slideDown('slow')), 10000) + unless @options.level.get('type', true) is 'hero' + @hintNextSelectionTimeout = _.delay((=> @$el.find('.no-selection-message').slideDown('slow')), 10000) return @createAvatar thangType, @thang @createProperties() diff --git a/app/views/play/level/PlayLevelView.coffee b/app/views/play/level/PlayLevelView.coffee index 14e10428f..27b54efbb 100644 --- a/app/views/play/level/PlayLevelView.coffee +++ b/app/views/play/level/PlayLevelView.coffee @@ -272,7 +272,7 @@ module.exports = class PlayLevelView extends RootView @insertSubView new GoalsView {} @insertSubView new LevelFlagsView world: @world if @levelID is 'sky-span' # TODO: figure out when flags are available @insertSubView new GoldView {} - @insertSubView new HUDView {} + @insertSubView new HUDView {level: @level} @insertSubView new ChatView levelID: @levelID, sessionID: @session.id, session: @session worldName = utils.i18n @level.attributes, 'name' @controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel} diff --git a/app/views/play/level/tome/Spell.coffee b/app/views/play/level/tome/Spell.coffee index 5335e3645..1abf57c29 100644 --- a/app/views/play/level/tome/Spell.coffee +++ b/app/views/play/level/tome/Spell.coffee @@ -182,7 +182,7 @@ module.exports = class Spell @updateLanguageAether e.codeLanguage else console.error 'Spell onNewOpponentCode did not receive code', e - + createProblemContext: (thang) -> # Create problemContext Aether can use to craft better error messages # stringReferences: values that should be referred to as a string instead of a variable (e.g. "Brak", not Brak) @@ -195,7 +195,7 @@ module.exports = class Spell @problemContext = { stringReferences: [], thisMethods: [], thisProperties: [] } # TODO: These should be read from the database - @problemContext.commonThisMethods = ['moveRight', 'moveLeft', 'moveUp', 'moveDown', 'attackNearbyEnemy', 'say', 'move', 'attackNearestEnemy', 'shootAt', 'rotateTo', 'shoot', 'distance', 'getNearestEnemy', 'getEnemies', 'attack', 'setAction', 'setTarget', 'getFriends', 'patrol'] + @problemContext.commonThisMethods = ['moveRight', 'moveLeft', 'moveUp', 'moveDown', 'attack', 'findNearestEnemy', 'buildXY', 'moveXY', 'say', 'move', 'distance', 'findEnemies', 'getFriends', 'addFlag', 'getFlag', 'removeFlag', 'getFlags', 'attackRange', 'cast', 'buildTypes', 'jump', 'jumpTo', 'attackXY'] return @problemContext unless thang? # Populate stringReferences From 9826311656a9be585ab14683e893f5b0623c0f32 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 15 Oct 2014 10:28:29 -0700 Subject: [PATCH 14/15] Started playing menu music on WorldMapView. Only go full-screen on squat windows where we really need it (see #1669). --- app/lib/surface/MusicPlayer.coffee | 1 + app/views/play/WorldMapView.coffee | 13 +++++++++++++ app/views/play/modal/PlayLevelModal.coffee | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/lib/surface/MusicPlayer.coffee b/app/lib/surface/MusicPlayer.coffee index 2a26e1b4a..ddedecbf6 100644 --- a/app/lib/surface/MusicPlayer.coffee +++ b/app/lib/surface/MusicPlayer.coffee @@ -77,4 +77,5 @@ module.exports = class MusicPlayer extends CocoClass destroy: -> me.off 'change:music', @onMusicSettingChanged, @ + @fadeOutCurrentMusic() super() diff --git a/app/views/play/WorldMapView.coffee b/app/views/play/WorldMapView.coffee index eea4fa639..dff84567f 100644 --- a/app/views/play/WorldMapView.coffee +++ b/app/views/play/WorldMapView.coffee @@ -5,6 +5,8 @@ CocoCollection = require 'collections/CocoCollection' AudioPlayer = require 'lib/AudioPlayer' PlayLevelModal = require 'views/play/modal/PlayLevelModal' ThangType = require 'models/ThangType' +MusicPlayer = require 'lib/surface/MusicPlayer' +storage = require 'lib/storage' class LevelSessionsCollection extends CocoCollection url: '' @@ -37,6 +39,9 @@ module.exports = class WorldMapView extends RootView @getLevelPlayCounts() $(window).on 'resize', @onWindowResize @playAmbientSound() + @probablyCachedMusic = storage.load("loaded-menu-music-#{@terrain}") + musicDelay = if @probablyCachedMusic then 1000 else 10000 + @playMusicTimeout = _.delay (=> @playMusic() unless @destroyed), musicDelay @preloadTopHeroes() @hadEverChosenHero = me.get('heroConfig')?.thangType @@ -45,6 +50,8 @@ module.exports = class WorldMapView extends RootView if ambientSound = @ambientSound # Doesn't seem to work; stops immediately. createjs.Tween.get(ambientSound).to({volume: 0.0}, 1500).call -> ambientSound.stop() + @musicPlayer?.destroy() + clearTimeout @playMusicTimeout super() getLevelPlayCounts: -> @@ -202,6 +209,12 @@ module.exports = class WorldMapView extends RootView @ambientSound = createjs.Sound.play src, loop: -1, volume: 0.1 createjs.Tween.get(@ambientSound).to({volume: 1.0}, 1000) + playMusic: -> + @musicPlayer = new MusicPlayer() + musicFile = {Dungeon: '/music/music-menu-dungeon', Grass: '/music/music-menu-grass'}[@terrain] + Backbone.Mediator.publish 'music-player:play-music', play: true, file: musicFile + storage.save("loaded-menu-music-#{@terrain}", true) unless @probablyCachedMusic + preloadTopHeroes: -> for heroID in ['captain', 'knight'] url = "/db/thang.type/#{ThangType.heroes[heroID]}/version" diff --git a/app/views/play/modal/PlayLevelModal.coffee b/app/views/play/modal/PlayLevelModal.coffee index 167b39c9f..dba101b58 100644 --- a/app/views/play/modal/PlayLevelModal.coffee +++ b/app/views/play/modal/PlayLevelModal.coffee @@ -106,7 +106,7 @@ module.exports = class PlayLevelModal extends ModalView return if @$el.find('#play-level-button').prop 'disabled' @showLoading() ua = navigator.userAgent.toLowerCase() - unless hasGoneFullScreenOnce or (/safari/.test(ua) and not /chrome/.test(ua)) + unless hasGoneFullScreenOnce or (/safari/.test(ua) and not /chrome/.test(ua)) or $(window).height() >= 658 # Min vertical resolution needed at 1366px wide @toggleFullscreen() hasGoneFullScreenOnce = true @updateConfig => From d3f35f024adfd3972b145c1f6df94a28b2bd731a Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 15 Oct 2014 10:33:33 -0700 Subject: [PATCH 15/15] Fixed #1665. Fixed #1667. --- app/views/play/WorldMapView.coffee | 1 + app/views/play/modal/PlayLevelModal.coffee | 1 + 2 files changed, 2 insertions(+) diff --git a/app/views/play/WorldMapView.coffee b/app/views/play/WorldMapView.coffee index dff84567f..0bcb43334 100644 --- a/app/views/play/WorldMapView.coffee +++ b/app/views/play/WorldMapView.coffee @@ -136,6 +136,7 @@ module.exports = class WorldMapView extends RootView levelID = $(e.target).parents('.level').data('level-id') @$levelInfo = @$el.find(".level-info-container[data-level-id=#{levelID}]").show() @adjustLevelInfoPosition e + @endHighlight() onMouseLeaveLevel: (e) -> return if application.isIPadApp diff --git a/app/views/play/modal/PlayLevelModal.coffee b/app/views/play/modal/PlayLevelModal.coffee index dba101b58..d4b700599 100644 --- a/app/views/play/modal/PlayLevelModal.coffee +++ b/app/views/play/modal/PlayLevelModal.coffee @@ -101,6 +101,7 @@ module.exports = class PlayLevelModal extends ModalView @chooseHeroView.$el.add('#choose-inventory-button, #choose-hero-header').removeClass 'secret' @inventoryView.$el.add('#choose-hero-button, #play-level-button, #choose-inventory-header').addClass 'secret' @chooseHeroView.onShown() + @inventoryView.endHighlight() onClickPlayLevel: (e) -> return if @$el.find('#play-level-button').prop 'disabled'