2013-09-10 22:06:16 +00:00
'use strict' ;
/ * *
* Services for each tour step when you unlock features
* /
angular . module ( 'guideServices' , [ ] ) .
2013-09-17 18:44:02 +00:00
factory ( 'Guide' , [ '$rootScope' , 'User' , 'Items' , 'Helpers' , function ( $rootScope , User , Items , Helpers ) {
2013-09-10 22:06:16 +00:00
2013-09-17 18:07:04 +00:00
/ * *
* Init and show the welcome tour . Note we do it listening to a $rootScope broadcasted 'userLoaded' message ,
* this because we need to determine whether to show the tour * after * the user has been pulled from the server ,
* otherwise it ' s always start off as true , and then get set to false later
* /
2013-09-17 18:44:02 +00:00
$rootScope . $on ( 'userUpdated' , initTour ) ;
function initTour ( ) {
2013-09-10 22:06:16 +00:00
if ( User . user . flags . showTour === false ) return ;
var tourSteps = [
{
element : ".main-herobox" ,
title : "Welcome to HabitRPG" ,
2013-09-10 22:20:10 +00:00
content : "Welcome to HabitRPG, a habit-tracker which treats your goals like a Role Playing Game. I'm <a href='http://www.kickstarter.com/profile/1823740484' target='_blank'>Justin</a>, your guide! "
2013-09-10 22:06:16 +00:00
} , {
element : "#bars" ,
title : "Achieve goals and level up" ,
content : "As you accomplish goals, you level up. If you fail your goals, you lose hit points. Lose all your HP and you die."
} , {
element : "ul.habits" ,
title : "Habits" ,
content : "Habits are goals that you constantly track." ,
placement : "bottom"
} , {
element : "ul.dailys" ,
title : "Dailies" ,
content : "Dailies are goals that you want to complete once a day." ,
placement : "bottom"
} , {
element : "ul.todos" ,
title : "Todos" ,
content : "Todos are one-off goals which need to be completed eventually." ,
placement : "bottom"
} , {
element : "ul.rewards" ,
title : "Rewards" ,
content : "As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits." ,
placement : "bottom"
} , {
element : "ul.habits li:first-child" ,
title : "Hover over comments" ,
content : "Different task-types have special properties. Hover over each task's comment for more information. When you're ready to get started, delete the existing tasks and add your own." ,
placement : "right"
}
] ;
2013-09-10 22:20:10 +00:00
_ . each ( tourSteps , function ( step ) {
2013-09-17 18:15:57 +00:00
step . content = "<div><div class='NPC-Justin float-left'></div>" + step . content + "</div>" ; // add Justin NPC img
2013-09-10 22:20:10 +00:00
} ) ;
2013-09-10 22:06:16 +00:00
$ ( '.main-herobox' ) . popover ( 'destroy' ) ;
var tour = new Tour ( {
onEnd : function ( ) {
2013-09-12 20:45:13 +00:00
User . set ( 'flags.showTour' , false ) ;
2013-09-10 22:06:16 +00:00
}
} ) ;
tourSteps . forEach ( function ( step ) {
tour . addStep ( _ . defaults ( step , { html : true } ) ) ;
} ) ;
tour . restart ( ) ; // Tour doesn't quite mesh with our handling of flags.showTour, just restart it on page load
//tour.start(true);
2013-09-17 18:44:02 +00:00
} ;
2013-09-17 18:07:04 +00:00
var alreadyShown = function ( before , after ) {
return ! ( ! before && after === true ) ;
} ;
var showPopover = function ( selector , title , html , placement ) {
if ( ! placement ) placement = 'bottom' ;
$ ( selector ) . popover ( 'destroy' ) ;
2013-09-17 18:44:02 +00:00
var button = "<button class='btn btn-sm btn-default' onClick=\"$('" + selector + "').popover('hide');return false;\">Close</button>" ;
html = "<div><div class='NPC-Justin float-left'></div>" + html + '<br/>' + button + '</div>' ;
2013-09-17 18:07:04 +00:00
$ ( selector ) . popover ( {
title : title ,
placement : placement ,
trigger : 'manual' ,
html : true ,
content : html
} ) . popover ( 'show' ) ;
2013-09-10 22:06:16 +00:00
} ;
2013-09-17 18:07:04 +00:00
$rootScope . $watch ( 'user.flags.customizationsNotification' , function ( after , before ) {
2013-09-17 18:57:40 +00:00
if ( alreadyShown ( before , after ) ) return ;
2013-09-17 18:07:04 +00:00
showPopover ( '.main-herobox' , 'Customize Your Avatar' , "Click your avatar to customize your appearance." , 'bottom' ) ;
} ) ;
$rootScope . $watch ( 'user.flags.itemsEnabled' , function ( after , before ) {
if ( alreadyShown ( before , after ) ) return ;
var html = "Congratulations, you have unlocked the Item Store! You can now buy weapons, armor, potions, etc. Read each item's comment for more information." ;
showPopover ( 'div.rewards' , 'Item Store Unlocked' , html , 'left' ) ;
} ) ;
$rootScope . $watch ( 'user.flags.petsEnabled' , function ( after , before ) {
2013-10-13 03:22:56 +00:00
//TODO is this ever used? I think dropsEnabled is the one that's used
2013-09-17 18:07:04 +00:00
if ( alreadyShown ( before , after ) ) return ;
var html = "You have unlocked Pets! You can now buy pets with Gems (note, you replenish Gems with real-life money - so chose your pets wisely!)" ;
showPopover ( '#rewardsTabs' , 'Pets Unlocked' , html , 'left' ) ;
} ) ;
$rootScope . $watch ( 'user.flags.partyEnabled' , function ( after , before ) {
if ( alreadyShown ( before , after ) ) return ;
var html = "Be social, join a party and play Habit with your friends! You'll be better at your habits with accountability partners. Click User -> Options -> Party, and follow the instructions. LFG anyone?" ;
showPopover ( '.user-menu' , 'Party System' , html , 'bottom' ) ;
} ) ;
$rootScope . $watch ( 'user.flags.dropsEnabled' , function ( after , before ) {
if ( alreadyShown ( before , after ) ) return ;
2013-09-17 18:44:02 +00:00
var drop = Helpers . randomVal ( Items . items . pets ) ;
2013-10-16 18:22:22 +00:00
var eggs = User . user . items . eggs || ( User . user . items . eggs = [ ] ) ;
2013-09-17 18:07:04 +00:00
eggs . push ( drop ) ; // FIXME put this on server instead
User . set ( 'items.eggs' , eggs ) ;
$rootScope . modals . dropsEnabled = true ;
} ) ;
$rootScope . $watch ( 'user.items.pets' , function ( after , before ) {
if ( User . user . achievements && User . user . achievements . beastMaster ) return ;
if ( before >= 90 ) {
User . set ( 'achievements.beastMaster' , true ) ;
$ ( '#beastmaster-achievement-modal' ) . modal ( 'show' ) ; // FIXME
}
} ) ;
$rootScope . $watch ( 'user.items' , function ( after , before ) {
if ( User . user . achievements && User . user . achievements . ultimateGear ) return ;
var items = User . user . items ;
if ( + items . weapon >= 6 && + items . armor >= 5 && + items . head >= 5 && + items . shield >= 5 ) {
User . set ( 'achievements.ultimateGear' , true ) ; // FIXME
$ ( '#max-gear-achievement-modal' ) . modal ( 'show' ) ; // FIXME
}
} ) ;
// FIXME how to handle tasks.*.streak?
// FIXME move to tasksCtrl
/ * $ r o o t S c o p e . $ w a t c h ( ' u s e r . t a s k s . * . s t r e a k ' , f u n c t i o n ( i d , a f t e r , b e f o r e ) {
if ( after > 0 ) {
if ( ( after % 21 ) === 0 ) {
user . incr ( 'achievements.streak' , 1 )
return $ ( '#streak-achievement-modal' ) . modal ( 'show' ) ;
} else if ( ( before - after === 1 ) && ( before % 21 === 0 ) ) {
return user . incr ( 'achievements.streak' , - 1 ) ;
}
}
} ) ; * /
2013-09-10 22:06:16 +00:00
2013-09-17 18:44:02 +00:00
return {
initTour : initTour
} ;
2013-09-10 22:06:16 +00:00
}
] ) ;