diff --git a/public/css/game-pane.styl b/public/css/game-pane.styl
index 124cc33030..5d65294780 100644
--- a/public/css/game-pane.styl
+++ b/public/css/game-pane.styl
@@ -68,6 +68,9 @@
max-height:50px
vertical-align:top
+ li
+ border:0
+
// Name tags
.label-contributor-1, .label-contributor-2
background-color: #333;
@@ -127,4 +130,4 @@
.list-cur {
background: #b9dff4;
-}
\ No newline at end of file
+}
diff --git a/public/js/controllers/inventoryCtrl.js b/public/js/controllers/inventoryCtrl.js
index 8874a531cb..d5f6fc18b4 100644
--- a/public/js/controllers/inventoryCtrl.js
+++ b/public/js/controllers/inventoryCtrl.js
@@ -126,6 +126,7 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', 'User', 'API_URL',
// Feeding Pet
if ($scope.selectedFood) {
+ if (window.habitrpgShared.items.items.specialPets[pet]) return Notification.text("Can't feed this pet.");
var setObj = {};
var userPets = user.items.pets;
if (user.items.mounts[pet] && (userPets[pet] >= 50 || $scope.selectedFood.name == 'Saddle'))
diff --git a/public/js/controllers/notificationCtrl.js b/public/js/controllers/notificationCtrl.js
index 759fd267b5..d1ddbda530 100644
--- a/public/js/controllers/notificationCtrl.js
+++ b/public/js/controllers/notificationCtrl.js
@@ -31,7 +31,9 @@ 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;
- var type = after.type === 'HatchingPotion' ? 'hatchingPotions' : (after.type.toLowerCase() + 's')
+ var type = (after.type == 'Food') ? 'food' :
+ (after.type == 'HatchingPotion') ? 'hatchingPotions' : // can we use camelcase and remove this line?
+ (after.type.toLowerCase() + 's');
if(!User.user.items[type][after.name]){
User.user.items[type][after.name] = 0;
}
diff --git a/public/js/services/userServices.js b/public/js/services/userServices.js
index 9db94b7828..26308ee955 100644
--- a/public/js/services/userServices.js
+++ b/public/js/services/userServices.js
@@ -57,7 +57,7 @@ angular.module('userServices', []).
sent.push(queue.shift());
});
- $http.post(API_URL + '/api/v1/user/batch-update', sent, {params: {data:+new Date, _v:user._v}})
+ $http.post(API_URL + '/api/v1/user/batch-update', sent, {params: {data:+new Date, _v:user._v, siteVersion: $window.env && $window.env.siteVersion}})
.success(function (data, status, heacreatingders, config) {
//make sure there are no pending actions to sync. If there are any it is not safe to apply model from server as we may overwrite user data.
if (!queue.length) {
@@ -85,6 +85,13 @@ angular.module('userServices', []).
syncQueue(); // call syncQueue to check if anyone pushed more actions to the queue while we were talking to server.
})
.error(function (data, status, headers, config) {
+ if(status === 400 && data.needRefresh === true){
+ alert("The site has been updated and the page needs to refresh. " +
+ "The last action has not been recorded, please do it again once the page reloads."
+ );
+
+ return location.reload();
+ }
//move sent actions back to queue
_.times(sent.length, function () {
queue.push(sent.shift())
diff --git a/src/controllers/groups.js b/src/controllers/groups.js
index d2e6d53ea8..d45adceca3 100644
--- a/src/controllers/groups.js
+++ b/src/controllers/groups.js
@@ -16,8 +16,7 @@ var api = module.exports;
------------------------------------------------------------------------
*/
-var itemFields = 'items.armor items.head items.shield items.weapon items.currentPet items.pets'; // TODO just send down count(items.pets) for better performance
-var partyFields = 'profile preferences stats achievements party backer contributor flags.rest auth.timestamps ' + itemFields;
+var partyFields = 'profile preferences stats achievements party backer contributor flags.rest auth.timestamps items';
var nameFields = 'profile.name';
var challengeFields = '_id name';
var guildPopulate = {path: 'members', select: nameFields, options: {limit: 15} };
diff --git a/src/middleware.js b/src/middleware.js
index 8fe5d8a19e..e03f08a88f 100644
--- a/src/middleware.js
+++ b/src/middleware.js
@@ -23,6 +23,16 @@ module.exports.cors = function(req, res, next) {
return next();
};
+var siteVersion = 0;
+
+module.exports.forceRefresh = function(req, res, next){
+ if(req.query.siteVersion && req.query.siteVersion != siteVersion){
+ return res.json(400, {needRefresh: true});
+ }
+
+ return next();
+};
+
var buildFiles = [];
var walk = function(folder){
@@ -115,14 +125,15 @@ var momentLangsMapping = {
'no': 'nn'
};
+var momentLangs = {};
+
_.each(langCodes, function(code){
var lang = _.find(avalaibleLanguages, {code: code});
lang.momentLangCode = (momentLangsMapping[code] || code);
try{
- var momentLang = momentLangsMapping[code] ? momentLangsMapping[code] : code;
// MomentJS lang files are JS files that has to be executed in the browser so we load them as plain text files
var f = fs.readFileSync(path.join(__dirname, '/../node_modules/moment/lang/' + lang.momentLangCode + '.js'), 'utf8');
- lang.momentLang = f;
+ momentLangs[code] = f;
}catch (e){}
});
@@ -159,6 +170,8 @@ module.exports.locals = function(req, res, next) {
getUserLanguage(req, function(err, language){
if(err) return res.json(500, {err: err});
+ language.momentLang = (momentLangs[language.code] || undefined);
+
res.locals.habitrpg = {
NODE_ENV: nconf.get('NODE_ENV'),
BASE_URL: nconf.get('BASE_URL'),
@@ -172,7 +185,8 @@ module.exports.locals = function(req, res, next) {
translations: translations[language.code],
t: function(string){
return (translations[language.code][string] || translations[language.code].stringNotFound);
- }
+ },
+ siteVersion: siteVersion
}
next();
diff --git a/src/routes/api.js b/src/routes/api.js
index 8329c4a511..f63b8b6fe5 100644
--- a/src/routes/api.js
+++ b/src/routes/api.js
@@ -7,6 +7,7 @@ var admin = require('../controllers/admin');
var challenges = require('../controllers/challenges');
var dataexport = require('../controllers/dataexport');
var nconf = require('nconf');
+var middleware = require('../middleware');
/*
---------- /api/v1 API ------------
@@ -54,7 +55,7 @@ router.post('/user/buy/:key', auth.auth, cron, user.buy);
router.get('/user', auth.auth, cron, user.getUser);
router.put('/user', auth.auth, cron, user.updateUser);
router.post('/user/revive', auth.auth, cron, user.revive);
-router.post('/user/batch-update', auth.auth, cron, user.batchUpdate);
+router.post('/user/batch-update', middleware.forceRefresh, auth.auth, cron, user.batchUpdate);
router.post('/user/reroll', auth.auth, cron, user.reroll);
router.post('/user/buy-gems', auth.auth, user.buyGems);
router.post('/user/buy-gems/paypal-ipn', user.buyGemsPaypalIPN);
diff --git a/views/options/inventory/inventory.jade b/views/options/inventory/inventory.jade
index 28b1e1e6d2..ab85e629cd 100644
--- a/views/options/inventory/inventory.jade
+++ b/views/options/inventory/inventory.jade
@@ -36,7 +36,7 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html')
.badge.badge-info.stack-count {{points}}
//-p {{pot}}
- //-li.customize-menu
+ li.customize-menu
menu.pets-menu(label='Food ({{foodCount}})')
p(ng-show='foodCount < 1') You don't have any food.
div(ng-repeat='(food,points) in ownedItems(user.items.food)')
@@ -84,7 +84,7 @@ script(type='text/ng-template', id='partials/options.inventory.inventory.html')
| {{pot.value}}
span.Pet_Currency_Gem1x.inline-gems
- //-li.customize-menu
+ li.customize-menu
menu.pets-menu(label='Food')
div(ng-repeat='food in Items.food')
button.customize-option(popover='{{food.notes}}', popover-title='{{food.text}}', popover-trigger='mouseenter', popover-placement='left', ng-click='buy("food", food)', class='Pet_Food_{{food.name}}')
diff --git a/views/options/inventory/stable.jade b/views/options/inventory/stable.jade
index 939c86cad4..4dd103f20c 100644
--- a/views/options/inventory/stable.jade
+++ b/views/options/inventory/stable.jade
@@ -1,16 +1,14 @@
script(type='text/ng-template', id='partials/options.inventory.stable.html')
- div(ui-view)
- //-
- ul.nav.nav-tabs
- li(ng-class="{ active: $state.includes('options.inventory.stable.pets') }")
- a(ui-sref='options.inventory.stable.pets')
- | Pets
- li(ng-class="{ active: $state.includes('options.inventory.stable.mounts') }")
- a(ui-sref='options.inventory.stable.mounts')
- | Mounts
- .tab-content
- .tab-pane.active
- div(ui-view)
+ ul.nav.nav-tabs
+ li(ng-class="{ active: $state.includes('options.inventory.stable.pets') }")
+ a(ui-sref='options.inventory.stable.pets')
+ | Pets
+ li(ng-class="{ active: $state.includes('options.inventory.stable.mounts') }")
+ a(ui-sref='options.inventory.stable.mounts')
+ | Mounts
+ .tab-content
+ .tab-pane.active
+ div(ui-view)
script(type='text/ng-template', id='partials/options.inventory.stable.mounts.html')
.stable
@@ -55,7 +53,7 @@ script(type='text/ng-template', id='partials/options.inventory.stable.pets.html'
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. Have a look-see at all the pets you can collect.
+ Welcome to the Stable! I'm Matt, the beast master. Choose a pet here to venture at your side. Feed them and they'll grow into powerful steeds. Have a look-see at all the pets you can collect.
h4 {{petCount}} / {{totalPets}} Pets Found
menu.pets(type='list')
@@ -63,7 +61,7 @@ script(type='text/ng-template', id='partials/options.inventory.stable.pets.html'
menu
div(ng-repeat='potion in Items.hatchingPotions', popover-trigger='mouseenter', popover='{{potion.text}} {{egg.text}}', popover-placement='bottom', 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, selectableInventory: selectedFood}', ng-click='choosePet(egg.name, potion.name)')
- //-.progress(ng-class='{"progress-success": user.items.pets[pet]<50}')
+ .progress(ng-class='{"progress-success": user.items.pets[pet]<50}')
.bar(style="width: {{user.items.pets[pet]/.5}}%;")
button(class="pet-button pet-not-owned", ng-if='!user.items.pets[pet]')
.PixelPaw
@@ -79,7 +77,7 @@ script(type='text/ng-template', id='partials/options.inventory.stable.pets.html'
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!')
.PixelPaw-Gold
- //-.well.food-tray
+ .well.food-tray
p(ng-show='foodCount < 1') You don't have any food yet.
menu.inventory-list(type='list', ng-if='foodCount > 0')
li.customize-menu
diff --git a/views/shared/modals/new-stuff.jade b/views/shared/modals/new-stuff.jade
index e7bd9bde38..b13bb61235 100644
--- a/views/shared/modals/new-stuff.jade
+++ b/views/shared/modals/new-stuff.jade
@@ -12,32 +12,39 @@ div(modal='modals.newStuff')
h3.popover-title
a(target='_blank', href='https://twitter.com/Mihakuu') Bailey
.popover-content
- table.table.table-striped
- tr
- td
- h4 Turkey Event (by @lemoness)
- p Say hi to our NPCs, dressed to impressed for Turkey day! Also - check your stable, you'll find a fun new pet.
- tr
- td
- h4 Chat Enhancements (by @Nick Gordon)
- p.
- Chat can now use markdown, Emoji, and @-tagging. Some pointers on using markdown & Emoji at here. To use @-tagging, simply type '@' in chat.
- tr
- td
- h4 Party Sorting (by @Fandekasp)
- p.
- You can now adjust the way you view your party members in the top bar. They can be sorted by level, number of pets, the date they joined the party, or just randomly. Also, level colors now reflect your contributor status.
- tr
- td
- h4 Wiki Updates (by @bobbyroberts99)
- p.
- The HabitRPG wiki is being speedily updated. If you’re confused about anything, go check it out - it’s a treasure trove.
+ h4 Mounts!
+ p You can now feed your pets and they'll grow into trusty steeds. Obtain food as new random drops, or you can hasten the process buy buying a saddle from Alexander.
+ // We may want to use their twitter handles, or something they prefer instead
+ hr
+ p.
+ By @lemoness @Shaners @baconsaur @RandallStanhope @ashjolliffe @fuzzytrees
-
- small.muted 11/27/2013
+ small.muted 12/7/2013
hr
+ h5 11/27/2013
+ table.table.table-striped
+ tr
+ td
+ h4 Turkey Event (by @lemoness)
+ p Say hi to our NPCs, dressed to impressed for Turkey day! Also - check your stable, you'll find a fun new pet.
+ tr
+ td
+ h4 Chat Enhancements (by @Nick Gordon)
+ p.
+ Chat can now use markdown, Emoji, and @-tagging. Some pointers on using markdown & Emoji at here. To use @-tagging, simply type '@' in chat.
+ tr
+ td
+ h4 Party Sorting (by @Fandekasp)
+ p.
+ You can now adjust the way you view your party members in the top bar. They can be sorted by level, number of pets, the date they joined the party, or just randomly. Also, level colors now reflect your contributor status.
+ tr
+ td
+ h4 Wiki Updates (by @bobbyroberts99)
+ p.
+ The HabitRPG wiki is being speedily updated. If you’re confused about anything, go check it out - it’s a treasure trove.
+
h5 11/08/2013
table.table.table-striped
tr