mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 14:47:53 +01:00
* Moved critical hit calculation from _addPoints() to _calculateDelta(). Added user as an input argument to _calculateDelta() so for critical hit calculation
* Changed test to expect task value of 1.5 after critical hit
* Revert "Moved critical hit calculation from _addPoints() to _calculateDelta(). Added user as an input argument to _calculateDelta() so for critical hit calculation"
This reverts commit 51b8ab6498.
* Moved critical hit calculation to _changeTaskValue(). Use value stored in user._tmp.crit in _addPoints()
* Test is no longer affected by critical hits
* Removed unneeded comment
* Added WIP test of critical hits
* Want the crit function to return 2 to test critical hits
* Changed crit function to export as a function within an object so that it can be stubbed for testing. References to the crit() function were updated to call crit.crit() instead
* Added test for increased experience on critical hits
This commit is contained in:
committed by
Keith Holliday
parent
fa024e071b
commit
016447ec77
@@ -11,7 +11,7 @@ describe('crit', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('computes', () => {
|
it('computes', () => {
|
||||||
let result = crit(user);
|
let result = crit.crit(user);
|
||||||
expect(result).to.eql(1);
|
expect(result).to.eql(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import scoreTask from '../../../website/common/script/ops/scoreTask';
|
import scoreTask from '../../../website/common/script/ops/scoreTask';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
generateUser,
|
generateUser,
|
||||||
generateDaily,
|
generateDaily,
|
||||||
@@ -11,6 +12,7 @@ import i18n from '../../../website/common/script/i18n';
|
|||||||
import {
|
import {
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
} from '../../../website/common/script/libs/errors';
|
} from '../../../website/common/script/libs/errors';
|
||||||
|
import crit from '../../../website/common/script/fns/crit';
|
||||||
|
|
||||||
let EPSILON = 0.0001; // negligible distance between datapoints
|
let EPSILON = 0.0001; // negligible distance between datapoints
|
||||||
|
|
||||||
@@ -142,6 +144,32 @@ describe('shared.ops.scoreTask', () => {
|
|||||||
expect(ref.beforeUser._id).to.eql(ref.afterUser._id);
|
expect(ref.beforeUser._id).to.eql(ref.afterUser._id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('critical hits', () => {
|
||||||
|
let normalUser = ref.beforeUser;
|
||||||
|
expect(normalUser.party.quest.progress.up).to.eql(0);
|
||||||
|
normalUser.party.quest.key = 'gryphon';
|
||||||
|
let critUser = ref.afterUser;
|
||||||
|
expect(critUser.party.quest.progress.up).to.eql(0);
|
||||||
|
critUser.party.quest.key = 'gryphon';
|
||||||
|
let normalTask = todo;
|
||||||
|
let critTask = freshTodo;
|
||||||
|
|
||||||
|
scoreTask({ user: normalUser, task: normalTask, direction: 'up', cron: false });
|
||||||
|
let normalTaskDelta = normalUser.party.quest.progress.up;
|
||||||
|
|
||||||
|
sandbox.stub(crit, 'crit').returns(1.5);
|
||||||
|
scoreTask({ user: critUser, task: critTask, direction: 'up', cron: false });
|
||||||
|
let critTaskDelta = critUser.party.quest.progress.up;
|
||||||
|
crit.crit.restore();
|
||||||
|
|
||||||
|
expect(critUser.stats.hp).to.eql(normalUser.stats.hp);
|
||||||
|
expect(critUser.stats.gp).to.be.greaterThan(normalUser.stats.gp);
|
||||||
|
expect(critUser.stats.mp).to.be.greaterThan(normalUser.stats.mp);
|
||||||
|
expect(critUser.stats.exp).to.be.greaterThan(normalUser.stats.exp);
|
||||||
|
expect(critTask.value).to.eql(normalTask.value);
|
||||||
|
expect(critTaskDelta).to.be.greaterThan(normalTaskDelta);
|
||||||
|
});
|
||||||
|
|
||||||
it('and increments quest progress', () => {
|
it('and increments quest progress', () => {
|
||||||
expect(ref.afterUser.party.quest.progress.up).to.eql(0);
|
expect(ref.afterUser.party.quest.progress.up).to.eql(0);
|
||||||
ref.afterUser.party.quest.key = 'gryphon';
|
ref.afterUser.party.quest.key = 'gryphon';
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import predictableRandom from './predictableRandom';
|
import predictableRandom from './predictableRandom';
|
||||||
|
|
||||||
module.exports = function crit (user, stat = 'str', chance = 0.03) {
|
function crit (user, stat = 'str', chance = 0.03) {
|
||||||
let s = user._statsComputed[stat];
|
let s = user._statsComputed[stat];
|
||||||
if (predictableRandom(user) <= chance * (1 + s / 100)) {
|
if (predictableRandom(user) <= chance * (1 + s / 100)) {
|
||||||
return 1.5 + 4 * s / (s + 200);
|
return 1.5 + 4 * s / (s + 200);
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
module.exports = { crit };
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ api.wrap = function wrapUser (user, main = true) {
|
|||||||
user.fns = {
|
user.fns = {
|
||||||
handleTwoHanded: _.partial(importedFns.handleTwoHanded, user),
|
handleTwoHanded: _.partial(importedFns.handleTwoHanded, user),
|
||||||
predictableRandom: _.partial(importedFns.predictableRandom, user),
|
predictableRandom: _.partial(importedFns.predictableRandom, user),
|
||||||
crit: _.partial(importedFns.crit, user),
|
crit: _.partial(importedFns.crit.crit, user),
|
||||||
randomDrop: _.partial(importedFns.randomDrop, user),
|
randomDrop: _.partial(importedFns.randomDrop, user),
|
||||||
autoAllocate: _.partial(importedFns.autoAllocate, user),
|
autoAllocate: _.partial(importedFns.autoAllocate, user),
|
||||||
updateStats: _.partial(importedFns.updateStats, user),
|
updateStats: _.partial(importedFns.updateStats, user),
|
||||||
|
|||||||
@@ -103,11 +103,7 @@ function _subtractPoints (user, task, stats, delta) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _addPoints (user, task, stats, direction, delta) {
|
function _addPoints (user, task, stats, direction, delta) {
|
||||||
// ===== CRITICAL HITS =====
|
let _crit = user._tmp.crit || 1;
|
||||||
// allow critical hit only when checking off a task, not when unchecking it:
|
|
||||||
let _crit = delta > 0 ? crit(user) : 1;
|
|
||||||
// if there was a crit, alert the user via notification
|
|
||||||
if (_crit > 1) user._tmp.crit = _crit;
|
|
||||||
|
|
||||||
// Exp Modifier
|
// Exp Modifier
|
||||||
// ===== Intelligence =====
|
// ===== Intelligence =====
|
||||||
@@ -138,6 +134,12 @@ function _addPoints (user, task, stats, direction, delta) {
|
|||||||
function _changeTaskValue (user, task, direction, times, cron) {
|
function _changeTaskValue (user, task, direction, times, cron) {
|
||||||
let addToDelta = 0;
|
let addToDelta = 0;
|
||||||
|
|
||||||
|
// ===== CRITICAL HITS =====
|
||||||
|
// allow critical hit only when checking off a task, not when unchecking it:
|
||||||
|
let _crit = direction === 'up' ? crit.crit(user) : 1;
|
||||||
|
// if there was a crit, alert the user via notification
|
||||||
|
if (_crit > 1) user._tmp.crit = _crit;
|
||||||
|
|
||||||
// If multiple days have passed, multiply times days missed
|
// If multiple days have passed, multiply times days missed
|
||||||
_.times(times, () => {
|
_.times(times, () => {
|
||||||
// Each iteration calculate the nextDelta, which is then accumulated in the total delta.
|
// Each iteration calculate the nextDelta, which is then accumulated in the total delta.
|
||||||
@@ -153,9 +155,9 @@ function _changeTaskValue (user, task, direction, times, cron) {
|
|||||||
let prevProgress = user.party.quest.progress.up;
|
let prevProgress = user.party.quest.progress.up;
|
||||||
|
|
||||||
if (task.type === 'todo' || task.type === 'daily') {
|
if (task.type === 'todo' || task.type === 'daily') {
|
||||||
user.party.quest.progress.up += nextDelta * (1 + user._statsComputed.str / 200);
|
user.party.quest.progress.up += nextDelta * _crit * (1 + user._statsComputed.str / 200);
|
||||||
} else if (task.type === 'habit') {
|
} else if (task.type === 'habit') {
|
||||||
user.party.quest.progress.up += nextDelta * (0.5 + user._statsComputed.str / 400);
|
user.party.quest.progress.up += nextDelta * _crit * (0.5 + user._statsComputed.str / 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user._tmp.quest) user._tmp.quest = {};
|
if (!user._tmp.quest) user._tmp.quest = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user