diff --git a/common/locales/en/death.json b/common/locales/en/death.json index b7032d7a73..dc131e74f2 100644 --- a/common/locales/en/death.json +++ b/common/locales/en/death.json @@ -3,5 +3,15 @@ "dontDespair": "Don't despair!", "deathPenaltyDetails": "You lost a Level, your Gold, and a piece of Equipment, but you can get them all back with hard work! Good luck--you'll do great.", "refillHealthTryAgain": "Refill Health & Try Again", - "dyingOftenTips": "Is this happening often? Here are some tips!" -} \ No newline at end of file + "dyingOftenTips": "Is this happening often? Here are some tips!", + "losingHealthWarning": "Careful - You're Losing Health!", + "losingHealthWarning2": "Don't let your Health drop to zero! If you do, you'll lose a level, your Gold, and a piece of equipment.", + "toRegainHealth": "To regain Health:", + "lowHealthTips1": "Level up to fully heal!", + "lowHealthTips2": "Buy a Health Potion from the Rewards column to restore 15 Health Points.", + "losingHealthQuickly": "Losing Health quickly?", + "lowHealthTips3": "Incomplete Dailies hurt you overnight, so be careful not to add too many at first!", + "lowHealthTips4": "If a Daily isn't due on a certain day, you can disable it by clicking the pencil icon.", + "goodLuck": "Good luck!" +} + diff --git a/website/public/css/shared.styl b/website/public/css/shared.styl index 41a04df2ce..9a48dd28df 100644 --- a/website/public/css/shared.styl +++ b/website/public/css/shared.styl @@ -45,6 +45,9 @@ a.hint:hover ul list-style-position: inside; +li.spaced + margin: auto auto .5em 3em + .group-leave-join .glyphicon-ban-circle color: white; diff --git a/website/public/js/controllers/notificationCtrl.js b/website/public/js/controllers/notificationCtrl.js index 77f66b497f..06c8dc74be 100644 --- a/website/public/js/controllers/notificationCtrl.js +++ b/website/public/js/controllers/notificationCtrl.js @@ -8,6 +8,8 @@ habitrpg.controller('NotificationCtrl', if (after <= 0){ $rootScope.playSound('Death'); $rootScope.openModal('death', {keyboard:false, backdrop:'static'}); + } else if (after <= 30 && !User.user.flags.warnedLowHealth) { + $rootScope.openModal('lowHealth', {keyboard:false, backdrop:'static', controller:'UserCtrl', track:'Health Warning'}); } if (after == before) return; if (User.user.stats.lvl == 0) return; diff --git a/website/public/js/controllers/userCtrl.js b/website/public/js/controllers/userCtrl.js index db8559d728..f2a53ed2b5 100644 --- a/website/public/js/controllers/userCtrl.js +++ b/website/public/js/controllers/userCtrl.js @@ -43,6 +43,10 @@ habitrpg.controller("UserCtrl", ['$rootScope', '$scope', '$location', 'User', '$ $scope._editing.profile = false; } + $scope.acknowledgeHealthWarning = function(){ + User.user.ops.update && User.set({'flags.warnedLowHealth':false}); + } + /** * For gem-unlockable preferences, (a) if owned, select preference (b) else, purchase * @param path: User.preferences <-> User.purchased maps like User.preferences.skin=abc <-> User.purchased.skin.abc. diff --git a/website/src/models/user.js b/website/src/models/user.js index fc52a48f3b..a8638dcc45 100644 --- a/website/src/models/user.js +++ b/website/src/models/user.js @@ -163,7 +163,8 @@ var UserSchema = new Schema({ armoireEnabled: {type: Boolean, 'default': false}, armoireOpened: {type: Boolean, 'default': false}, armoireEmpty: {type: Boolean, 'default': false}, - cardReceived: {type: Boolean, 'default': false} + cardReceived: {type: Boolean, 'default': false}, + warnedLowHealth: {type: Boolean, 'default': false} }, history: { exp: Array, // [{date: Date, value: Number}], // big peformance issues if these are defined diff --git a/website/views/shared/avatar/appearance.jade b/website/views/shared/avatar/appearance.jade index 75d74e2a45..7b28273996 100644 --- a/website/views/shared/avatar/appearance.jade +++ b/website/views/shared/avatar/appearance.jade @@ -1,3 +1,5 @@ +include generated_avatar + mixin avatar(opts) .character-sprites .addthis_native_toolbox(ng-if='::profile._id==user._id', @@ -16,7 +18,7 @@ mixin avatar(opts) // Show avatar only if not currently affected by visual buff - var buffs = '!profile.stats.buffs' span(ng-if='#{buffs}.snowball && #{buffs}.spookDust && #{buffs}.shinySeed && #{buffs}.seafoam') - include generated_avatar + +generatedAvatar // Mount Head if !opts.minimal diff --git a/website/views/shared/avatar/generated_avatar.jade b/website/views/shared/avatar/generated_avatar.jade index 7f7ef4479b..e6423c8f16 100644 --- a/website/views/shared/avatar/generated_avatar.jade +++ b/website/views/shared/avatar/generated_avatar.jade @@ -4,39 +4,24 @@ mixin costumeSetting(type, options) - var equipped = (options.prefix || '') + 'profile.items.gear.equipped.' + type + (options.suffix || '') span(ng-class="profile.preferences.costume ? #{costume} : #{equipped}") -// Back accessory -+costumeSetting('back') - -span(ng-class="profile.preferences.sleep ? 'skin_' + profile.preferences.skin + '_sleep' : 'skin_' + profile.preferences.skin") - -// Shirt -span(class='{{profile.preferences.size}}_shirt_{{profile.preferences.shirt}}') - -// Armor -+costumeSetting('armor', {prefix: "profile.preferences.size + '_' + "}) - -// Cape collar -+costumeSetting('back', {suffix: " + '_collar'"}) - -// Body -+costumeSetting('body') - -// Empty outline of head -span(class='head_0') - -// Hair -- var hairTypes = ['base', 'bangs', 'mustache', 'beard'] -each type in hairTypes - span(class='hair_#{type}_{{profile.preferences.hair.#{type}}}_{{profile.preferences.hair.color}}') - -// Head -+costumeSetting('eyewear') -+costumeSetting('head') -+costumeSetting('headAccessory') - -// Flower -span(class='hair_flower_{{profile.preferences.hair.flower}}') - -// Items held in hands -+costumeSetting('shield') -+costumeSetting('weapon') +mixin generatedAvatar(options) + - options = options || {} + +costumeSetting('back') + if options.sleep + span(ng-class="'skin_' + profile.preferences.skin + '_sleep'") + else + span(ng-class="profile.preferences.sleep ? 'skin_' + profile.preferences.skin + '_sleep' : 'skin_' + profile.preferences.skin") + span(class='{{profile.preferences.size}}_shirt_{{profile.preferences.shirt}}') + +costumeSetting('armor', {prefix: "profile.preferences.size + '_' + "}) + +costumeSetting('back', {suffix: " + '_collar'"}) + +costumeSetting('body') + span(class='head_0') + - var hairTypes = ['base', 'bangs', 'mustache', 'beard'] + each type in hairTypes + span(class='hair_#{type}_{{profile.preferences.hair.#{type}}}_{{profile.preferences.hair.color}}') + +costumeSetting('eyewear') + +costumeSetting('head') + +costumeSetting('headAccessory') + span(class='hair_flower_{{profile.preferences.hair.flower}}') + +costumeSetting('shield') + +costumeSetting('weapon') diff --git a/website/views/shared/modals/death.jade b/website/views/shared/modals/death.jade index 2c7166fb62..cfdbced16e 100644 --- a/website/views/shared/modals/death.jade +++ b/website/views/shared/modals/death.jade @@ -15,22 +15,7 @@ script(type='text/ng-template', id='modals/death.html') | {{Math.ceil(user.stats.hp)}} / {{::Shared.maxHealth}} figure.herobox.text-center .character-sprites - +costumeSetting('back') - span(ng-class="'skin_' + profile.preferences.skin + '_sleep'") - span(class='{{profile.preferences.size}}_shirt_{{profile.preferences.shirt}}') - +costumeSetting('armor', {prefix: "profile.preferences.size + '_' + "}) - +costumeSetting('back', {suffix: " + '_collar'"}) - +costumeSetting('body') - span(class='head_0') - - var hairTypes = ['base', 'bangs', 'mustache', 'beard'] - each type in hairTypes - span(class='hair_#{type}_{{profile.preferences.hair.#{type}}}_{{profile.preferences.hair.color}}') - +costumeSetting('eyewear') - +costumeSetting('head') - +costumeSetting('headAccessory') - span(class='hair_flower_{{profile.preferences.hair.flower}}') - +costumeSetting('shield') - +costumeSetting('weapon') + +generatedAvatar({sleep:true}) span(class='knockout') .col-md-6 h4(style='margin-top:1.5em')=env.t('dontDespair') diff --git a/website/views/shared/modals/index.jade b/website/views/shared/modals/index.jade index 519f20e2d6..8146882046 100644 --- a/website/views/shared/modals/index.jade +++ b/website/views/shared/modals/index.jade @@ -13,3 +13,4 @@ include ./rebirth include ./limited include ./invite-friends include ./welcome.jade +include ./low-health.jade diff --git a/website/views/shared/modals/low-health.jade b/website/views/shared/modals/low-health.jade new file mode 100644 index 0000000000..4cc26e8384 --- /dev/null +++ b/website/views/shared/modals/low-health.jade @@ -0,0 +1,29 @@ +include ../avatar/generated_avatar + +script(type='text/ng-template', id='modals/lowHealth.html') + .modal-header + h3.text-center=env.t('losingHealthWarning') + .modal-body + .hero-stats(style='position:absolute; margin-left:9em; width:50%') + .meter-label(tooltip=env.t('health')) + span.glyphicon.glyphicon-heart + .meter.health(tooltip='{{Math.round(user.stats.hp * 100) / 100}}') + .bar(ng-style='{"width": Shared.percent(user.stats.hp, Shared.maxHealth)+"%"}') + span.meter-text.value + | {{Math.ceil(user.stats.hp)}} / {{::Shared.maxHealth}} + .herobox.inline-block(style='padding-top:0em; margin-left:16em') + .character-sprites(style='display:inline-flex; margin:3em auto') + +generatedAvatar + p=env.t('losingHealthWarning2') + h4=env.t('toRegainHealth') + ul + li.spaced=env.t('lowHealthTips1') + li.spaced=env.t('lowHealthTips2') + h4=env.t('losingHealthQuickly') + ul + li.spaced=env.t('lowHealthTips3') + li.spaced=env.t('lowHealthTips4') + h4=env.t('goodLuck') + .modal-footer(style='margin-top: 0em') + a.btn.btn-primary(ng-click='acknowledgeHealthWarning(); $close()')=env.t('ok') +