diff --git a/bower.json b/bower.json index c85155ebdc..48bdd5ff9d 100644 --- a/bower.json +++ b/bower.json @@ -31,7 +31,7 @@ "bootstrap-growl": "git://github.com/ifightcrime/bootstrap-growl.git#master", "bootstrap-tour": "~0.8.1", "habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared.git#develop", - "BrowserQuest": "git://github.com/mozilla/BrowserQuest.git", + "BrowserQuest": "git://github.com/browserquest/BrowserQuest.git", "github-buttons": "git://github.com/mdo/github-buttons.git", "marked": "~0.2.9", "Angular-At-Directive": "git://github.com/snicker/Angular-At-Directive#master", diff --git a/public/audio/danielTheBard/Achievement_Unlocked.mp3 b/public/audio/danielTheBard/Achievement_Unlocked.mp3 new file mode 100644 index 0000000000..539771b46f Binary files /dev/null and b/public/audio/danielTheBard/Achievement_Unlocked.mp3 differ diff --git a/public/audio/danielTheBard/Achievement_Unlocked.ogg b/public/audio/danielTheBard/Achievement_Unlocked.ogg new file mode 100644 index 0000000000..b70b4fe1ec Binary files /dev/null and b/public/audio/danielTheBard/Achievement_Unlocked.ogg differ diff --git a/public/audio/danielTheBard/Chat.mp3 b/public/audio/danielTheBard/Chat.mp3 new file mode 100644 index 0000000000..dd3d8e0995 Binary files /dev/null and b/public/audio/danielTheBard/Chat.mp3 differ diff --git a/public/audio/danielTheBard/Chat.ogg b/public/audio/danielTheBard/Chat.ogg new file mode 100644 index 0000000000..462f1fe63f Binary files /dev/null and b/public/audio/danielTheBard/Chat.ogg differ diff --git a/public/audio/danielTheBard/Daily.mp3 b/public/audio/danielTheBard/Daily.mp3 new file mode 100644 index 0000000000..0252f35975 Binary files /dev/null and b/public/audio/danielTheBard/Daily.mp3 differ diff --git a/public/audio/danielTheBard/Daily.ogg b/public/audio/danielTheBard/Daily.ogg new file mode 100644 index 0000000000..6cb33851ee Binary files /dev/null and b/public/audio/danielTheBard/Daily.ogg differ diff --git a/public/audio/danielTheBard/Item_Drop.mp3 b/public/audio/danielTheBard/Item_Drop.mp3 new file mode 100644 index 0000000000..bfaa6a7171 Binary files /dev/null and b/public/audio/danielTheBard/Item_Drop.mp3 differ diff --git a/public/audio/danielTheBard/Item_Drop.ogg b/public/audio/danielTheBard/Item_Drop.ogg new file mode 100644 index 0000000000..a498bdb166 Binary files /dev/null and b/public/audio/danielTheBard/Item_Drop.ogg differ diff --git a/public/audio/danielTheBard/Level_Up.mp3 b/public/audio/danielTheBard/Level_Up.mp3 new file mode 100644 index 0000000000..6f0e6e1a02 Binary files /dev/null and b/public/audio/danielTheBard/Level_Up.mp3 differ diff --git a/public/audio/danielTheBard/Level_Up.ogg b/public/audio/danielTheBard/Level_Up.ogg new file mode 100644 index 0000000000..fe7988b68d Binary files /dev/null and b/public/audio/danielTheBard/Level_Up.ogg differ diff --git a/public/audio/danielTheBard/Minus_Habit.mp3 b/public/audio/danielTheBard/Minus_Habit.mp3 new file mode 100644 index 0000000000..d29c6d8fe0 Binary files /dev/null and b/public/audio/danielTheBard/Minus_Habit.mp3 differ diff --git a/public/audio/danielTheBard/Minus_Habit.ogg b/public/audio/danielTheBard/Minus_Habit.ogg new file mode 100644 index 0000000000..182c856262 Binary files /dev/null and b/public/audio/danielTheBard/Minus_Habit.ogg differ diff --git a/public/audio/danielTheBard/Plus_Habit.mp3 b/public/audio/danielTheBard/Plus_Habit.mp3 new file mode 100644 index 0000000000..3f43d830ac Binary files /dev/null and b/public/audio/danielTheBard/Plus_Habit.mp3 differ diff --git a/public/audio/danielTheBard/Plus_Habit.ogg b/public/audio/danielTheBard/Plus_Habit.ogg new file mode 100644 index 0000000000..d0874ba48d Binary files /dev/null and b/public/audio/danielTheBard/Plus_Habit.ogg differ diff --git a/public/audio/danielTheBard/Reward.mp3 b/public/audio/danielTheBard/Reward.mp3 new file mode 100644 index 0000000000..58994c86b2 Binary files /dev/null and b/public/audio/danielTheBard/Reward.mp3 differ diff --git a/public/audio/danielTheBard/Reward.ogg b/public/audio/danielTheBard/Reward.ogg new file mode 100644 index 0000000000..31341da2c4 Binary files /dev/null and b/public/audio/danielTheBard/Reward.ogg differ diff --git a/public/audio/danielTheBard/ToDo.mp3 b/public/audio/danielTheBard/ToDo.mp3 new file mode 100644 index 0000000000..50c1e8e32e Binary files /dev/null and b/public/audio/danielTheBard/ToDo.mp3 differ diff --git a/public/audio/danielTheBard/ToDo.ogg b/public/audio/danielTheBard/ToDo.ogg new file mode 100644 index 0000000000..23b8244f38 Binary files /dev/null and b/public/audio/danielTheBard/ToDo.ogg differ diff --git a/public/css/menu.styl b/public/css/menu.styl index 5abfe4dc8c..fcd3652893 100644 --- a/public/css/menu.styl +++ b/public/css/menu.styl @@ -123,7 +123,7 @@ padding-left:0em margin-left:0em margin-right: 0.618em -.toolbar-sync, .toolbar-settings +.toolbar-sync, .toolbar-settings, .toolbar-audio @extend $hrpg-button hrpg-button-color-mixin($color-toolbar) // Notifications icon and dropdown @@ -154,7 +154,7 @@ .toolbar-notifs-no-messages padding: 0.382em 1em // Settings dropdown -.toolbar-settings +.toolbar-settings, .toolbar-audio @extend $hrpg-modal-dropdown-left .toolbar-controls @extend $hrpg-modal-controls @@ -166,7 +166,7 @@ @media screen and (max-width:768px) .toolbar-toggle display: none - .toolbar-mobile, .toolbar-settings + .toolbar-mobile, .toolbar-settings, .toolbar-audio .toolbar-submenu padding-left: 1em display: block @@ -186,4 +186,4 @@ 0% transform: rotate(45deg) 100% - transform: rotate(0deg) \ No newline at end of file + transform: rotate(0deg) diff --git a/public/js/controllers/authCtrl.js b/public/js/controllers/authCtrl.js index 7bd7618890..25f367ca39 100644 --- a/public/js/controllers/authCtrl.js +++ b/public/js/controllers/authCtrl.js @@ -79,7 +79,7 @@ angular.module('authCtrl', []) // Using controller: 'AuthCtrl' it causes problems }); } - } + }; $scope.passwordReset = function(email){ $http.post(API_URL + '/api/v2/user/reset-password', {email:email}) @@ -89,10 +89,14 @@ angular.module('authCtrl', []) .error(function(data){ alert(data.err); }); - } + }; $scope.expandMenu = function(menu) { $scope._expandedMenu = ($scope._expandedMenu == menu) ? null : menu; - } + }; + + $scope.switchAudio = function(bool) { + User.set({"preferences.sound": bool}); + }; } ]); diff --git a/public/js/controllers/notificationCtrl.js b/public/js/controllers/notificationCtrl.js index f014b27539..1188db3759 100644 --- a/public/js/controllers/notificationCtrl.js +++ b/public/js/controllers/notificationCtrl.js @@ -4,13 +4,14 @@ habitrpg.controller('NotificationCtrl', ['$scope', '$rootScope', 'Shared', 'Content', 'User', 'Guide', 'Notification', function ($scope, $rootScope, Shared, Content, User, Guide, Notification) { - $rootScope.$watch('user.stats.hp', function(after, before) { + $rootScope.$watch('user.stats.hp', function (after, before) { if (after <= 0){ $rootScope.openModal('death', {keyboard:false, backdrop:'static'}); } if (after == before) return; if (User.user.stats.lvl == 0) return; Notification.hp(after - before, 'hp'); + if (after < 0) $rootScope.playSound('Minus_Habit'); }); $rootScope.$watch('user.stats.exp', function(after, before) { @@ -19,6 +20,10 @@ habitrpg.controller('NotificationCtrl', Notification.exp(after - before); }); + $rootScope.$watch('user.achievements', function(){ + $rootScope.playSound('Achievement_Unlocked'); + }, true); + $rootScope.$watch('user.stats.gp', function(after, before) { if (after == before) return; if (User.user.stats.lvl == 0) return; @@ -53,6 +58,7 @@ habitrpg.controller('NotificationCtrl', $rootScope.$watch('user._tmp.drop', function(after, before){ // won't work when getting the same item twice? if (after == before || !after) return; + $rootScope.playSound('Achievement_Unlocked'); if (after.type !== 'gear') { var type = (after.type == 'Food') ? 'food' : (after.type == 'HatchingPotion') ? 'hatchingPotions' : // can we use camelcase and remove this line? @@ -79,12 +85,14 @@ habitrpg.controller('NotificationCtrl', // Keep support for another type of drops that might be added Notification.drop(User.user._tmp.drop.dialog); } + $rootScope.playSound('Item_Drop'); }); $rootScope.$watch('user.achievements.streak', function(after, before){ if(before == undefined || after == before || after < before) return; if (User.user.achievements.streak > 1) { Notification.streak(User.user.achievements.streak); + $rootScope.playSound('Achievement_Unlocked'); } else { $rootScope.openModal('achievements/streak'); @@ -137,6 +145,7 @@ habitrpg.controller('NotificationCtrl', if (after == before) return; if (after > before) { Notification.lvl(); + $rootScope.playSound('Level_Up'); } }); diff --git a/public/js/controllers/rootCtrl.js b/public/js/controllers/rootCtrl.js index 2186fe9774..7091331d29 100644 --- a/public/js/controllers/rootCtrl.js +++ b/public/js/controllers/rootCtrl.js @@ -49,6 +49,15 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ return style; } + $rootScope.playSound = function(id){ + if (!user.preferences.sound) return; + var theme = user.preferences.soundTheme; + var file = 'audio/' + theme + '/' + id; + document.getElementById('oggSource').src = file + '.ogg'; + document.getElementById('mp3Source').src = file + '.mp3'; + document.getElementById('sound').load(); + } + // count pets, mounts collected totals, etc $rootScope.countExists = function(items) {return _.reduce(items,function(m,v){return m+(v?1:0)},0)} diff --git a/public/js/controllers/settingsCtrl.js b/public/js/controllers/settingsCtrl.js index bff15f4911..37b408d962 100644 --- a/public/js/controllers/settingsCtrl.js +++ b/public/js/controllers/settingsCtrl.js @@ -142,5 +142,10 @@ habitrpg.controller('SettingsCtrl', window.location.href = '/api/v2/coupons?limit='+codes.count+'&_id='+User.user._id+'&apiToken='+User.user.apiToken; }) } + + // Audio list of themes + $scope.soundThemes = { + 'danielTheBard': 'Daniel the Bard' + }; } ]); diff --git a/public/js/controllers/tasksCtrl.js b/public/js/controllers/tasksCtrl.js index 1bde5c0bed..130407f9ab 100644 --- a/public/js/controllers/tasksCtrl.js +++ b/public/js/controllers/tasksCtrl.js @@ -1,11 +1,25 @@ "use strict"; -habitrpg.controller("TasksCtrl", ['$scope', '$location', 'User','Notification', '$http', 'API_URL', '$timeout', 'Shared', - function($scope, $location, User, Notification, $http, API_URL, $timeout, Shared) { +habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','Notification', '$http', 'API_URL', '$timeout', 'Shared', + function($scope, $rootScope, $location, User, Notification, $http, API_URL, $timeout, Shared) { $scope.obj = User.user; // used for task-lists $scope.user = User.user; $scope.score = function(task, direction) { + switch (task.type) { + case 'reward': + $rootScope.playSound('Reward'); + break; + case 'daily': + $rootScope.playSound('Daily'); + break; + case 'todo': + $rootScope.playSound('ToDo'); + break; + default: + if (direction === 'down') $rootScope.playSound('Minus_Habit'); + else if (direction === 'up') $rootScope.playSound('Plus_Habit'); + } User.user.ops.score({params:{id: task.id, direction:direction}}) }; @@ -143,6 +157,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$location', 'User','Notification', $scope.buy = function(item) { User.user.ops.buy({params:{key:item.key}}); + $rootScope.playSound('Reward'); }; diff --git a/src/models/user.js b/src/models/user.js index 2877256b14..9c3718c2a7 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -255,6 +255,8 @@ var UserSchema = new Schema({ skin: {type:String, 'default':'915533'}, shirt: {type: String, 'default': 'blue'}, timezoneOffset: Number, + sound: Boolean, + soundTheme: {type:String, 'default':'danielTheBard'}, language: String, automaticAllocation: Boolean, allocationMode: {type:String, enum: ['flat','classbased','taskbased'], 'default': 'flat'}, diff --git a/views/index.jade b/views/index.jade index 22883c65a2..a6d92ad08f 100644 --- a/views/index.jade +++ b/views/index.jade @@ -34,4 +34,4 @@ html(ng-app="habitrpg", ng-controller="RootCtrl", ng-class='{"applying-action":a .col-md-12.exp-chart(ng-show='charts.exp') #main(ui-view) - include ./shared/footer \ No newline at end of file + include ./shared/footer diff --git a/views/shared/footer.jade b/views/shared/footer.jade index a013c8135f..106e29547f 100644 --- a/views/shared/footer.jade +++ b/views/shared/footer.jade @@ -78,3 +78,8 @@ footer.footer(ng-controller='FooterCtrl') a.btn.btn-default(ng-click='addOneLevel()') +1 Level div(ng-init='deferredScripts()') + + // Load audio last + audio#sound(autoplay) + source#oggSource(type="audio/ogg") + source#mp3Source(type="audio/mp3") diff --git a/views/shared/header/menu.jade b/views/shared/header/menu.jade index ec3c079167..9babfcff5d 100644 --- a/views/shared/header/menu.jade +++ b/views/shared/header/menu.jade @@ -136,6 +136,28 @@ nav.toolbar(ng-controller='AuthCtrl', ng-class='{active: isToolbarHidden}') //-a(ng-click='') Clear all li.toolbar-controls-button a(ng-click='expandMenu(null)')=env.t('close') + li.toolbar-audio + a(ng-click='expandMenu("music")') + span.glyphicon.glyphicon-music + div(ng-if='_expandedMenu=="music"') + h4=env.t('music') + div + ul.toolbar-submenu(ng-click='expandMenu(null)') + li + label=env.t('switchSound') + a(ng-if='user.preferences.sound', ng-click='switchAudio(false)') + span.glyphicon.glyphicon-volume-down(tooltip=env.t('soundOff')) + a(ng-if='!user.preferences.sound', ng-click='switchAudio(true)') + span.glyphicon.glyphicon-volume-off(tooltip=env.t('soundOn')) + li + label(for='audioTheme')=env.t('selectTheme') + select#audioTheme( + style='width:140px', + ng-controller='SettingsCtrl', + ng-model='user.preferences.soundTheme', + ng-options='k as v for (k , v) in soundThemes', + ng-change='set("preferences.soundTheme", user.preferences.soundTheme)' + ) li.toolbar-sync a(ng-click='User.sync()', popover=env.t('sync'),popover-placement='bottom',popover-trigger='mouseenter') span.glyphicon.glyphicon-refresh @@ -181,4 +203,4 @@ nav.toolbar(ng-controller='AuthCtrl', ng-class='{active: isToolbarHidden}') span {{Shared.silver(user.stats.gp)}} ul.toolbar-bailey(ng-class='{inactive: !_expandedMenu}') li.toolbar-bailey-container(ng-if='user.flags.newStuff') - .npc_bailey.npc_bailey_head(popover=env.t('psst'), popover-trigger='mouseenter', popover-placement='right', ng-click='openModal("newStuff")') \ No newline at end of file + .npc_bailey.npc_bailey_head(popover=env.t('psst'), popover-trigger='mouseenter', popover-placement='right', ng-click='openModal("newStuff")')