mirror of
https://github.com/sudoxnym/habitica-self-host.git
synced 2026-07-13 17:52:22 +00:00
Merge branch 'free-rebirth-limit' into release
This commit is contained in:
commit
377f849f9e
9 changed files with 69 additions and 9 deletions
|
|
@ -49,6 +49,7 @@ describe('shared.ops.rebirth', () => {
|
|||
let [, message] = rebirth(user);
|
||||
|
||||
expect(message).to.equal(i18n.t('rebirthComplete'));
|
||||
expect(user.flags.lastFreeRebirth).to.exist;
|
||||
});
|
||||
|
||||
it('rebirths a user with not enough gems but more than max level', () => {
|
||||
|
|
@ -60,6 +61,16 @@ describe('shared.ops.rebirth', () => {
|
|||
expect(message).to.equal(i18n.t('rebirthComplete'));
|
||||
});
|
||||
|
||||
it('rebirths a user using gems if over max level but rebirthed recently', () => {
|
||||
user.stats.lvl = MAX_LEVEL + 1;
|
||||
user.flags.lastFreeRebirth = new Date();
|
||||
|
||||
let [, message] = rebirth(user);
|
||||
|
||||
expect(message).to.equal(i18n.t('rebirthComplete'));
|
||||
expect(user.balance).to.equal(0);
|
||||
});
|
||||
|
||||
it('resets user\'s tasks values except for rewards to 0', () => {
|
||||
tasks[0].value = 1;
|
||||
tasks[1].value = 1;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ $maroon-50: #C92B2B;
|
|||
$maroon-100: #DE3F3F;
|
||||
$maroon-500: #F19595;
|
||||
|
||||
$yellow-5: #EE9109;
|
||||
$yellow-10: #FFA623;
|
||||
$yellow-50: #FFB445;
|
||||
$yellow-100: #FFBE5D;
|
||||
|
|
@ -60,9 +61,6 @@ $green-50: #3FDAA2;
|
|||
$green-100: #5AEAB2;
|
||||
$green-500: #A6FFDF;
|
||||
|
||||
$orange-10: #ee9109;
|
||||
$orange-50: #bf7d1a;
|
||||
|
||||
$suggested-item-color: #D5C8FF;
|
||||
|
||||
$healer-color: #cf8229;
|
||||
|
|
|
|||
6
website/client/assets/svg/clock-white.svg
Normal file
6
website/client/assets/svg/clock-white.svg
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path fill="#FFF" d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0m0 2c3.308 0 6 2.692 6 6s-2.692 6-6 6-6-2.692-6-6 2.692-6 6-6"/>
|
||||
<path stroke="#FFF" stroke-linecap="round" stroke-width="2" d="M8 5v3.031L10 10"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 358 B |
|
|
@ -76,9 +76,14 @@
|
|||
) {{ $t('buyNow') }}
|
||||
|
||||
div.limitedTime(v-if="item.event && item.owned == null")
|
||||
span.svg-icon.inline.icon-16(v-html="icons.clock")
|
||||
span.svg-icon.inline.icon-16.clock-icon(v-html="icons.clock")
|
||||
span.limitedString {{ limitedString }}
|
||||
|
||||
.free-rebirth.d-flex.align-items-center(v-if='item.key === "rebirth_orb" && item.value > 0')
|
||||
.m-auto
|
||||
span.svg-icon.inline.icon-16.mr-2.pt-015(v-html="icons.whiteClock")
|
||||
span(v-html='$t("nextFreeRebirth", {days: nextFreeRebirth})')
|
||||
|
||||
div.clearfix(slot="modal-footer")
|
||||
span.balance.float-left {{ $t('yourBalance') }}
|
||||
balanceInfo(
|
||||
|
|
@ -253,6 +258,18 @@
|
|||
.gems-left {
|
||||
margin-top: .5em;
|
||||
}
|
||||
|
||||
.free-rebirth {
|
||||
background-color: $yellow-5;
|
||||
color: $white;
|
||||
height: 2rem;
|
||||
line-height: 16px;
|
||||
margin: auto -1rem -1rem;
|
||||
}
|
||||
|
||||
.pt-015 {
|
||||
padding-top: 0.15rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -268,6 +285,7 @@
|
|||
import svgHourglasses from 'assets/svg/hourglass.svg';
|
||||
import svgPin from 'assets/svg/pin.svg';
|
||||
import svgClock from 'assets/svg/clock.svg';
|
||||
import svgWhiteClock from 'assets/svg/clock-white.svg';
|
||||
|
||||
import BalanceInfo from './balanceInfo.vue';
|
||||
import currencyMixin from './_currencyMixin';
|
||||
|
|
@ -308,6 +326,7 @@
|
|||
hourglasses: svgHourglasses,
|
||||
pin: svgPin,
|
||||
clock: svgClock,
|
||||
whiteClock: svgWhiteClock,
|
||||
}),
|
||||
|
||||
selectedAmountToBuy: 1,
|
||||
|
|
@ -360,6 +379,9 @@
|
|||
notEnoughCurrency () {
|
||||
return !this.enoughCurrency(this.getPriceClass(), this.item.value * this.selectedAmountToBuy);
|
||||
},
|
||||
nextFreeRebirth () {
|
||||
return 45 - moment().diff(moment(this.user.flags.lastFreeRebirth), 'days');
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
item: function itemChanged () {
|
||||
|
|
|
|||
|
|
@ -25,5 +25,6 @@
|
|||
"rebirthName": "Orb of Rebirth",
|
||||
"reborn": "Reborn, max level <%= reLevel %>",
|
||||
"confirmReborn": "Are you sure?",
|
||||
"rebirthComplete": "You have been reborn!"
|
||||
"rebirthComplete": "You have been reborn!",
|
||||
"nextFreeRebirth": "<strong><%= days %> days</strong> until <strong>FREE</strong> Orb of Rebirth"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { BadRequest } from './errors';
|
|||
import count from '../count';
|
||||
|
||||
import isPinned from './isPinned';
|
||||
import isFreeRebirth from './isFreeRebirth';
|
||||
import getOfficialPinnedItems from './getOfficialPinnedItems';
|
||||
|
||||
import _mapValues from 'lodash/mapValues';
|
||||
|
|
@ -296,7 +297,7 @@ module.exports = function getItemInfo (user, type, item, officialPinnedItems, la
|
|||
class: 'rebirth_orb',
|
||||
text: i18n.t('rebirthName'),
|
||||
notes: i18n.t('rebirthPop'),
|
||||
value: user.stats.lvl < 100 ? 6 : 0,
|
||||
value: isFreeRebirth(user) ? 0 : 6,
|
||||
currency: 'gems',
|
||||
path: 'special.rebirth_orb',
|
||||
pinType: 'rebirth_orb',
|
||||
|
|
|
|||
14
website/common/script/libs/isFreeRebirth.js
Normal file
14
website/common/script/libs/isFreeRebirth.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import moment from 'moment';
|
||||
import { MAX_LEVEL } from '../constants';
|
||||
|
||||
module.exports = function isFreeRebirth (user) {
|
||||
let daysFromLastFreeRebirth = user.flags.lastFreeRebirth;
|
||||
|
||||
if (daysFromLastFreeRebirth) {
|
||||
daysFromLastFreeRebirth = moment().diff(moment(user.flags.lastFreeRebirth), 'days');
|
||||
} else {
|
||||
daysFromLastFreeRebirth = 999;
|
||||
}
|
||||
|
||||
return user.stats.lvl >= MAX_LEVEL && daysFromLastFreeRebirth > 45;
|
||||
};
|
||||
|
|
@ -7,12 +7,14 @@ import {
|
|||
} from '../libs/errors';
|
||||
import equip from './equip';
|
||||
import { removePinnedGearByClass } from './pinnedGearUtils';
|
||||
|
||||
import isFreeRebirth from '../libs/isFreeRebirth';
|
||||
|
||||
const USERSTATSLIST = ['per', 'int', 'con', 'str', 'points', 'gp', 'exp', 'mp'];
|
||||
|
||||
module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
|
||||
if (user.balance < 1.5 && user.stats.lvl < MAX_LEVEL) {
|
||||
const notFree = !isFreeRebirth(user);
|
||||
|
||||
if (user.balance < 1.5 && notFree) {
|
||||
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
|
||||
}
|
||||
|
||||
|
|
@ -21,7 +23,7 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
|
|||
category: 'behavior',
|
||||
};
|
||||
|
||||
if (user.stats.lvl < MAX_LEVEL) {
|
||||
if (notFree) {
|
||||
user.balance -= 1.5;
|
||||
analyticsData.acquireMethod = 'Gems';
|
||||
analyticsData.gemCost = 6;
|
||||
|
|
@ -95,6 +97,10 @@ module.exports = function rebirth (user, tasks = [], req = {}, analytics) {
|
|||
user.achievements.rebirthLevel = lvl;
|
||||
}
|
||||
|
||||
if (!notFree) {
|
||||
user.flags.lastFreeRebirth = new Date();
|
||||
}
|
||||
|
||||
if (user.addNotification) user.addNotification('REBIRTH_ACHIEVEMENT');
|
||||
|
||||
user.stats.buffs = {};
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ let schema = new Schema({
|
|||
classSelected: {$type: Boolean, default: false},
|
||||
mathUpdates: Boolean,
|
||||
rebirthEnabled: {$type: Boolean, default: false},
|
||||
lastFreeRebirth: Date,
|
||||
levelDrops: {$type: Schema.Types.Mixed, default: () => {
|
||||
return {};
|
||||
}},
|
||||
|
|
|
|||
Loading…
Reference in a new issue