diff --git a/test/common/fns/randomDrop.test.js b/test/common/fns/randomDrop.test.js index 9ef30ca267..c04bddacb7 100644 --- a/test/common/fns/randomDrop.test.js +++ b/test/common/fns/randomDrop.test.js @@ -16,17 +16,14 @@ describe('common.fns.randomDrop', () => { user = generateUser(); user._tmp = user._tmp ? user._tmp : {}; task = generateTodo({ userId: user._id }); - predictableRandom = () => { - return 0.5; - }; + predictableRandom = sandbox.stub().returns(0.5); }); it('drops an item for the user.party.quest.progress', () => { expect(user.party.quest.progress.collectedItems).to.eql(0); user.party.quest.key = 'vice2'; - predictableRandom = () => { - return 0.0001; - }; + predictableRandom.returns(0.0001); + randomDrop(user, { task, predictableRandom }); expect(user.party.quest.progress.collectedItems).to.eql(1); expect(user._tmp.quest.collection).to.eql(1); @@ -50,9 +47,8 @@ describe('common.fns.randomDrop', () => { it('drops something when the task is a todo', () => { expect(user._tmp).to.eql({}); user.flags.dropsEnabled = true; - predictableRandom = () => { - return 0.1; - }; + predictableRandom.returns(0.1); + randomDrop(user, { task, predictableRandom }); expect(user._tmp).to.not.eql({}); }); @@ -61,9 +57,8 @@ describe('common.fns.randomDrop', () => { task = generateHabit({ userId: user._id }); expect(user._tmp).to.eql({}); user.flags.dropsEnabled = true; - predictableRandom = () => { - return 0.1; - }; + predictableRandom.returns(0.1); + randomDrop(user, { task, predictableRandom }); expect(user._tmp).to.not.eql({}); }); @@ -72,9 +67,8 @@ describe('common.fns.randomDrop', () => { task = generateDaily({ userId: user._id }); expect(user._tmp).to.eql({}); user.flags.dropsEnabled = true; - predictableRandom = () => { - return 0.1; - }; + predictableRandom.returns(0.1); + randomDrop(user, { task, predictableRandom }); expect(user._tmp).to.not.eql({}); }); @@ -83,34 +77,30 @@ describe('common.fns.randomDrop', () => { task = generateReward({ userId: user._id }); expect(user._tmp).to.eql({}); user.flags.dropsEnabled = true; - predictableRandom = () => { - return 0.1; - }; + predictableRandom.returns(0.1); + randomDrop(user, { task, predictableRandom }); expect(user._tmp).to.not.eql({}); }); it('drops food', () => { - predictableRandom = () => { - return 0.65; - }; + predictableRandom.returns(0.65); + randomDrop(user, { task, predictableRandom }); expect(user._tmp.drop.type).to.eql('Food'); }); it('drops eggs', () => { - predictableRandom = () => { - return 0.35; - }; + predictableRandom.returns(0.35); + randomDrop(user, { task, predictableRandom }); expect(user._tmp.drop.type).to.eql('Egg'); }); context('drops hatching potion', () => { it('drops a very rare potion', () => { - predictableRandom = () => { - return 0.01; - }; + predictableRandom.returns(0.01); + randomDrop(user, { task, predictableRandom }); expect(user._tmp.drop.type).to.eql('HatchingPotion'); expect(user._tmp.drop.value).to.eql(5); @@ -118,9 +108,8 @@ describe('common.fns.randomDrop', () => { }); it('drops a rare potion', () => { - predictableRandom = () => { - return 0.08; - }; + predictableRandom.returns(0.08); + randomDrop(user, { task, predictableRandom }); expect(user._tmp.drop.type).to.eql('HatchingPotion'); expect(user._tmp.drop.value).to.eql(4); @@ -129,9 +118,8 @@ describe('common.fns.randomDrop', () => { }); it('drops an uncommon potion', () => { - predictableRandom = () => { - return 0.17; - }; + predictableRandom.returns(0.17); + randomDrop(user, { task, predictableRandom }); expect(user._tmp.drop.type).to.eql('HatchingPotion'); expect(user._tmp.drop.value).to.eql(3); @@ -140,9 +128,8 @@ describe('common.fns.randomDrop', () => { }); it('drops a common potion', () => { - predictableRandom = () => { - return 0.20; - }; + predictableRandom.returns(0.20); + randomDrop(user, { task, predictableRandom }); expect(user._tmp.drop.type).to.eql('HatchingPotion'); expect(user._tmp.drop.value).to.eql(2); diff --git a/website/common/script/fns/randomDrop.js b/website/common/script/fns/randomDrop.js index 188ca32ec0..0022bf09be 100644 --- a/website/common/script/fns/randomDrop.js +++ b/website/common/script/fns/randomDrop.js @@ -5,6 +5,9 @@ import { daysSince } from '../cron'; import { diminishingReturns } from '../statHelpers'; import randomVal from './randomVal'; +// TODO This is only used on the server +// move to user model as an instance method? + // Clone a drop object maintaining its functions so that we can change it without affecting the original item function cloneDropItem (drop) { return _.cloneDeep(drop, (val) => { @@ -12,18 +15,20 @@ function cloneDropItem (drop) { }); } +function trueRandom () { + return Math.random(); +} + module.exports = function randomDrop (user, options, req = {}) { let acceptableDrops; - let chance; let drop; let dropMultiplier; let rarity; - let task; - let predictableRandom = options.predictableRandom || Math.random; - task = options.task; + let predictableRandom = options.predictableRandom || trueRandom; + let task = options.task; - chance = _.min([Math.abs(task.value - 21.27), 37.5]) / 150 + 0.02; + let chance = _.min([Math.abs(task.value - 21.27), 37.5]) / 150 + 0.02; chance *= task.priority * // Task priority: +50% for Medium, +100% for Hard (1 + (task.streak / 100 || 0)) * // Streak bonus: +1% per streak (1 + user._statsComputed.per / 100) * // PERception: +1% per point @@ -35,7 +40,7 @@ module.exports = function randomDrop (user, options, req = {}) { }, 0) || 0)); chance = diminishingReturns(chance, 0.75); - if (predictableRandom(user, user.stats.gp) < chance) { + if (predictableRandom() < chance) { if (!user.party.quest.progress.collectedItems) user.party.quest.progress.collectedItems = 0; user.party.quest.progress.collectedItems++; if (!user._tmp.quest) user._tmp.quest = {}; @@ -54,8 +59,8 @@ module.exports = function randomDrop (user, options, req = {}) { return; } - if (user.flags && user.flags.dropsEnabled && predictableRandom(user, user.stats.exp) < chance) { - rarity = predictableRandom(user, user.stats.gp); + if (user.flags && user.flags.dropsEnabled && predictableRandom() < chance) { + rarity = predictableRandom(); if (rarity > 0.6) { // food 40% chance drop = cloneDropItem(randomVal(_.where(content.food, {