From 6473fff940b7b0d810c311c514ef1ed4e2742968 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Sat, 25 Oct 2014 21:53:55 -0700 Subject: [PATCH 1/7] Implemented stat comparison bars on ChooseHeroView. --- app/locale/en.coffee | 2 + app/styles/game-menu/choose-hero-view.sass | 22 +++- app/templates/game-menu/choose-hero-view.jade | 35 ++++-- app/views/game-menu/ChooseHeroView.coffee | 119 +++++++++++++----- 4 files changed, 138 insertions(+), 40 deletions(-) diff --git a/app/locale/en.coffee b/app/locale/en.coffee index adf8a1b42..fa68ee8f7 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -297,8 +297,10 @@ programming_language_description: "Which programming language do you want to use?" status: "Status" weapons: "Weapons" + attack: "Damage" # Can also translate as "Attack" health: "Health" speed: "Speed" + skills: "Skills" save_load: granularity_saved_games: "Saved" diff --git a/app/styles/game-menu/choose-hero-view.sass b/app/styles/game-menu/choose-hero-view.sass index 79fbd4349..1c4e367d2 100644 --- a/app/styles/game-menu/choose-hero-view.sass +++ b/app/styles/game-menu/choose-hero-view.sass @@ -79,7 +79,27 @@ $heroCanvasHeight: 265px .hero-stats text-shadow: 0 1px 1px rgba(255, 255, 255, 0.6) - font-size: 24px + + .hero-class, .hero-status, .hero-skills + font-size: 14px + + .hero-stat + margin: 10px 0 + + .progress + width: 90% + text-align: center + height: 26px + position: relative + margin: 0 + + .hero-stat-label + position: absolute + width: 100% + font-size: 18px + text-transform: uppercase + color: white + text-shadow: 0px 1px 0px black, 0px -1px 0px black, -1px 0px 0px black, 1px 0px 0px black .carousel-control.left border-top-left-radius: 10px diff --git a/app/templates/game-menu/choose-hero-view.jade b/app/templates/game-menu/choose-hero-view.jade index e9f86a36a..aea114afe 100644 --- a/app/templates/game-menu/choose-hero-view.jade +++ b/app/templates/game-menu/choose-hero-view.jade @@ -16,25 +16,40 @@ img .hero-stats h2= info.fullName - p + //.hero-description= info.description // Not until we have written the descriptions. + .hero-status span(data-i18n="choose_hero.status") Status span.spr : if hero.locked | #{info.status} else | Available - p + .hero-class span(data-i18n="choose_hero.weapons") Weapons span.spr : | #{info.weapons} - p - span(data-i18n="choose_hero.health") Health - span.spr : - | #{info.health} - p - span(data-i18n="choose_hero.speed") Speed - span.spr : - | #{info.speed} + for statInfo in [{name: 'attack', color: 'danger'}, {name: 'health', color: 'info'}, {name: 'speed', color: 'success'}] + - var tooltip = ""; + - if (statInfo.name == 'attack') + - tooltip = Math.round(100 * info[statInfo.name + 'Factor']) + '% ' + info.class.toLowerCase() + ' weapon damage'; + - else if (statInfo.name == 'health') + - tooltip = Math.round(100 * info[statInfo.name + 'Factor']) + '% ' + info.class.toLowerCase() + ' armor health'; + - else if (statInfo.name == 'speed') + - tooltip = info.speedAbsolute + ' meters per second'; + .hero-stat(title=tooltip) + .progress + div(class="progress-bar progress-bar-" + statInfo.color, style="width: " + (10 * info[statInfo.name]) + "%") + .hero-stat-label + span(data-i18n="choose_hero." + statInfo.name) + span.spr : + | #{info[statInfo.name]} + + if info.skills + .hero-skills + span(data-i18n="choose_hero.skills") Skills + span.spr : + for skill in info.skills + code.spl.spr= skill a.carousel-control.left(role="button", data-slide="prev", href="#hero-carousel") span.glyphicon.glyphicon-chevron-left a.carousel-control.right(role="button", data-slide="next", href="#hero-carousel") diff --git a/app/views/game-menu/ChooseHeroView.coffee b/app/views/game-menu/ChooseHeroView.coffee index 07a1988e6..25005cf63 100644 --- a/app/views/game-menu/ChooseHeroView.coffee +++ b/app/views/game-menu/ChooseHeroView.coffee @@ -65,6 +65,7 @@ module.exports = class ChooseHeroView extends CocoView heroIndex = Math.max 0, _.findIndex(heroes, ((hero) -> hero.get('original') is heroConfig.thangType)) @$el.find(".hero-item:nth-child(#{heroIndex + 1}), .hero-indicator:nth-child(#{heroIndex + 1})").addClass('active') @onHeroChanged direction: null, relatedTarget: @$el.find('.hero-item')[heroIndex] + @$el.find('.hero-stat').tooltip() onHeroChanged: (e) -> direction = e.direction # 'left' or 'right' @@ -161,65 +162,125 @@ module.exports = class ChooseHeroView extends CocoView temporaryHeroInfo = - captain: - fullName: 'Captain Anya Weston' - weapons: 'Razor Discs' - status: 'Available' - health: '35' - speed: '4 m/s' - knight: fullName: 'Tharin Thunderfist' - weapons: 'Swords' + weapons: 'Swords - Short Range, No Magic' + class: 'Warrior' + description: 'Beefcake! Beefcaaake!' status: 'Available' - health: '35' - speed: '4 m/s' + attack: 8 + attackFactor: 1.2 + health: 8.5 + healthFactor: 1.4 + speed: 1.5 + speedAbsolute: 6 + + captain: + fullName: 'Captain Anya Weston' + weapons: 'Swords - Short Range, No Magic' + class: 'Warrior' + description: 'Don\'t bother me, I\'m winning this fight for you.' + status: 'Available' + attack: 8 + attackFactor: 1.2 + health: 8.5 + healthFactor: 1.4 + speed: 1.5 + speedAbsolute: 6 thoktar: fullName: 'Thoktar the Devourer' - weapons: 'Magic' + weapons: 'Wands, Staffs - Long Range, Magic' + class: 'Wizard' + description: '???' status: 'Locked' - health: '???' - speed: '???' + attack: 5 + attackFactor: 2 + health: 4.5 + healthFactor: 1.4 + speed: 2.5 + speedAbsolute: 7 + skills: ['summonElemental', 'devour'] equestrian: fullName: 'Rider Reynaldo' - weapons: 'Axes' + weapons: 'Crossbows, Guns - Long Range, No Magic' + class: 'Ranger' + description: '???' status: 'Locked' - health: '???' - speed: '???' + attack: 6 + attackFactor: 1.4 + health: 7 + healthFactor: 1.8 + speed: 1.5 + speedAbsolute: 6 + skills: ['hide'] 'potion-master': fullName: 'Master Snake' - weapons: 'Magic' + weapons: 'Wands, Staffs - Long Range, Magic' + class: 'Wizard' + description: '???' status: 'Locked' - health: '???' - speed: '???' + attack: 2 + attackFactor: 0.833 + health: 4 + healthFactor: 1.2 + speed: 6 + speedAbsolute: 11 + skills: ['brewPotion'] librarian: fullName: 'Hushbaum' - weapons: 'Magic' + weapons: 'Wands, Staffs - Long Range, Magic' + class: 'Wizard' + description: '???' status: 'Locked' - health: '???' - speed: '???' + attack: 3 + attackFactor: 1.2 + health: 4.5 + healthFactor: 1.4 + speed: 2.5 + speedAbsolute: 7 'robot-walker': fullName: '???' weapons: '???' + class: 'Ranger' + description: '???' status: 'Locked' - health: '???' - speed: '???' + attack: 6.5 + attackFactor: 1.6 + health: 5.5 + healthFactor: 1.2 + speed: 6 + speedAbsolute: 11 + skills: ['???', '???', '???'] 'michael-heasell': fullName: '???' weapons: '???' + class: 'Ranger' + description: '???' status: 'Locked' - health: '???' - speed: '???' + attack: 4 + attackFactor: 0.714 + health: 5 + healthFactor: 1 + speed: 10 + speedAbsolute: 16 + skills: ['???', '???'] 'ian-elliott': fullName: '???' - weapons: '???' + weapons: 'Swords - Short Range, No Magic' + class: 'Warrior' + description: '???' status: 'Locked' - health: '???' - speed: '???' + attack: 9.5 + attackFactor: 1.8 + health: 6.5 + healthFactor: 0.714 + speed: 3.5 + speedAbsolute: 8 + skills: ['trueStrike'] From 647e578b46735c0fee5eafbae7b967347d8fa42c Mon Sep 17 00:00:00 2001 From: Imperadeiro98 Date: Sun, 26 Oct 2014 14:25:53 +0000 Subject: [PATCH 2/7] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index cf335f9da..39157309a 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -203,12 +203,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: victory_rate_the_level: "Classifica este nível: " # Only in old-style levels. victory_return_to_ladder: "Voltar à Classificação" victory_play_continue: "Continuar" -# victory_play_skip: "Skip Ahead" + victory_play_skip: "Passar à Frente" victory_play_next_level: "Jogar Próximo Nível" -# victory_play_more_practice: "More Practice" -# victory_play_too_easy: "Too Easy" -# victory_play_just_right: "Just Right" -# victory_play_too_hard: "Too Hard" + victory_play_more_practice: "Mais Treino" + victory_play_too_easy: "Muito Fácil" + victory_play_just_right: "Perfeito" + victory_play_too_hard: "Muito Difícil" victory_saving_progress: "A Guardar o Progresso" victory_go_home: "Ir para o Início" # Only in old-style levels. victory_review: "Conta-nos mais!" # Only in old-style levels. @@ -1052,10 +1052,10 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: av_entities_active_instances_url: "Activar Instâncias" av_entities_employer_list_url: "Lista de Empregadores" av_entities_candidates_list_url: "Lista de Candidatos" -# av_entities_user_code_problems_list_url: "User Code Problems List" + av_entities_user_code_problems_list_url: "Lista de Problemas no Código do Jogador" av_other_sub_title: "Outro" av_other_debug_base_url: "Base (para depurar base.jade)" u_title: "Lista de Utilizadores" -# ucp_title: "User Code Problems" + ucp_title: "Problemas no Código do Jogador" lg_title: "Últimos Jogos" clas: "CLA's" From 7c21d5921eeeb3d405347075624475974b14265f Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Sun, 26 Oct 2014 10:49:13 -0700 Subject: [PATCH 3/7] Update query for user code problems view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So it doesn’t explode in production. --- app/templates/admin/user-code-problems.jade | 57 +++++++++++---------- app/views/admin/UserCodeProblemsView.coffee | 15 +++++- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/app/templates/admin/user-code-problems.jade b/app/templates/admin/user-code-problems.jade index 75ad99c1e..1d8386e01 100644 --- a/app/templates/admin/user-code-problems.jade +++ b/app/templates/admin/user-code-problems.jade @@ -4,30 +4,33 @@ block content h1(data-i18n="admin.ucp_title") User Code Problems - table.table.table-striped.table-bordered.table-condensed#users - thead(style='font-weight:bold') - tr - td language - //- td errType - //- td errLevel - //- td errId - td levelID - td codeSnippet - td errHint - td errMessage - //- td code - td created - - tbody - each problem in userCodeProblems - tr - td #{problem.language} - //- td #{problem.errType} - //- td #{problem.errLevel} - //- td #{problem.errId} - td #{problem.levelID} - td #{problem.codeSnippet} - td #{problem.errHint} - td #{problem.errMessage} - //- td #{problem.code} - td #{new Date(problem.created).toLocaleString()} + if fetchingData + h3 Fetching data... + else + table.table.table-striped.table-bordered.table-condensed#users + thead(style='font-weight:bold') + tr + td language + //- td errType + //- td errLevel + //- td errId + td levelID + td codeSnippet + td errHint + td errMessage + //- td code + td created + + tbody + each problem in userCodeProblems + tr + td #{problem.language} + //- td #{problem.errType} + //- td #{problem.errLevel} + //- td #{problem.errId} + td #{problem.levelID} + td #{problem.codeSnippet} + td #{problem.errHint} + td #{problem.errMessage} + //- td #{problem.code} + td #{new Date(problem.created).toLocaleString()} diff --git a/app/views/admin/UserCodeProblemsView.coffee b/app/views/admin/UserCodeProblemsView.coffee index 876ab9a4b..008d4268c 100644 --- a/app/views/admin/UserCodeProblemsView.coffee +++ b/app/views/admin/UserCodeProblemsView.coffee @@ -10,6 +10,7 @@ module.exports = class UserCodeProblemsView extends RootView constructor: (options) -> super options + @fetchingData = true @getUserCodeProblems() getUserCodeProblems: -> @@ -19,9 +20,18 @@ module.exports = class UserCodeProblemsView extends RootView # The first arg is the function name # The rest are the args for the function + lastMonth = new Date() + if lastMonth.getMonth() is 1 + lastMonth.setMonth 12 + lastMonth.setYear lastMonth.getYear() - 1 + else + lastMonth.setMonth lastMonth.getMonth() - 1 + conditions = [ ['limit', 1000] ['sort', '-created'] + ['where', 'created'] + ['gte', lastMonth.toString()] ] conditions = $.param({conditions:JSON.stringify(conditions)}) UserCodeProblemCollection = Backbone.Collection.extend({ @@ -30,9 +40,12 @@ module.exports = class UserCodeProblemsView extends RootView }) @userCodeProblems = new UserCodeProblemCollection() @userCodeProblems.fetch() - @listenTo(@userCodeProblems, 'all', @render) + @listenTo @userCodeProblems, 'all', -> + @fetchingData = false + @render() getRenderData: -> c = super() + c.fetchingData = @fetchingData c.userCodeProblems = (problem.attributes for problem in @userCodeProblems.models) c From 6d9e2439681d7cdcc140eb8ef8b25c0474b31696 Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Sun, 26 Oct 2014 10:52:22 -0700 Subject: [PATCH 4/7] Update server development logging Provide more details. --- server_setup.coffee | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/server_setup.coffee b/server_setup.coffee index 70f9a7f9b..e90acccc6 100644 --- a/server_setup.coffee +++ b/server_setup.coffee @@ -27,6 +27,16 @@ productionLogging = (tokens, req, res) -> return "\x1b[90m#{req.method} #{req.originalUrl} \x1b[#{color}m#{res.statusCode} \x1b[#{elapsedColor}m#{elapsed}ms\x1b[0m" null +developmentLogging = (tokens, req, res) -> + status = res.statusCode + color = 32 + if status >= 500 then color = 31 + else if status >= 400 then color = 33 + else if status >= 300 then color = 36 + elapsed = (new Date()) - req._startTime + elapsedColor = if elapsed < 500 then 90 else 31 + "\x1b[90m#{req.method} #{req.originalUrl} \x1b[#{color}m#{res.statusCode} \x1b[#{elapsedColor}m#{elapsed}ms\x1b[0m" + setupExpressMiddleware = (app) -> if config.isProduction express.logger.format('prod', productionLogging) @@ -35,6 +45,7 @@ setupExpressMiddleware = (app) -> return false if req.headers.host is 'codecombat.com' # CloudFlare will gzip it for us on codecombat.com # But now it's disabled. compressible res.getHeader('Content-Type') else + express.logger.format('dev', developmentLogging) app.use(express.logger('dev')) app.use(express.static(path.join(__dirname, 'public'))) app.use(useragent.express()) From 27d1304c6c0eb907fd8edb42b03546948685e315 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Sun, 26 Oct 2014 10:16:43 -0700 Subject: [PATCH 5/7] Turns out checking Errorception is really useful. --- app/views/play/level/modal/HeroVictoryModal.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/play/level/modal/HeroVictoryModal.coffee b/app/views/play/level/modal/HeroVictoryModal.coffee index bfd52cc1f..115f774bd 100644 --- a/app/views/play/level/modal/HeroVictoryModal.coffee +++ b/app/views/play/level/modal/HeroVictoryModal.coffee @@ -211,7 +211,7 @@ module.exports = class HeroVictoryModal extends ModalView else if panel.hero thangType = @thangTypes[panel.hero] panel.textEl.text(thangType.get('name')) - @playSelectionSound hero if 0.5 < ratio < 0.6 + @playSelectionSound thangType if 0.5 < ratio < 0.6 if ratio is 1 panel.rootEl.removeClass('animating').find('.reward-image-container img').removeClass('pulse') @sequentialAnimationStart = new Date() From e71767cc1f8cf465b9633dc8a683f3bac9756a73 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Sun, 26 Oct 2014 11:02:12 -0700 Subject: [PATCH 6/7] Enabled sourcemaps for production. --- config.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config.coffee b/config.coffee index ff02150a1..503da36b0 100644 --- a/config.coffee +++ b/config.coffee @@ -5,10 +5,13 @@ startsWith = (string, substring) -> exports.config = paths: public: 'public' - watched: ['app', 'vendor', 'test/app', 'test/demo'] + watched: ['app', 'vendor', 'test/app', 'test/demo'] conventions: ignored: (path) -> startsWith(sysPath.basename(path), '_') sourceMaps: true + overrides: + production: + sourceMaps: true files: javascripts: defaultExtension: 'coffee' From c0f5c357ba85ab986677f7300c64585b1560986f Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Sun, 26 Oct 2014 15:31:20 -0700 Subject: [PATCH 7/7] Defense, not defence. --- app/views/game-menu/InventoryView.coffee | 2 +- app/views/play/WorldMapView.coffee | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/game-menu/InventoryView.coffee b/app/views/game-menu/InventoryView.coffee index 9d5137f31..2ccbca886 100644 --- a/app/views/game-menu/InventoryView.coffee +++ b/app/views/game-menu/InventoryView.coffee @@ -337,7 +337,7 @@ module.exports = class InventoryView extends CocoView 'closing-the-distance': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', eyes: 'crude-glasses'} 'the-final-kithmaze': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'} 'kithgard-gates': {feet: 'simple-boots', 'right-hand': 'builders-hammer'} - 'defence-of-plainswood': {feet: 'simple-boots', 'right-hand': 'builders-hammer'} + 'defense-of-plainswood': {feet: 'simple-boots', 'right-hand': 'builders-hammer'} # TODO: figure out leather boots for plainswood (or next one?) return unless necessaryGear = gearByLevel[@options.levelID] if @inserted diff --git a/app/views/play/WorldMapView.coffee b/app/views/play/WorldMapView.coffee index e53069774..3860655a3 100644 --- a/app/views/play/WorldMapView.coffee +++ b/app/views/play/WorldMapView.coffee @@ -864,13 +864,13 @@ hero = [ x: 89 y: 82 nextLevels: - continue: 'defence-of-plainswood' + continue: 'defense-of-plainswood' } { - name: 'Defence of Plainswood' + name: 'Defense of Plainswood' type: 'hero' difficulty: 1 - id: 'defence-of-plainswood' + id: 'defense-of-plainswood' original: '541b67f71ccc8eaae19f3c62' description: 'Protect the peasants from the pursuing ogres.' x: 95.31