mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 15:17:25 +01:00
fix: Corrects stat allocation bug where it was possible to recieve more points than 100
fixes #6434
This commit is contained in:
@@ -2271,41 +2271,56 @@ api.wrap = function(user, main) {
|
|||||||
}
|
}
|
||||||
})()]++;
|
})()]++;
|
||||||
},
|
},
|
||||||
updateStats: function(stats, req, analytics) {
|
updateStats (stats, req, analytics) {
|
||||||
|
let allocatedStatPoints;
|
||||||
|
let totalStatPoints;
|
||||||
|
let experienceToNextLevel;
|
||||||
|
|
||||||
if (stats.hp <= 0) {
|
if (stats.hp <= 0) {
|
||||||
return user.stats.hp = 0;
|
user.stats.hp = 0;
|
||||||
|
return user.stats.hp;
|
||||||
}
|
}
|
||||||
|
|
||||||
user.stats.hp = stats.hp;
|
user.stats.hp = stats.hp;
|
||||||
user.stats.gp = stats.gp >= 0 ? stats.gp : 0;
|
user.stats.gp = stats.gp >= 0 ? stats.gp : 0;
|
||||||
|
|
||||||
var experienceToNextLevel = api.tnl(user.stats.lvl);
|
experienceToNextLevel = api.tnl(user.stats.lvl);
|
||||||
|
|
||||||
if (stats.exp >= experienceToNextLevel) {
|
if (stats.exp >= experienceToNextLevel) {
|
||||||
user.stats.exp = stats.exp;
|
user.stats.exp = stats.exp;
|
||||||
|
|
||||||
while (stats.exp >= experienceToNextLevel) {
|
while (stats.exp >= experienceToNextLevel) {
|
||||||
stats.exp -= experienceToNextLevel;
|
stats.exp -= experienceToNextLevel;
|
||||||
user.stats.lvl++;
|
user.stats.lvl++;
|
||||||
experienceToNextLevel = api.tnl(user.stats.lvl);
|
|
||||||
user.stats.hp = 50;
|
|
||||||
var userTotalStatPoints = user.stats.str + user.stats.int + user.stats.con + user.stats.per;
|
|
||||||
|
|
||||||
if (userTotalStatPoints >= MAX_STAT_POINTS) {
|
experienceToNextLevel = api.tnl(user.stats.lvl);
|
||||||
continue;
|
user.stats.hp = MAX_HEALTH;
|
||||||
|
allocatedStatPoints = user.stats.str + user.stats.int + user.stats.con + user.stats.per;
|
||||||
|
totalStatPoints = allocatedStatPoints + user.stats.points;
|
||||||
|
|
||||||
|
if (totalStatPoints >= MAX_STAT_POINTS) {
|
||||||
|
continue; // eslint-disable-line no-continue
|
||||||
}
|
}
|
||||||
if (user.preferences.automaticAllocation) {
|
if (user.preferences.automaticAllocation) {
|
||||||
user.fns.autoAllocate();
|
user.fns.autoAllocate();
|
||||||
} else {
|
} else {
|
||||||
user.stats.points = user.stats.lvl - userTotalStatPoints;
|
user.stats.points = user.stats.lvl - allocatedStatPoints;
|
||||||
|
totalStatPoints = user.stats.points + allocatedStatPoints;
|
||||||
|
|
||||||
|
if (totalStatPoints > MAX_STAT_POINTS) {
|
||||||
|
user.stats.points = MAX_STAT_POINTS - allocatedStatPoints;
|
||||||
|
}
|
||||||
|
|
||||||
if (user.stats.points < 0) {
|
if (user.stats.points < 0) {
|
||||||
user.stats.points = 0;
|
user.stats.points = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
user.stats.exp = stats.exp;
|
user.stats.exp = stats.exp;
|
||||||
if (user.flags == null) {
|
user.flags = user.flags || {};
|
||||||
user.flags = {};
|
|
||||||
}
|
|
||||||
if (!user.flags.customizationsNotification && (user.stats.exp > 5 || user.stats.lvl > 1)) {
|
if (!user.flags.customizationsNotification && (user.stats.exp > 5 || user.stats.lvl > 1)) {
|
||||||
user.flags.customizationsNotification = true;
|
user.flags.customizationsNotification = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ describe('user.fns.updateStats', () => {
|
|||||||
user = generateUser({});
|
user = generateUser({});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('no hp', () => {
|
context('No Hp', () => {
|
||||||
it('returns 0 if user\'s hp is 0', () => {
|
it('returns 0 if user\'s hp is 0', () => {
|
||||||
let stats = {
|
let stats = {
|
||||||
hp: 0,
|
hp: 0,
|
||||||
@@ -38,7 +38,19 @@ describe('user.fns.updateStats', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Stat Allocation', () => {
|
context('Stat Allocation', () => {
|
||||||
it('Adds an attibute point when user\'s stat points are less than max level', () => {
|
it('adds only attribute points up to user\'s level', () => {
|
||||||
|
let stats = {
|
||||||
|
exp: 261,
|
||||||
|
};
|
||||||
|
|
||||||
|
user.stats.lvl = 10;
|
||||||
|
|
||||||
|
user.fns.updateStats(stats);
|
||||||
|
|
||||||
|
expect(user.stats.points).to.eql(11);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds an attibute point when user\'s stat points are less than max level', () => {
|
||||||
let stats = {
|
let stats = {
|
||||||
exp: 3581,
|
exp: 3581,
|
||||||
};
|
};
|
||||||
@@ -54,7 +66,7 @@ describe('user.fns.updateStats', () => {
|
|||||||
expect(user.stats.points).to.eql(1);
|
expect(user.stats.points).to.eql(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Does not add an attibute point when user\'s stat points are equal to max level', () => {
|
it('does not add an attibute point when user\'s stat points are equal to max level', () => {
|
||||||
let stats = {
|
let stats = {
|
||||||
exp: 3581,
|
exp: 3581,
|
||||||
};
|
};
|
||||||
@@ -69,5 +81,54 @@ describe('user.fns.updateStats', () => {
|
|||||||
|
|
||||||
expect(user.stats.points).to.eql(0);
|
expect(user.stats.points).to.eql(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not add an attibute point when user\'s stat points + unallocated points are equal to max level', () => {
|
||||||
|
let stats = {
|
||||||
|
exp: 3581,
|
||||||
|
};
|
||||||
|
|
||||||
|
user.stats.lvl = 99;
|
||||||
|
user.stats.str = 25;
|
||||||
|
user.stats.int = 25;
|
||||||
|
user.stats.con = 25;
|
||||||
|
user.stats.per = 15;
|
||||||
|
user.stats.points = 10;
|
||||||
|
|
||||||
|
user.fns.updateStats(stats);
|
||||||
|
|
||||||
|
expect(user.stats.points).to.eql(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('only awards stat points up to level 100 if user is missing unallocated stat points and is over level 100', () => {
|
||||||
|
let stats = {
|
||||||
|
exp: 5581,
|
||||||
|
};
|
||||||
|
|
||||||
|
user.stats.lvl = 104;
|
||||||
|
user.stats.str = 25;
|
||||||
|
user.stats.int = 25;
|
||||||
|
user.stats.con = 25;
|
||||||
|
user.stats.per = 15;
|
||||||
|
user.stats.points = 0;
|
||||||
|
|
||||||
|
user.fns.updateStats(stats);
|
||||||
|
|
||||||
|
expect(user.stats.points).to.eql(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
// @TODO: Set up sinon sandbox
|
||||||
|
xit('auto allocates stats if automaticAllocation is turned on', () => {
|
||||||
|
sandbox.stub(user.fns, 'autoAllocate');
|
||||||
|
|
||||||
|
let stats = {
|
||||||
|
exp: 261,
|
||||||
|
};
|
||||||
|
|
||||||
|
user.stats.lvl = 10;
|
||||||
|
|
||||||
|
user.fns.updateStats(stats);
|
||||||
|
|
||||||
|
expect(user.fns.autoAllocate).to.be.calledOnce;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user