diff --git a/app/core/Tracker.coffee b/app/core/Tracker.coffee index c0db96c69..59a5aec7c 100644 --- a/app/core/Tracker.coffee +++ b/app/core/Tracker.coffee @@ -39,7 +39,7 @@ module.exports = class Tracker for integration in includeIntegrations options.integrations[integration] = true - console.log "Would track analytics pageview: '/#{name}'", properties, options if debugAnalytics + console.log "Would track analytics pageview: '/#{name}'", properties, options, includeIntegrations if debugAnalytics return unless @isProduction and analytics? and not me.isAdmin() # Ok to pass empty properties, but maybe not options @@ -58,7 +58,7 @@ module.exports = class Tracker # https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide#Anatomy # Mixpanel properties format: whatever you want unlike GA # https://segment.com/docs/integrations/mixpanel/ - console.log 'Would track analytics event:', action, properties if debugAnalytics + console.log 'Would track analytics event:', action, properties, includeIntegrations if debugAnalytics return unless me and @isProduction and analytics? and not me.isAdmin() properties = properties or {} context = {} diff --git a/app/core/social-handlers/FacebookHandler.coffee b/app/core/social-handlers/FacebookHandler.coffee index 84c6323e7..26df3151f 100644 --- a/app/core/social-handlers/FacebookHandler.coffee +++ b/app/core/social-handlers/FacebookHandler.coffee @@ -42,12 +42,16 @@ module.exports = FacebookHandler = class FacebookHandler extends CocoClass me.set('facebookID', r.id) if r.id Backbone.Mediator.publish 'auth:logging-in-with-facebook', {} - window.tracker?.trackEvent 'Facebook Login' window.tracker?.identify() + beforeID = me.id me.patch({ error: backboneFailure, url: "/db/user/#{me.id}?facebookID=#{r.id}&facebookAccessToken=#{@authResponse.accessToken}" success: (model) -> + window.tracker?.trackEvent 'Facebook Login', category: "Signup", ['Google Analytics'] + if model.id is beforeID + window.tracker?.trackEvent 'Finished Signup', category: "Signup", label: 'Facebook' + window.tracker?.trackPageView "signup/finished", ['Google Analytics'] window.location.reload() if model.get('email') isnt oldEmail }) diff --git a/app/core/social-handlers/GPlusHandler.coffee b/app/core/social-handlers/GPlusHandler.coffee index e60ba5303..748615ff6 100644 --- a/app/core/social-handlers/GPlusHandler.coffee +++ b/app/core/social-handlers/GPlusHandler.coffee @@ -98,11 +98,10 @@ module.exports = GPlusHandler = class GPlusHandler extends CocoClass Backbone.Mediator.publish 'auth:logging-in-with-gplus', {} gplusID = me.get('gplusID') - window.tracker?.trackEvent 'Google Login' window.tracker?.identify() patch = {} patch[key] = me.get(key) for gplusKey, key of userPropsToSave - patch._id = me.id + patch._id = beforeID = me.id patch.email = me.get('email') wasAnonymous = me.get('anonymous') @trigger 'logging-into-codecombat' @@ -111,11 +110,15 @@ module.exports = GPlusHandler = class GPlusHandler extends CocoClass patch: true type: 'PUT' error: -> - console.debug('Logging into GPlus fail.', arguments) + console.warn('Logging into GPlus fail.', arguments) backboneFailure(arguments...) url: "/db/user?gplusID=#{gplusID}&gplusAccessToken=#{@accessToken.access_token}" success: (model) -> - console.debug('GPLus login success!') + console.info('GPLus login success!') + window.tracker?.trackEvent 'Google Login', category: "Signup", ['Google Analytics'] + if model.id is beforeID + window.tracker?.trackEvent 'Finished Signup', label: 'GPlus' + window.tracker?.trackPageView "signup/finished", ['Google Analytics'] window.location.reload() if wasAnonymous and not model.get('anonymous') }) diff --git a/app/lib/LevelOptions.coffee b/app/lib/LevelOptions.coffee index 5fae9716e..f7db0b214 100644 --- a/app/lib/LevelOptions.coffee +++ b/app/lib/LevelOptions.coffee @@ -295,3 +295,14 @@ module.exports = LevelOptions = 'siege-of-stonehold': requiredGear: {} restrictedGear: {} + + # Desert + 'the-dunes': + requiredGear: {} + restrictedGear: {} + 'the-mighty-sand-yak': + requiredGear: {} + restrictedGear: {} + 'oasis': + requiredGear: {} + restrictedGear: {} diff --git a/app/locale/en.coffee b/app/locale/en.coffee index 6322894cc..e0035ed1a 100644 --- a/app/locale/en.coffee +++ b/app/locale/en.coffee @@ -372,6 +372,7 @@ regeneration: "Regeneration" range: "Range" # As in "attack or visual range" blocks: "Blocks" # As in "this shield blocks this much damage" + backstab: "Backstab" # As in "this dagger does this much backstab damage" skills: "Skills" available_for_purchase: "Available for Purchase" level_to_unlock: "Level to unlock:" diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee index 50c9d46de..c0eee0d83 100644 --- a/app/locale/hu.coffee +++ b/app/locale/hu.coffee @@ -7,7 +7,7 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t try_it: "Tegyél próbát!" # Alternate wording for Play button old_browser: "Hohó, a böngésződ már túl régi ahhoz, hogy a CodeCombat futhasson rajta. Bocsi!" # Warning that shows up on really old Firefox/Chrome/Safari old_browser_suffix: "Megpróbálhatod éppen, da valószínűleg nem fog működni.." - ipad_browser: "Rossy hír. CodeCombat nem fut iPadon böngészőben. Jó hír: a hivatalos iPad applikációnk csak az Apple jóváhagyására vár." + ipad_browser: "Rossz hír. CodeCombat nem fut iPadon böngészőben. Jó hír: a hivatalos iPad applikációnk csak az Apple jóváhagyására vár." campaign: "Kampány" for_beginners: "Kezdőknek" multiplayer: "Többjátékos" # Not currently shown on home page @@ -101,14 +101,14 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t log_in: "Bejelentkezés" logging_in: "Bejelentkezés" log_out: "Kijelentkezés" -# forgot_password: "Forgot your password?" + forgot_password: "Elfelejtetted a jelszavad?" authenticate_gplus: "Csatlakozz G+ profillal" load_profile: "Töltsd be G+ Profilod" load_email: "Töltsd be G+ Emaileket" finishing: "Befejezés" -# sign_in_with_facebook: "Sign in with Facebook" -# sign_in_with_gplus: "Sign in with G+" -# signup_switch: "Want to create an account?" + sign_in_with_facebook: "Jelentkezz be Facebook-kal" + sign_in_with_gplus: "Jelentkezz be G+-szal" + signup_switch: "Hozz létre egy fiókot!" signup: email_announcements: "Szeretnél kapni hírlevelet?" @@ -117,7 +117,7 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t log_in: "Belépés meglévő fiókkal" social_signup: "De regisztrálhatsz a Facebook-on vagy a G+:-on keresztül is." required: "Csak akkor mehetsz arra, ha már bejelentkeztél." -# login_switch: "Already have an account?" + login_switch: "Már van fiókod?" recover: recover_account_title: "Meglévő fiók visszaállítása" @@ -157,7 +157,7 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t version: "Verzió" # commit_msg: "Commit Message" version_history: "Verzió történet" -# version_history_for: "Version History for: " + version_history_for: "Verzió története ennek: " result: "Eredmény" results: "Eredmények" description: "Leírás" @@ -216,11 +216,11 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t click_to_select: "Kattints egy egységre, hogy kijelöld!" control_bar_multiplayer: "Többjátékos" control_bar_join_game: "Csatlakozz" -# reload: "Reload" + reload: "Újratöltés" reload_title: "Újra kezded mindet?" reload_really: "Biztos vagy benne, hogy előlről szeretnéd kezdeni az egész pályát?" reload_confirm: "Előlről az egészet" -# victory: "Victory" + victory: "Győzelem" # victory_title_prefix: "" victory_title_suffix: "Kész" victory_sign_up: "Regisztrálj a friss infókért" @@ -233,8 +233,8 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t victory_review: "Mondd el a véleményedet!" # Only in old-style levels. victory_hour_of_code_done: "Készen vagy?" victory_hour_of_code_done_yes: "Igen, ez volt életem kódja!" -# victory_experience_gained: "XP Gained" -# victory_gems_gained: "Gems Gained" + victory_experience_gained: "Szerzett tapasztalat" + victory_gems_gained: "Szerzett Drágakövek" guide_title: "Útmutató" tome_minion_spells: "Egységeid varázslatai" # Only in old-style levels. tome_read_only_spells: "Csak olvasható varázslatok" # Only in old-style levels. @@ -274,11 +274,11 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t tip_error_free: "Két módon lehet hibátlan programot írni. De csak a harmadik működik. - Alan Perlis" # tip_debugging_program: "If debugging is the process of removing bugs, then programming must be the process of putting them in. - Edsger W. Dijkstra" tip_forums: "Irány a fórumok, és mondd el mit gondolsz!!" -# tip_baby_coders: "In the future, even babies will be Archmages." -# tip_morale_improves: "Loading will continue until morale improves." + tip_baby_coders: "A jövőben még a bébik is Főmágusok lesznek." + tip_morale_improves: "A töltés addig folytatódik, amíg a morál javul." tip_all_species: "Hisszük, hogy minden fajnak egyenlő lehetőségekkel kell bírnia a programozás megtanulására." # tip_reticulating: "Reticulating spines." -# tip_harry: "Yer a Wizard, " + tip_harry: "Te, Mágus, " tip_great_responsibility: "Nagy kódolási képességgel nagy hibaelhárítási felelősség jár." # tip_munchkin: "If you don't eat your vegetables, a munchkin will come after you while you're asleep." tip_binary: "A világon csak 10 féle ember van: azok, akik értik a kettes számrendszert és azok, akik nem.." diff --git a/app/models/ThangType.coffee b/app/models/ThangType.coffee index 09fe9ed44..eec0b7b36 100644 --- a/app/models/ThangType.coffee +++ b/app/models/ThangType.coffee @@ -412,6 +412,7 @@ module.exports = class ThangType extends CocoModel throwDamage: 'attack' throwRange: 'range' bashDamage: 'attack' + backstabDamage: 'backstab' }[name] if i18nKey diff --git a/app/models/User.coffee b/app/models/User.coffee index 51bae80a7..1a4ab7454 100644 --- a/app/models/User.coffee +++ b/app/models/User.coffee @@ -115,6 +115,17 @@ module.exports = class User extends CocoModel application.tracker.identify announcesActionAudioGroup: @announcesActionAudioGroup unless me.isAdmin() @announcesActionAudioGroup + getFastVictoryModalGroup: -> + # A/B Testing no delay showing the signup and continue buttons in hero victory modal + return @fastVictoryModalGroup if @fastVictoryModalGroup + group = me.get('testGroupNumber') % 2 + @fastVictoryModalGroup = switch group + when 0 then 'normal' + when 1 then 'fast' + @fastVictoryModalGroup = 'fast' if me.isAdmin() + application.tracker.identify fastVictoryModalGroup: @fastVictoryModalGroup unless me.isAdmin() + @fastVictoryModalGroup + getGemPromptGroup: -> return @gemPromptGroup if @gemPromptGroup group = me.get('testGroupNumber') % 8 diff --git a/app/templates/play/level/modal/hero-victory-modal.jade b/app/templates/play/level/modal/hero-victory-modal.jade index 8e1fd2445..cc196082e 100644 --- a/app/templates/play/level/modal/hero-victory-modal.jade +++ b/app/templates/play/level/modal/hero-victory-modal.jade @@ -65,7 +65,7 @@ block modal-footer-content if me.get('anonymous') .sign-up-poke.hide .sign-up-blurb(data-i18n="play_level.victory_sign_up_poke") Want to save your code? Create a free account! - button.btn.btn-illustrated.btn-warning.sign-up-button.btn-lg(data-toggle="coco-modal", data-target="core/AuthModal", data-i18n="play_level.victory_sign_up") Sign Up to Save Progress + button.btn.btn-illustrated.btn-warning.sign-up-button.btn-lg(data-dismiss="modal", data-i18n="play_level.victory_sign_up") Sign Up to Save Progress button.btn.btn-illustrated.btn-lg.btn-warning.hide#saving-progress-label(disabled, data-i18n="play_level.victory_saving_progress") Saving Progress diff --git a/app/templates/play/level/modal/victory.jade b/app/templates/play/level/modal/victory.jade index d2fbd3e70..1927a924e 100644 --- a/app/templates/play/level/modal/victory.jade +++ b/app/templates/play/level/modal/victory.jade @@ -23,7 +23,7 @@ block modal-footer-content a.btn.btn-primary(href="/", data-dismiss="modal", data-i18n="play_level.victory_go_home") Go Home if me.get('anonymous') p.sign-up-poke - button.btn.btn-success.sign-up-button.btn-large(data-toggle="coco-modal", data-target="core/AuthModal", data-i18n="play_level.victory_sign_up") Sign Up to Save Progress + button.btn.btn-success.sign-up-button.btn-large(data-dismiss="modal", data-i18n="play_level.victory_sign_up") Sign Up to Save Progress span(data-i18n="play_level.victory_sign_up_poke") Want to save your code? Create a free account! p.clearfix else diff --git a/app/views/core/AuthModal.coffee b/app/views/core/AuthModal.coffee index 8034cd5b8..5c28e8c62 100644 --- a/app/views/core/AuthModal.coffee +++ b/app/views/core/AuthModal.coffee @@ -90,7 +90,7 @@ module.exports = class AuthModal extends ModalView res = tv4.validateMultiple userObject, User.schema return forms.applyErrorsToForm(@$el, res.errors) unless res.valid Backbone.Mediator.publish "auth:signed-up", {} - window.tracker?.trackEvent 'Finished Signup' + window.tracker?.trackEvent 'Finished Signup', label: 'CodeCombat' window.tracker?.trackPageView "signup/finished", ['Google Analytics'] @enableModalInProgress(@$el) createUser userObject, null, window.nextLevelURL diff --git a/app/views/core/RootView.coffee b/app/views/core/RootView.coffee index 922f6f0ae..a1d095f96 100644 --- a/app/views/core/RootView.coffee +++ b/app/views/core/RootView.coffee @@ -55,14 +55,14 @@ module.exports = class RootView extends CocoView switch @id when 'home-view' window.tracker?.trackEvent 'Started Signup', category: 'Homepage', label: 'Homepage' - window.tracker?.trackPageView "signup/homepage", ['Google Analytics'] + window.tracker?.trackPageView "signup/start", ['Google Analytics'] when 'world-map-view' # TODO: add campaign data window.tracker?.trackEvent 'Started Signup', category: 'World Map', label: 'World Map' - window.tracker?.trackPageView "signup/world-map", ['Google Analytics'] + window.tracker?.trackPageView "signup/start", ['Google Analytics'] else - window.tracker?.trackEvent 'Started Signup', label: 'unknown' - window.tracker?.trackPageView "signup/unknown", ['Google Analytics'] + window.tracker?.trackEvent 'Started Signup', label: @id + window.tracker?.trackPageView "signup/start", ['Google Analytics'] @openModalView new AuthModal {mode: 'signup'} onClickLoginButton: -> diff --git a/app/views/play/WorldMapView.coffee b/app/views/play/WorldMapView.coffee index 6a8980cdd..7d121906f 100644 --- a/app/views/play/WorldMapView.coffee +++ b/app/views/play/WorldMapView.coffee @@ -895,8 +895,8 @@ forest = [ id: 'siege-of-stonehold' original: '54712072eb739dbc9d24034b' description: 'Unlock the desert world, if you are strong enough to win this epic battle!' - #nextLevels: - # continue: '' + nextLevels: + continue: 'the-dunes' disabled: not me.isAdmin() x: 85.5 y: 83.5 @@ -923,6 +923,50 @@ forest = [ y: 23 adventurer: true } + + { + name: 'The Dunes' + type: 'hero' + id: 'the-dunes' + original: '5480b62e1bf0b10000711c59' + description: 'Behold, the desert, full of glory, danger, and sand. Lots of sand.' + nextLevels: + continue: 'the-mighty-sand-yak' + disabled: not me.isAdmin() + x: 88.66 + y: 62.61 + adventurer: true + requiresSubscription: true + } + { + name: 'The Mighty Sand Yak' + type: 'hero' + id: 'the-mighty-sand-yak' + original: '5480b9d01bf0b10000711c5f' + description: 'In addition to sand, there are also yaks. Sandy yaks. Yak attack, back to back, man that\'s whack.' + nextLevels: + continue: 'oasis' + disabled: not me.isAdmin() + x: 81.00 + y: 55.37 + adventurer: true + requiresSubscription: true + } + { + name: 'Oasis' + type: 'hero' + id: 'oasis' + original: '5480ba761bf0b10000711c64' + description: 'There is a bit of water in the desert, too. Probably.' + #nextLevels: + # continue: '' + disabled: not me.isAdmin() + x: 92.56 + y: 40.88 + adventurer: true + requiresSubscription: true + } + ] WorldMapView.campaigns = campaigns = [ diff --git a/app/views/play/level/ControlBarView.coffee b/app/views/play/level/ControlBarView.coffee index 95fb9f202..e6e277695 100644 --- a/app/views/play/level/ControlBarView.coffee +++ b/app/views/play/level/ControlBarView.coffee @@ -98,7 +98,7 @@ module.exports = class ControlBarView extends CocoView onClickSignupButton: -> window.tracker?.trackEvent 'Started Signup', category: 'Play Level', label: 'Control Bar', level: @levelID - window.tracker?.trackPageView "signup/play-level", ['Google Analytics'] + window.tracker?.trackPageView "signup/start", ['Google Analytics'] onDisableControls: (e) -> @toggleControls e, false onEnableControls: (e) -> @toggleControls e, true diff --git a/app/views/play/level/modal/HeroVictoryModal.coffee b/app/views/play/level/modal/HeroVictoryModal.coffee index 921d08c12..04434e77a 100644 --- a/app/views/play/level/modal/HeroVictoryModal.coffee +++ b/app/views/play/level/modal/HeroVictoryModal.coffee @@ -1,4 +1,5 @@ ModalView = require 'views/core/ModalView' +AuthModal = require 'views/core/AuthModal' template = require 'templates/play/level/modal/hero-victory-modal' Achievement = require 'models/Achievement' EarnedAchievement = require 'models/EarnedAchievement' @@ -24,6 +25,7 @@ module.exports = class HeroVictoryModal extends ModalView events: 'click #continue-button': 'onClickContinue' 'click .return-to-ladder-button': 'onClickReturnToLadder' + 'click .sign-up-button': 'onClickSignupButton' constructor: (options) -> super(options) @@ -281,7 +283,8 @@ module.exports = class HeroVictoryModal extends ModalView Backbone.Mediator.publish 'music-player:enter-menu', terrain: @level.get('terrain', true) updateSavingProgressStatus: -> - return unless @animationComplete + # A/B Testing no delay showing the signup and continue buttons in hero victory modal + return unless @animationComplete or me.getFastVictoryModalGroup() is 'fast' @$el.find('#saving-progress-label').toggleClass('hide', @readyToContinue) @$el.find('.next-level-button').toggleClass('hide', not @readyToContinue) @$el.find('.sign-up-poke').toggleClass('hide', not @readyToContinue) @@ -335,3 +338,9 @@ module.exports = class HeroVictoryModal extends ModalView route = $(e.target).data('href') # Preserve the supermodel as we navigate back to the ladder. Backbone.Mediator.publish 'router:navigate', route: route, viewClass: 'views/ladder/LadderView', viewArgs: [{supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel}, @level.get('slug')] + + onClickSignupButton: (e) -> + e.preventDefault() + window.tracker?.trackEvent 'Started Signup', category: 'Play Level', label: 'Hero Victory Modal', level: @level.get('slug') + window.tracker?.trackPageView "signup/start", ['Google Analytics'] + @openModalView new AuthModal {mode: 'signup'} diff --git a/app/views/play/level/modal/VictoryModal.coffee b/app/views/play/level/modal/VictoryModal.coffee index 81ae265ef..2cc03bd7e 100644 --- a/app/views/play/level/modal/VictoryModal.coffee +++ b/app/views/play/level/modal/VictoryModal.coffee @@ -1,4 +1,5 @@ ModalView = require 'views/core/ModalView' +AuthModal = require 'views/core/AuthModal' template = require 'templates/play/level/modal/victory' {me} = require 'core/auth' LadderSubmissionView = require 'views/play/common/LadderSubmissionView' @@ -15,6 +16,7 @@ module.exports = class VictoryModal extends ModalView events: 'click .next-level-button': 'onPlayNextLevel' 'click .world-map-button': 'onClickWorldMap' + 'click .sign-up-button': 'onClickSignupButton' # review events 'mouseover .rating i': (e) -> @showStars(@starNum($(e.target))) @@ -68,6 +70,12 @@ module.exports = class VictoryModal extends ModalView e.stopImmediatePropagation() Backbone.Mediator.publish 'router:navigate', route: '/play', viewClass: require('views/play/WorldMapView'), viewArgs: [{supermodel: @supermodel}] + onClickSignupButton: (e) -> + e.preventDefault() + window.tracker?.trackEvent 'Started Signup', category: 'Play Level', label: 'Victory Modal', level: @level.get('slug') + window.tracker?.trackPageView "signup/start", ['Google Analytics'] + @openModalView new AuthModal {mode: 'signup'} + onGameSubmitted: (e) -> ladderURL = "/play/ladder/#{@level.get('slug')}#my-matches" Backbone.Mediator.publish 'router:navigate', route: ladderURL diff --git a/app/views/play/menu/GameMenuModal.coffee b/app/views/play/menu/GameMenuModal.coffee index 8b9ed7a35..85cf63ab0 100644 --- a/app/views/play/menu/GameMenuModal.coffee +++ b/app/views/play/menu/GameMenuModal.coffee @@ -1,4 +1,5 @@ ModalView = require 'views/core/ModalView' +AuthModal = require 'views/core/AuthModal' template = require 'templates/play/menu/game-menu-modal' submenuViews = [ require 'views/play/menu/SaveLoadView' @@ -18,6 +19,7 @@ module.exports = class GameMenuModal extends ModalView 'shown.bs.tab #game-menu-nav a': 'onTabShown' 'click #change-hero-tab': -> @trigger 'change-hero' 'click #close-modal': 'hide' + 'click .auth-tab': 'onClickSignupButton' constructor: (options) -> super options @@ -63,3 +65,10 @@ module.exports = class GameMenuModal extends ModalView subview.onHidden?() for subviewKey, subview of @subviews @playSound 'game-menu-close' Backbone.Mediator.publish 'music-player:exit-menu', {} + + onClickSignupButton: (e) -> + window.tracker?.trackEvent 'Started Signup', category: 'Play Level', label: 'Game Menu', level: @options.levelID + window.tracker?.trackPageView "signup/start", ['Google Analytics'] + # TODO: Default already seems to be prevented. Need to be explicit? + e.preventDefault() + @openModalView new AuthModal {mode: 'signup'}