diff --git a/package.json b/package.json index 8d7d1f36d8..9d1794abd6 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "version": "0.0.0-152", "main": "./src/server.js", "dependencies": { - "habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared#master", + "habitrpg-shared": "git://github.com/HabitRPG/habitrpg-shared#mounts", "derby-auth": "git://github.com/lefnire/derby-auth#master", "connect-mongo": "*", "passport-facebook": "~1.0.0", diff --git a/public/css/inventory.styl b/public/css/inventory.styl index fe5f84fd22..3ba84b2bb6 100644 --- a/public/css/inventory.styl +++ b/public/css/inventory.styl @@ -65,10 +65,18 @@ menu.pets div .Pet_Currency_Gem2x {background-position: -55px -513px; width: 34px; height: 30px} .Pet_Currency_Gem1x {background-position: -63px -542px; width: 19px; height: 17px} -.inventory-list p +.inventory-list + p //display: none -.inventory-list li + li clear:both + button.customize-option + position:relative + .stack-count + position:absolute + bottom:-6px + right:-9px + .pets-menu > div display:inline-block vertical-align:top @@ -90,6 +98,17 @@ menu.pets div width:6em margin-top:-.5em +// This adds feeding progress bars to pets. If we have any issues with `menu.pets > button`, revisit +menu.pets .customize-menu + button + position: relative + .progress + width: 60% + position: absolute + bottom: -25px + left: 20% + height: 5px + .pet-button border: none background: none white diff --git a/public/js/app.js b/public/js/app.js index cdb890c820..599d5255f1 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -128,7 +128,8 @@ window.habitrpg = angular.module('habitrpg', // Options > Inventory .state('options.inventory', { url: '/inventory', - templateUrl: "partials/options.inventory.html" + templateUrl: "partials/options.inventory.html", + controller: 'InventoryCtrl' }) .state('options.inventory.inventory', { url: '/inventory', diff --git a/public/js/controllers/inventoryCtrl.js b/public/js/controllers/inventoryCtrl.js index 6dc8d16955..1b7a443ce5 100644 --- a/public/js/controllers/inventoryCtrl.js +++ b/public/js/controllers/inventoryCtrl.js @@ -1,18 +1,27 @@ -habitrpg.controller("InventoryCtrl", ['$scope', 'User', - function($scope, User) { +habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User', 'API_URL', '$http', 'Notification', + function($rootScope, $scope, User, API_URL, $http, Notification) { + + var user = User.user; // convenience vars since these are accessed frequently - $scope.userEggs = User.user.items.eggs; - $scope.userHatchingPotions = User.user.items.hatchingPotions; $scope.selectedEgg = null; // {index: 1, name: "Tiger", value: 5} $scope.selectedPotion = null; // {index: 5, name: "Red", value: 3} + $scope.petCount = _.size(User.user.items.pets); + $scope.totalPets = _.size($scope.Items.eggs) * _.size($scope.Items.hatchingPotions); - $scope.chooseEgg = function(egg, $index){ - if ($scope.selectedEgg && $scope.selectedEgg.index == $index) { + var countItems = function(items) { + return _.reduce(items,function(m,v){return m+v;},0); + } + $scope.$watch('user.items.pets', function(pets){ $scope.petCount = countItems(pets); }); + $scope.$watch('user.items.eggs', function(eggs){ $scope.eggCount = countItems(eggs); }); + $scope.$watch('user.items.hatchingPotions', function(pots){ $scope.potCount = countItems(pots); }); + + $scope.chooseEgg = function(egg){ + if ($scope.selectedEgg && $scope.selectedEgg.name == egg) { return $scope.selectedEgg = null; // clicked same egg, unselect } - var eggData = _.defaults({index:$index}, egg); + var eggData = _.findWhere(window.habitrpgShared.items.items.eggs, {name:egg}); if (!$scope.selectedPotion) { $scope.selectedEgg = eggData; } else { @@ -20,13 +29,12 @@ habitrpg.controller("InventoryCtrl", ['$scope', 'User', } } - $scope.choosePotion = function(potion, $index){ - if ($scope.selectedPotion && $scope.selectedPotion.index == $index) { + $scope.choosePotion = function(potion){ + if ($scope.selectedPotion && $scope.selectedPotion.name == potion) { return $scope.selectedPotion = null; // clicked same egg, unselect } // we really didn't think through the way these things are stored and getting passed around... var potionData = _.findWhere(window.habitrpgShared.items.items.hatchingPotions, {name:potion}); - potionData = _.defaults({index:$index}, potionData); if (!$scope.selectedEgg) { $scope.selectedPotion = potionData; } else { @@ -34,54 +42,52 @@ habitrpg.controller("InventoryCtrl", ['$scope', 'User', } } + $scope.chooseFood = function(food){ + $scope.selectedFood = $scope.Items.food[food]; + } + $scope.sellInventory = function() { + // TODO DRY this if ($scope.selectedEgg) { - $scope.userEggs.splice($scope.selectedEgg.index, 1); + user.items.eggs[$scope.selectedEgg.name]--; User.setMultiple({ - 'items.eggs': $scope.userEggs, + 'items.eggs': user.items.eggs, 'stats.gp': User.user.stats.gp + $scope.selectedEgg.value }); $scope.selectedEgg = null; } else if ($scope.selectedPotion) { - $scope.userHatchingPotions.splice($scope.selectedPotion.index, 1); + user.items.hatchingPotions[$scope.selectedPotion.name]--; User.setMultiple({ - 'items.hatchingPotions': $scope.userHatchingPotions, + 'items.hatchingPotions': user.items.hatchingPotions, 'stats.gp': User.user.stats.gp + $scope.selectedPotion.value }); $scope.selectedPotion = null; + } else if ($scope.selectedFood) { + user.items.food[$scope.selectedFood.name]--; + User.setMultiple({ + 'items.food': user.items.food, + 'stats.gp': User.user.stats.gp + $scope.selectedFood.value + }); + $scope.selectedFood = null; } + } - $scope.ownsPet = function(egg, potion){ - if (!egg || !potion) return; - var pet = egg.name + '-' + potion; - return User.user.items.pets && ~User.user.items.pets.indexOf(pet) - } - - $scope.selectableInventory = function(egg, potion, $index) { - if (!egg || !potion) return; - // FIXME this isn't updating the view for some reason - //if ($scope.selectedEgg && $scope.selectedEgg.index == $index) return 'selectableInventory'; - //if ($scope.selectedPotion && $scope.selectedPotion.index == $index) return 'selectableInventory'; - if (!$scope.ownsPet(egg, potion)) return 'selectableInventory'; + $scope.ownedItems = function(inventory){ + return _.pick(inventory, function(v,k){return v>0;}); } $scope.hatch = function(egg, potion){ - if ($scope.ownsPet(egg, potion.name)){ - return alert("You already have that pet, hatch a different combo.") - } - var pet = egg.name + '-' + potion.name; - $scope.userEggs.splice(egg.index, 1); - $scope.userHatchingPotions.splice(potion.index, 1); + var pet = egg.name+"-"+potion.name; + if (user.items.pets[pet]) + return alert("You already have that pet, hatch a different combo."); - if(!User.user.items.pets) User.user.items.pets = []; - User.user.items.pets.push(pet); + var setObj = {}; + setObj['items.pets.' + pet] = 5; + setObj['items.eggs.' + egg.name] = user.items.eggs[egg.name] - 1; + setObj['items.hatchingPotions.' + potion.name] = user.items.hatchingPotions[potion.name] - 1; - User.log([ - { op: 'set', data: {'items.pets': User.user.items.pets} }, - { op: 'set', data: {'items.eggs': $scope.userEggs} }, - { op: 'set', data: {'items.hatchingPotions': $scope.userHatchingPotions} } - ]); + User.setMultiple(setObj); alert("Your egg hatched! Visit your stable to equip your pet."); @@ -89,4 +95,68 @@ habitrpg.controller("InventoryCtrl", ['$scope', 'User', $scope.selectedPotion = null; } - }]); \ No newline at end of file + $scope.buy = function(type, item){ + var gems = User.user.balance * 4; + if(gems < item.value) return $rootScope.modals.buyGems = true; + var string = (type == 'hatchingPotion') ? 'hatching potion' : type; // give hatchingPotion a space + var message = "Buy this " + string + " with " + item.value + " of your " + gems + " Gems?" + if(confirm(message)){ + $http.post(API_URL + '/api/v1/market/buy?type=' + type, item) + .success(function(data){ + User.user.items = data.items; + }); + } + } + + $scope.choosePet = function(egg, potion){ + var pet = egg + '-' + potion; + + // Feeding Pet + if ($scope.selectedFood) { + var setObj = {}; + var userPets = user.items.pets; + + // Saddling a pet + if ($scope.selectedFood.name == 'Saddle') { + if (userPets[pet] < 150) + return Notification.text(egg+" is not strong enough yet to saddle."); + if (!confirm('Saddle ' + pet + '?')) return; + userPets[pet] = 0; + setObj['items.mounts.' + pet] = true; + Notification.text('You have tamed '+egg+", let's go for a ride!"); + } else { + if (userPets[pet] >= 150) + return Notification.text(egg+" has become very strong and wild, try using a saddle and something might happen."); + if (!confirm('Feed ' + pet + ' a ' + $scope.selectedFood.name + '?')) return; + if ($scope.selectedFood.target == potion) { + userPets[pet] += 50; // FIXME change this to 5 before we're live + Notification.text(egg+' really likes the '+$scope.selectedFood.name+'!'); + } else { + userPets[pet] += 2; + Notification.text(egg+' eats the '+$scope.selectedFood.name+" but doesn't seem to enjoy it."); + } + } + setObj['items.pets.' + pet] = userPets[pet]; + setObj['items.food.' + $scope.selectedFood.name] = user.items.food[$scope.selectedFood.name] - 1; + User.setMultiple(setObj); + $scope.selectedFood = null; + + // Selecting Pet + } else { + var userCurrentPet = User.user.items.currentPet; + if(userCurrentPet && userCurrentPet == pet){ + User.user.items.currentPet = null; + }else{ + User.user.items.currentPet = pet; + } + User.set('items.currentPet', User.user.items.currentPet); + } + } + + $scope.chooseMount = function(egg, potion) { + var mount = egg + '-' + potion; + User.set('items.currentMount', (user.items.currentMount == mount) ? null : mount); + } + + } +]); \ No newline at end of file diff --git a/public/js/controllers/marketCtrl.js b/public/js/controllers/marketCtrl.js deleted file mode 100644 index c0cf429539..0000000000 --- a/public/js/controllers/marketCtrl.js +++ /dev/null @@ -1,37 +0,0 @@ -habitrpg.controller("MarketCtrl", ['$rootScope', '$scope', 'User', 'API_URL', '$http', - function($rootScope, $scope, User, API_URL, $http) { - - $scope.eggs = window.habitrpgShared.items.items.pets; - $scope.hatchingPotions = window.habitrpgShared.items.items.hatchingPotions; - $scope.userEggs = User.user.items.eggs; - $scope.userHatchingPotions = User.user.items.hatchingPotions; - - $scope.buy = function(type, item){ - var gems = User.user.balance * 4, - store = type === 'egg' ? $scope.userEggs : $scope.userHatchingPotions, - storePath = type === 'egg' ? 'items.eggs' : 'items.hatchingPotions' - - if(gems < item.value){ - return $rootScope.modals.buyGems = true; - } - - var message = "Buy this " + (type == 'egg' ? 'egg' : 'hatching potion') + " with " + item.value + " of your " + gems + " Gems?" - - if(confirm(message)){ - $http.post(API_URL + '/api/v1/market/buy?type=' + type, item) - .success(function(data){ - // don't know what's going on, but trying to work with the returned data (a) isn't updating the ui, (b) isnt' - // stickign between refreshes until a force-refresh is called (user._v--). - User.user._v--; - User.log({}); - //User.user.balance = data.balance; - store.push(type === 'egg' ? item : item.name); - //$scope.items = data.items.eggs; // FIXME this isn't updating the UI - }).error(function(data){ - alert(data); - console.error(data); - }); - } - } - - }]); \ No newline at end of file diff --git a/public/js/controllers/notificationCtrl.js b/public/js/controllers/notificationCtrl.js index 618964f70f..4eb64caa9b 100644 --- a/public/js/controllers/notificationCtrl.js +++ b/public/js/controllers/notificationCtrl.js @@ -43,8 +43,8 @@ habitrpg.controller('NotificationCtrl', $rootScope.modals.achievements.ultimateGear = true; }); - $rootScope.$watch('user.items.pets.length', function(after, before){ - if(after === before || after < 90) return; + $rootScope.$watch('user.items.pets', function(after, before){ + if(_.size(after) === _.size(before) || _.size(after) < 90) return; User.user.achievements.beastMaster = true; $rootScope.modals.achievements.beastMaster = true; }) diff --git a/public/js/controllers/petsCtrl.js b/public/js/controllers/petsCtrl.js deleted file mode 100644 index 7d4e6ba5ed..0000000000 --- a/public/js/controllers/petsCtrl.js +++ /dev/null @@ -1,32 +0,0 @@ -habitrpg.controller("PetsCtrl", ['$scope', 'User', - function($scope, User) { - - $scope.userPets = User.user.items.pets; - $scope.userCurrentPet = User.user.items.currentPet; - $scope.pets = window.habitrpgShared.items.items.pets; - $scope.hatchingPotions = window.habitrpgShared.items.items.hatchingPotions; - $scope.totalPets = $scope.pets.length * $scope.hatchingPotions.length; - - $scope.hasPet = function(name, potion){ - if (!$scope.userPets) return false; - return _.contains($scope.userPets, name + '-' + potion) ? true : false; - } - - $scope.isCurrentPet = function(name, potion){ - if (!$scope.userCurrentPet || !$scope.userPets) return false; - return $scope.userCurrentPet.str === (name + '-' + potion); - } - - $scope.choosePet = function(name, potion){ - if($scope.userCurrentPet && $scope.userCurrentPet.str === (name + '-' + potion)){ - $scope.userCurrentPet = null; - }else{ - var pet = _.find($scope.pets, {name: name}); - pet.modifier = potion; - pet.str = name + '-' + potion; - $scope.userCurrentPet = pet; - } - User.set('items.currentPet', $scope.userCurrentPet); - } - - }]); \ No newline at end of file diff --git a/public/js/controllers/rootCtrl.js b/public/js/controllers/rootCtrl.js index eab96974a5..98b09b2401 100644 --- a/public/js/controllers/rootCtrl.js +++ b/public/js/controllers/rootCtrl.js @@ -10,6 +10,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ $rootScope.User = User; $rootScope.user = User.user; $rootScope.settings = User.settings; + $rootScope.Items = window.habitrpgShared.items.items; // Angular UI Router $rootScope.$state = $state; diff --git a/public/js/filters/filters.js b/public/js/filters/filters.js index 65223c5957..9d2255d9e2 100644 --- a/public/js/filters/filters.js +++ b/public/js/filters/filters.js @@ -3,8 +3,9 @@ angular.module('habitrpg') return function (gp) { return Math.floor(gp); } - }).filter('silver', function () { + }) + .filter('silver', function () { return function (gp) { return Math.floor((gp - Math.floor(gp))*100); } - }); + }) \ No newline at end of file diff --git a/public/js/services/guideServices.js b/public/js/services/guideServices.js index 3e709ce4c5..964ccdffc9 100644 --- a/public/js/services/guideServices.js +++ b/public/js/services/guideServices.js @@ -96,13 +96,6 @@ angular.module('guideServices', []). showPopover('div.rewards', 'Item Store Unlocked', html, 'left'); }); - $rootScope.$watch('user.flags.petsEnabled', function(after, before) { - //TODO is this ever used? I think dropsEnabled is the one that's used - 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?"; @@ -111,10 +104,8 @@ angular.module('guideServices', []). $rootScope.$watch('user.flags.dropsEnabled', function(after, before) { if (alreadyShown(before, after)) return; - var drop = Helpers.randomVal(Items.items.pets); - var eggs = User.user.items.eggs || []; - eggs.push(drop); // FIXME put this on server instead - User.set('items.eggs', eggs); + var eggs = User.user.items.eggs || {}; + eggs['Wolf-Base'] = 5; // This is also set on the server $rootScope.modals.dropsEnabled = true; }); diff --git a/public/manifest.json b/public/manifest.json index ee6d559b95..83dd7176bd 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -48,9 +48,7 @@ "js/controllers/filtersCtrl.js", "js/controllers/userCtrl.js", "js/controllers/groupsCtrl.js", - "js/controllers/petsCtrl.js", "js/controllers/inventoryCtrl.js", - "js/controllers/marketCtrl.js", "js/controllers/footerCtrl.js", "js/controllers/challengesCtrl.js", "js/controllers/adminCtrl.js" diff --git a/src/controllers/groups.js b/src/controllers/groups.js index 4aefd73e08..41ac5ab55f 100644 --- a/src/controllers/groups.js +++ b/src/controllers/groups.js @@ -60,9 +60,7 @@ api.updateMember = function(req, res) { member.balance += (req.body.contributor.level - (member.contributor.level || 0))*.5 // +2 gems per tier } _.merge(member, _.pick(req.body, 'contributor')); - if (!member.items.pets) member.items.pets = []; - var i = member.items.pets.indexOf('Dragon-Hydra'); - if (!~i && member.contributor.level >= 6) member.items.pets.push('Dragon-Hydra'); + if (member.contributor.level >= 6 && !member.items.pets['Dragon-Hydra']) member.items.pets['Dragon-Hydra'] = 5; member.save(cb); } ], function(err, saved){ diff --git a/src/controllers/user.js b/src/controllers/user.js index b67c61fe42..560b5a7776 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -22,17 +22,11 @@ api.marketBuy = function(req, res, next){ type = req.query.type, item = req.body; - if (!_.contains(['hatchingPotion', 'egg'], req.query.type)) - return res.json(400, {err: "Type must be in 'hatchingPotion' or 'egg'"}); - var item; - if (type == 'egg'){ - if (!user.items && !user.items.eggs) user.items.eggs = []; - user.items.eggs.push(item); - } else { - if (!user.items && !user.items.hatchingPotions) user.items.hatchingPotions = []; - user.items.hatchingPotions.push(item.name); - } - user.markModified('items'); // I still don't get when this is necessary and when not.. + if (!_.contains(['hatchingPotion', 'egg', 'food'], type)) + return res.json(400, {err: "Type must be 'hatchingPotion', 'egg', or 'food'"}); + type = (type == 'food' ? type : type + 's'); // I'm stupid, we're passing up 'hatchingPotion' but we need 'hatchingPotions' + if (!user.items[type][item.name]) user.items[type][item.name] = 0; + user.items[type][item.name]++; user.balance -= (item.value/4); user.save(function(err, saved){ if (err) return res.json(500, {err:err}); @@ -270,30 +264,21 @@ api.updateUser = function(req, res, next) { acceptableAttrs = 'tasks. achievements. filters. flags. invitations. items. lastCron party. preferences. profile. stats. tags custom.'.split(' '); _.each(req.body, function(v, k) { - if ((_.find(acceptableAttrs, function(attr) { - return k.indexOf(attr) === 0; - })) != null) { - if (_.isObject(v)) { - errors.push("Value for " + k + " was an object. Be careful here, you could clobber stuff."); - } + var found = _.find(acceptableAttrs, function(attr) { return k.indexOf(attr) == 0; }) + if (found) { +// if (_.isObject(v)) { +// errors.push("Value for " + k + " was an object. Be careful here, you could clobber stuff."); +// } helpers.dotSet(k, v, user); } else { errors.push("path `" + k + "` was not saved, as it's a protected path. Make sure to send `PUT /api/v1/user` request bodies as `{'set.this.path':value}` instead of `{set:{this:{path:value}}}`"); } return true; }); - return user.save(function(err) { - if (!_.isEmpty(errors)) { - return res.json(500, { - err: errors - }); - } - if (err) { - return res.json(500, { - err: err - }); - } - return res.json(200, user); + user.save(function(err) { + if (!_.isEmpty(errors)) return res.json(500, {err: errors}); + if (err) {return res.json(500, {err: err})} + res.json(200, user); }); }; diff --git a/views/options/inventory/inventory.jade b/views/options/inventory/inventory.jade index 37be78f7b2..95b5ff2be0 100644 --- a/views/options/inventory/inventory.jade +++ b/views/options/inventory/inventory.jade @@ -1,25 +1,38 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html') - .row-fluid(ng-controller='InventoryCtrl') + .row-fluid .span6.border-right h2 Inventory p.well Click an egg to see usable potions highlighted in green and then click one of the highlighted potions to hatch your pet. If no potions are highlighted, click that egg again to deselect it, and instead click a potion first to have the usable eggs highlighted. You can also sell unwanted drops to Alexander the Merchant. menu.inventory-list(type='list') + li.customize-menu - menu.pets-menu(label='Eggs ({{userEggs.length}})') - p(ng-show='userEggs.length < 1') You don't have any eggs yet. - div(ng-repeat='egg in userEggs track by $index') - button.customize-option(tooltip='{{egg.text}}', ng-click='chooseEgg(egg, $index)', class='Pet_Egg_{{egg.name}}', ng-class='selectableInventory(egg, selectedPotion.name, $index)') - p {{egg.text}} + menu.pets-menu(label='Eggs ({{eggCount}})') + p(ng-show='user.items.eggs.length < 1') You don't have any eggs yet. + div(ng-repeat='(egg,points) in ownedItems(user.items.eggs)') + //TODO move positioning this styling to css + button.customize-option(tooltip='{{Items.eggs[egg].text}}', ng-click='chooseEgg(egg)', class='Pet_Egg_{{egg}}', ng-class='{selectableInventory: selectedPotion && !user.items.pets[egg+"-"+selectedPotion.name]}') + .badge.badge-info.stack-count {{points}} + p {{Items.eggs[egg].text}} + li.customize-menu - menu.hatchingPotion-menu(label='Hatching Potions ({{userHatchingPotions.length}})') - p(ng-show='userHatchingPotions.length < 1') You don't have any hatching potions yet. - div(ng-repeat='hatchingPotion in userHatchingPotions track by $index') - button.customize-option(tooltip='{{hatchingPotion}}', ng-click='choosePotion(hatchingPotion, $index)', class='Pet_HatchingPotion_{{hatchingPotion}}', ng-class='selectableInventory(selectedEgg, hatchingPotion, $index)') - p {{hatchingPotion}} + menu.hatchingPotion-menu(label='Hatching Potions ({{potCount}})') + p(ng-show='potCount < 1') You don't have any hatching potions yet. + div(ng-repeat='(pot,points) in ownedItems(user.items.hatchingPotions)') + button.customize-option(tooltip='{{pot}}', ng-click='choosePotion(pot)', class='Pet_HatchingPotion_{{pot}}', ng-class='{selectableInventory: selectedEgg && !user.items.pets[selectedEgg.name+"-"+pot]}') + .badge.badge-info.stack-count {{points}} + p {{pot}} + + li.customize-menu + menu.food-menu(label='Food ({{foodCount}})') + p(ng-show='foodCount < 1') You don't have any food yet. + div(ng-repeat='(food,points) in ownedItems(user.items.food)') + button.customize-option(tooltip='{{food}}', ng-click='chooseFood(food)', class='Pet_Food_{{food}}') + .badge.badge-info.stack-count {{points}} + p {{food}} .span6 h2 Market - .row-fluid(ng-controller='MarketCtrl') + .row-fluid table.NPC-Alex-container tr td @@ -37,19 +50,27 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html') | Sell {{selectedEgg.name}} for {{selectedEgg.value}} GP button.btn.btn-primary(ng-show='selectedPotion', ng-click='sellInventory()') | Sell {{selectedPotion.name}} for {{selectedPotion.value}} GP + button.btn.btn-primary(ng-show='selectedFood', ng-click='sellInventory()') + | Sell {{selectedFood.name}} for {{selectedFood.value}} GP menu.inventory-list(type='list') li.customize-menu menu.pets-menu(label='Eggs') - div(ng-repeat='egg in eggs track by $index') + div(ng-repeat='egg in Items.eggs') button.customize-option(tooltip='{{egg.text}} - {{egg.value}} Gem(s)', ng-click='buy("egg", egg)', class='Pet_Egg_{{egg.name}}') p {{egg.text}} li.customize-menu menu.pets-menu(label='Hatching Potions') - div(ng-repeat='hatchingPotion in hatchingPotions track by $index') - button.customize-option(tooltip='{{hatchingPotion.text}} - {{hatchingPotion.value}} Gem(s)', ng-click='buy("hatchingPotion", hatchingPotion)', class='Pet_HatchingPotion_{{hatchingPotion.name}}') - p {{hatchingPotion.text}} + div(ng-repeat='pot in Items.hatchingPotions') + button.customize-option(tooltip='{{pot.text}} - {{pot.value}} Gem(s)', ng-click='buy("hatchingPotion", pot)', class='Pet_HatchingPotion_{{pot.name}}') + p {{pot.text}} + + li.customize-menu + menu.pets-menu(label='Food') + div(ng-repeat='food in Items.food') + button.customize-option(tooltip='{{food.text}} - {{food.value}} Gem(s)', ng-click='buy("food", food)', class='Pet_Food_{{food.name}}') + p {{food.text}} diff --git a/views/options/inventory/stable.jade b/views/options/inventory/stable.jade index 042970aed9..f95c00bd25 100644 --- a/views/options/inventory/stable.jade +++ b/views/options/inventory/stable.jade @@ -1,33 +1,51 @@ script(type='text/ng-template', id='partials/options.inventory.stable.html') - .stable(ng-controller='PetsCtrl') + .stable .NPC-Matt .popover.static-popover.fade.right.in(style='max-width: 550px; margin-left: 10px;') .arrow h3.popover-title a(target='_blank', href='http://www.kickstarter.com/profile/mattboch') Matt Boch .popover-content - p - | Welcome to the Stable! I'm Matt, the beast master. Choose a pet here to venture at your side. They aren't much help yet, but I forsee a time when they're able to - a(href='https://trello.com/card/mounts/50e5d3684fe3a7266b0036d6/221') grow into powerful steeds - | ! Until that day, - a(target='_blank', href='https://f.cloud.github.com/assets/2374703/164631/3ed5fa6c-78cd-11e2-8743-f65ac477b55e.png') have a look-see - | at all the pets you can collect. - h4 {{userPets.length}} / {{totalPets}} Pets Found + p. + Welcome to the Stable! I'm Matt, the beast master. Choose a pet here to venture at your side. They aren't much help yet, but I forsee a time when they're able to grow into powerful steeds! Until that day, have a look-see at all the pets you can collect. + h4 {{petCount}} / {{totalPets}} Pets Found menu.pets(type='list') - li.customize-menu(ng-repeat='pet in pets') + li.customize-menu(ng-repeat='egg in Items.eggs') menu - div(ng-repeat='potion in hatchingPotions', tooltip='{{potion.name}} {{pet.name}}') - button(class="pet-button Pet-{{pet.name}}-{{potion.name}}", ng-show='hasPet(pet.name, potion.name)', ng-class="{active: isCurrentPet(pet.name, potion.name)}", ng-click='choosePet(pet.name, potion.name)') - button(class="pet-button pet-not-owned", ng-hide='hasPet(pet.name, potion.name)') + div(ng-repeat='potion in Items.hatchingPotions', tooltip='{{potion.name}} {{egg.name}}', ng-init='pet = egg.name+"-"+potion.name') + button(class="pet-button Pet-{{pet}}", ng-if='user.items.pets[pet]>0', ng-class='{active: user.items.currentPet == pet}', ng-click='choosePet(egg.name, potion.name)') + .progress(ng-class='{"progress-success": user.items.pets[pet]<150}') + .bar(style="width: {{user.items.pets[pet]/1.5}}%;") + button(class="pet-button pet-not-owned", ng-if='!user.items.pets[pet]') img(src='/bower_components/habitrpg-shared/img/PixelPaw.png') h4 Rare Pets menu div - button(ng-if='hasPet("Wolf", "Veteran")', class="pet-button Pet-Wolf-Veteran", ng-class='{active: isCurrentPet("Wolf", "Veteran")}', ng-click='choosePet("Wolf", "Veteran")', tooltip='Veteran Wolf') - button(ng-if='hasPet("Wolf", "Cerberus")', class="pet-button Pet-Wolf-Cerberus", ng-class='{active: isCurrentPet("Wolf", "Cerberus")}', ng-click='choosePet("Wolf", "Cerberus")', tooltip='Cerberus Pup') - button(ng-if='hasPet("Dragon", "Hydra")', class="pet-button Pet-Dragon-Hydra", ng-class='{active: isCurrentPet("Dragon", "Hydra")}', ng-click='choosePet("Dragon", "Hydra")', tooltip='Hydra Pet') + button(ng-if='user.items.pets["Wolf-Veteran"]', class="pet-button Pet-Wolf-Veteran", ng-class='{active: user.items.currentPet == "Wolf-Veteran")}', ng-click='choosePet("Wolf", "Veteran")', tooltip='Veteran Wolf') + button(ng-if='user.items.pets["Wolf-Cerberus"]', class="pet-button Pet-Wolf-Cerberus", ng-class='{active: user.items.currentPet == "Wolf-Cerberus")}', ng-click='choosePet("Wolf", "Cerberus")', tooltip='Cerberus Pup') + button(ng-if='user.items.pets["Dragon-Hydra"]', class="pet-button Pet-Dragon-Hydra", ng-class='{active: user.items.currentPet == "Dragon-Hydra")}', ng-click='choosePet("Dragon", "Hydra")', tooltip='Hydra Pet') a(target='_blank', href='https://github.com/HabitRPG/habitrpg/wiki/Contributing') - button(ng-if='!hasPet("Dragon", "Hydra")', class="pet-button pet-not-owned", popover-trigger='mouseenter', popover-placement='right', popover="Click the gold paw to learn more about how you can obtain this rare pet through contributing to HabitRPG!", popover-title='How to Get this Pet!') - img(src='/bower_components/habitrpg-shared/img/PixelPaw-Gold.png') \ No newline at end of file + button(ng-if='!user.items.pets["Dragon-Hydra"]', class="pet-button pet-not-owned", popover-trigger='mouseenter', popover-placement='right', popover="Click the gold paw to learn more about how you can obtain this rare pet through contributing to HabitRPG!", popover-title='How to Get this Pet!') + img(src='/bower_components/habitrpg-shared/img/PixelPaw-Gold.png') + + hr + h4 Mounts + menu.pets(type='list') + li.customize-menu(ng-repeat='egg in Items.eggs') + menu + div(ng-repeat='potion in Items.hatchingPotions', tooltip='{{potion.name}} {{egg.name}}', ng-init='mount = egg.name+"-"+potion.name') + button(class="pet-button Pet-{{mount}}", ng-show='user.items.mounts[mount]', ng-class='{active: user.items.currentMount == mount}', ng-click='chooseMount(egg.name, potion.name)') + button(class="pet-button pet-not-owned", ng-hide='user.items.mounts[mount]') + img(src='/bower_components/habitrpg-shared/img/PixelPaw.png') + + .well(style='position:fixed;right:0px;top:50%;width:200px') + menu.inventory-list(type='list') + li.customize-menu + menu.food-menu(label='Food') + p(ng-show='foodCount < 1') You don't have any food yet. + div(ng-repeat='(food,points) in ownedItems(user.items.food)') + button.customize-option(tooltip='{{food}}', ng-click='chooseFood(food)', class='Pet_Food_{{food}}') + .badge.badge-info.stack-count {{points}} + p {{food}} \ No newline at end of file diff --git a/views/shared/header/avatar.jade b/views/shared/header/avatar.jade index 0fcb8096a4..9ee9527b33 100644 --- a/views/shared/header/avatar.jade +++ b/views/shared/header/avatar.jade @@ -1,6 +1,9 @@ -figure.herobox(ng-click='clickMember(profile._id)', data-name='{{profile.profile.name}}', ng-class='{isUser: profile.id==user.id, hasPet: profile.items.pet}', data-level='{{profile.stats.lvl}}', data-uid='{{profile.id}}', rel='popover', data-placement='bottom', data-trigger='hover', data-html='true', data-content="
Level: {{profile.stats.lvl}}
GP: {{profile.stats.gp | number:0}}
{{count(profile.items.pets)}} / 90 Pets Found
") +figure.herobox(ng-click='clickMember(profile._id)', data-name='{{profile.profile.name}}', ng-class='{isUser: profile.id==user.id, hasPet: profile.items.currentPet}', data-level='{{profile.stats.lvl}}', data-uid='{{profile.id}}', rel='popover', data-placement='bottom', data-trigger='hover', data-html='true', data-content="
Level: {{profile.stats.lvl}}
GP: {{profile.stats.gp | number:0}}
{{count(profile.items.pets)}} / 90 Pets Found
") .character-sprites - span(ng-class='{zzz:profile.flags.rest}') + // Mount Body + span(class='Mount_Body_{{profile.items.currentMount}}') + + // Avatar span(class='{{profile.preferences.gender}}_skin_{{profile.preferences.skin}}') span(class='{{profile.preferences.gender}}_hair_{{profile.preferences.hair}}') span(class='{{equipped("armor", profile.items.armor, profile.preferences, profile.backer, profile.contributor)}}') @@ -8,6 +11,14 @@ figure.herobox(ng-click='clickMember(profile._id)', data-name='{{profile.profile span(class='{{equipped("head", profile.items.head, profile.preferences, profile.backer, profile.contributor)}}', ng-show='profile.preferences.showHelm') span(class='{{equipped("shield",profile.items.shield,profile.preferences, profile.backer, profile.contributor)}}') span(class='{{equipped("weapon",profile.items.weapon,profile.preferences, profile.backer, profile.contributor)}}') + + // Mount Head + span(class='Mount_Head_{{profile.items.currentMount}}') + + // Resting + span(ng-class='{zzz:profile.flags.rest}') + + // Pet // FIXME handle @minimal, this might have to be a directive - span.current-pet(class='Pet-{{profile.items.currentPet.name}}-{{profile.items.currentPet.modifier}}', ng-show='profile.items.currentPet && !minimal') + span.current-pet(class='Pet-{{profile.items.currentPet}}', ng-show='profile.items.currentPet && !minimal') .avatar-level Lvl {{profile.stats.lvl}} diff --git a/views/shared/modals/pets.jade b/views/shared/modals/pets.jade index aa60e7610b..0a2f152d08 100644 --- a/views/shared/modals/pets.jade +++ b/views/shared/modals/pets.jade @@ -2,11 +2,15 @@ div(modal='modals.dropsEnabled') .modal-header h3 Drops Enabled! .modal-body - p + //-p // TODO how to handle random first drop? span.item-drop-icon(class='Pet_Egg_{{user.items.eggs.0.name}}', style='margin-left: 0px') | You've unlocked the Drop System! Now when you complete tasks, you have a small chance of finding an item. You just found a strong {{user.items.eggs.0.text}} Egg | ! {{user.items.eggs.0.notes}}. + p + span.item-drop-icon(class='Pet_Egg_Wolf', style='margin-left: 0px') + span. + You've unlocked the Drop System! Now when you complete tasks, you have a small chance of finding an item. You just found a {{Items.eggs.Wolf.text}} Egg! {{Items.eggs.Wolf.notes}} br p. If you've got your eye on a pet, but can't wait any longer for it to drop, use Gems in Options > Inventory to buy one!