mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 07:07:35 +01:00
refactor: Make quest methods private instance methods
This commit is contained in:
@@ -50,6 +50,318 @@ describe('Group Model', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Static Methods', () => {
|
||||||
|
describe('processQuestProgress', () => {
|
||||||
|
let progress;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
progress = {
|
||||||
|
up: 5,
|
||||||
|
down: -5,
|
||||||
|
collect: 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
party.quest.members = {
|
||||||
|
[questLeader._id]: true,
|
||||||
|
[participatingMember._id]: true,
|
||||||
|
[nonParticipatingMember._id]: false,
|
||||||
|
[undecidedMember._id]: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
await party.save();
|
||||||
|
});
|
||||||
|
|
||||||
|
context('early returns', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
sandbox.stub(Group.prototype, '_processBossQuest').returns(Promise.resolve());
|
||||||
|
sandbox.stub(Group.prototype, '_processCollectionQuest').returns(Promise.resolve());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns early if user is not in a party', async () => {
|
||||||
|
let userWithoutParty = new User();
|
||||||
|
|
||||||
|
await userWithoutParty.save();
|
||||||
|
|
||||||
|
await Group.processQuestProgress(userWithoutParty, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party._processBossQuest).to.not.be.called;
|
||||||
|
expect(party._processCollectionQuest).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns early if party is not on quest', async () => {
|
||||||
|
party.quest.active = false;
|
||||||
|
await party.save();
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party._processBossQuest).to.not.be.called;
|
||||||
|
expect(party._processCollectionQuest).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns early if user is not on quest', async () => {
|
||||||
|
await Group.processQuestProgress(nonParticipatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party._processBossQuest).to.not.be.called;
|
||||||
|
expect(party._processCollectionQuest).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns early if user has made no progress', async () => {
|
||||||
|
await Group.processQuestProgress(participatingMember, null);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party._processBossQuest).to.not.be.called;
|
||||||
|
expect(party._processCollectionQuest).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns early if quest does not exist', async () => {
|
||||||
|
party.quest.key = 'foobar';
|
||||||
|
await party.save();
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party._processBossQuest).to.not.be.called;
|
||||||
|
expect(party._processCollectionQuest).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls _processBossQuest if quest is a boss quest', async () => {
|
||||||
|
party.quest.key = 'whale';
|
||||||
|
|
||||||
|
await party.startQuest(questLeader);
|
||||||
|
await party.save();
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(Group.prototype._processBossQuest).to.be.calledOnce;
|
||||||
|
expect(party._processCollectionQuest).to.not.be.called;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls _processCollectionQuest if quest is a collection quest', async () => {
|
||||||
|
party.quest.key = 'evilsanta2';
|
||||||
|
|
||||||
|
await party.startQuest(questLeader);
|
||||||
|
await party.save();
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party._processBossQuest).to.not.be.called;
|
||||||
|
expect(Group.prototype._processCollectionQuest).to.be.calledOnce;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('Boss Quests', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
party.quest.key = 'whale';
|
||||||
|
|
||||||
|
await party.startQuest(questLeader);
|
||||||
|
await party.save();
|
||||||
|
|
||||||
|
sandbox.stub(Group.prototype, 'sendChat');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies user\'s progress to quest boss hp', async () => {
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party.quest.progress.hp).to.eql(495);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends a chat message about progress', async () => {
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledOnce;
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledWith('`Participating Member attacks Wailing Whale for 5.0 damage.` `Wailing Whale attacks party for 7.5 damage.`');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies damage only to participating members of party', async () => {
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
let [
|
||||||
|
updatedLeader,
|
||||||
|
updatedParticipatingMember,
|
||||||
|
updatedNonParticipatingMember,
|
||||||
|
updatedUndecidedMember,
|
||||||
|
] = await Promise.all([
|
||||||
|
User.findById(questLeader._id),
|
||||||
|
User.findById(participatingMember._id),
|
||||||
|
User.findById(nonParticipatingMember._id),
|
||||||
|
User.findById(undecidedMember._id),
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(updatedLeader.stats.hp).to.eql(42.5);
|
||||||
|
expect(updatedParticipatingMember.stats.hp).to.eql(42.5);
|
||||||
|
expect(updatedNonParticipatingMember.stats.hp).to.eql(50);
|
||||||
|
expect(updatedUndecidedMember.stats.hp).to.eql(50);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends message about victory', async () => {
|
||||||
|
progress.up = 999;
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledTwice;
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledWith('`You defeated Wailing Whale! Questing party members receive the rewards of victory.`');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls finishQuest when boss has <= 0 hp', async () => {
|
||||||
|
let quest = questScrolls[party.quest.key];
|
||||||
|
let finishQuest = sandbox.spy(Group.prototype, 'finishQuest');
|
||||||
|
|
||||||
|
progress.up = 999;
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
expect(finishQuest).to.be.calledOnce;
|
||||||
|
expect(finishQuest).to.be.calledWith(quest);
|
||||||
|
});
|
||||||
|
|
||||||
|
context('with Rage', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
party.quest.active = false;
|
||||||
|
party.quest.key = 'trex_undead';
|
||||||
|
|
||||||
|
await party.startQuest(questLeader);
|
||||||
|
await party.save();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies down progress to boss rage', async () => {
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party.quest.progress.rage).to.eql(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('activates rage when progress.down triggers rage bar', async () => {
|
||||||
|
let quest = questScrolls[party.quest.key];
|
||||||
|
|
||||||
|
progress.down = -999;
|
||||||
|
party.quest.progress.hp = 300;
|
||||||
|
|
||||||
|
await party.save();
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledWith(quest.boss.rage.effect('en'));
|
||||||
|
expect(party.quest.progress.hp).to.eql(383.5);
|
||||||
|
expect(party.quest.progress.rage).to.eql(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rage sets boss hp to max hp if raging would have caused hp to be higher than the max', async () => {
|
||||||
|
progress.down = -999;
|
||||||
|
|
||||||
|
party.quest.progress.hp = 490;
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party.quest.progress.hp).to.eql(500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('Collection Quests', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
party.quest.key = 'atom1';
|
||||||
|
|
||||||
|
await party.startQuest(questLeader);
|
||||||
|
await party.save();
|
||||||
|
|
||||||
|
sandbox.stub(Group.prototype, 'sendChat');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('applies user\'s progress to found quest items', async () => {
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(party.quest.progress.collect.soapBars).to.eq(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends a chat message about progress', async () => {
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledOnce;
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledWith('`Participating Member found 5 Bars of Soap.`');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends a chat message if no progress is made', async () => {
|
||||||
|
progress.collect = 0;
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledOnce;
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledWith('`Participating Member found nothing.`');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles collection quests with multiple items', async () => {
|
||||||
|
progress.collect = 10;
|
||||||
|
party.quest.key = 'evilsanta2';
|
||||||
|
party.quest.active = false;
|
||||||
|
|
||||||
|
await party.startQuest(questLeader);
|
||||||
|
await party.save();
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledOnce;
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledWithMatch(/`Participating Member found/);
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledWithMatch(/\d* (Tracks|Broken Twigs)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sends message about victory', async () => {
|
||||||
|
progress.collect = 500;
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
party = await Group.findOne({_id: party._id});
|
||||||
|
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledTwice;
|
||||||
|
expect(Group.prototype.sendChat).to.be.calledWith('`All items found! Party has received their rewards.`');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls finishQuest when all items are found', async () => {
|
||||||
|
let quest = questScrolls[party.quest.key];
|
||||||
|
let finishQuest = sandbox.spy(Group.prototype, 'finishQuest');
|
||||||
|
|
||||||
|
progress.collect = 999;
|
||||||
|
|
||||||
|
await Group.processQuestProgress(participatingMember, progress);
|
||||||
|
|
||||||
|
expect(finishQuest).to.be.calledOnce;
|
||||||
|
expect(finishQuest).to.be.calledWith(quest);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
context('Instance Methods', () => {
|
context('Instance Methods', () => {
|
||||||
describe('#startQuest', () => {
|
describe('#startQuest', () => {
|
||||||
context('Failure Conditions', () => {
|
context('Failure Conditions', () => {
|
||||||
@@ -300,363 +612,5 @@ describe('Group Model', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('processQuestProgress', () => {
|
|
||||||
let progress;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
progress = {
|
|
||||||
up: 5,
|
|
||||||
down: -5,
|
|
||||||
};
|
|
||||||
|
|
||||||
party.quest.active = true;
|
|
||||||
party.quest.members = {
|
|
||||||
[questLeader._id]: true,
|
|
||||||
[participatingMember._id]: true,
|
|
||||||
[nonParticipatingMember._id]: false,
|
|
||||||
[undecidedMember._id]: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
await party.save();
|
|
||||||
|
|
||||||
sandbox.stub(Group, 'processBossQuest').returns(Promise.resolve());
|
|
||||||
sandbox.stub(Group, 'processCollectionQuest').returns(Promise.resolve());
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns early if user is not in a party', async () => {
|
|
||||||
let userWithoutParty = new User();
|
|
||||||
|
|
||||||
await userWithoutParty.save();
|
|
||||||
|
|
||||||
await Group.processQuestProgress(userWithoutParty, progress);
|
|
||||||
|
|
||||||
expect(Group.processBossQuest).to.not.be.called;
|
|
||||||
expect(Group.processCollectionQuest).to.not.be.called;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns early if party is not on quest', async () => {
|
|
||||||
party.quest.active = false;
|
|
||||||
await party.save();
|
|
||||||
|
|
||||||
await Group.processQuestProgress(participatingMember, progress);
|
|
||||||
|
|
||||||
expect(Group.processBossQuest).to.not.be.called;
|
|
||||||
expect(Group.processCollectionQuest).to.not.be.called;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns early if user is not on quest', async () => {
|
|
||||||
await Group.processQuestProgress(nonParticipatingMember, progress);
|
|
||||||
|
|
||||||
expect(Group.processBossQuest).to.not.be.called;
|
|
||||||
expect(Group.processCollectionQuest).to.not.be.called;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns early if user has made no progress', async () => {
|
|
||||||
await Group.processQuestProgress(participatingMember, null);
|
|
||||||
|
|
||||||
expect(Group.processBossQuest).to.not.be.called;
|
|
||||||
expect(Group.processCollectionQuest).to.not.be.called;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns early if quest does not exist', async () => {
|
|
||||||
party.quest.key = 'foobar';
|
|
||||||
await party.save();
|
|
||||||
|
|
||||||
await Group.processQuestProgress(participatingMember, progress);
|
|
||||||
|
|
||||||
expect(Group.processBossQuest).to.not.be.called;
|
|
||||||
expect(Group.processCollectionQuest).to.not.be.called;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls processBossQuest if quest is a boss quest', async () => {
|
|
||||||
party.quest.key = 'whale';
|
|
||||||
await party.save();
|
|
||||||
|
|
||||||
await Group.processQuestProgress(participatingMember, progress);
|
|
||||||
|
|
||||||
expect(Group.processBossQuest).to.be.calledOnce;
|
|
||||||
expect(Group.processCollectionQuest).to.not.be.called;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls processCollectionQuest if quest is a collection quest', async () => {
|
|
||||||
party.quest.key = 'evilsanta2';
|
|
||||||
await party.save();
|
|
||||||
|
|
||||||
await Group.processQuestProgress(participatingMember, progress);
|
|
||||||
|
|
||||||
expect(Group.processBossQuest).to.not.be.called;
|
|
||||||
expect(Group.processCollectionQuest).to.be.calledOnce;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('processBossQuest', () => {
|
|
||||||
let progress, quest;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
progress = {
|
|
||||||
up: 5,
|
|
||||||
down: -5,
|
|
||||||
};
|
|
||||||
quest = questScrolls.whale;
|
|
||||||
|
|
||||||
party.quest.members = {
|
|
||||||
[questLeader._id]: true,
|
|
||||||
[participatingMember._id]: true,
|
|
||||||
[nonParticipatingMember._id]: false,
|
|
||||||
[undecidedMember._id]: null,
|
|
||||||
};
|
|
||||||
party.quest.key = 'whale';
|
|
||||||
|
|
||||||
await party.save();
|
|
||||||
await party.startQuest(questLeader);
|
|
||||||
|
|
||||||
sandbox.stub(party, 'sendChat');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('applies user\'s progress to quest boss hp', async () => {
|
|
||||||
await Group.processBossQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.quest.progress.hp).to.eql(495);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sends a chat message about progress', async () => {
|
|
||||||
await Group.processBossQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.sendChat).to.be.calledOnce;
|
|
||||||
expect(party.sendChat).to.be.calledWith('`Participating Member attacks Wailing Whale for 5.0 damage.` `Wailing Whale attacks party for 7.5 damage.`');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('applies damage only to participating members of party', async () => {
|
|
||||||
await Group.processBossQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
let [
|
|
||||||
updatedLeader,
|
|
||||||
updatedParticipatingMember,
|
|
||||||
updatedNonParticipatingMember,
|
|
||||||
updatedUndecidedMember,
|
|
||||||
] = await Promise.all([
|
|
||||||
User.findById(questLeader._id),
|
|
||||||
User.findById(participatingMember._id),
|
|
||||||
User.findById(nonParticipatingMember._id),
|
|
||||||
User.findById(undecidedMember._id),
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect(updatedLeader.stats.hp).to.eql(42.5);
|
|
||||||
expect(updatedParticipatingMember.stats.hp).to.eql(42.5);
|
|
||||||
expect(updatedNonParticipatingMember.stats.hp).to.eql(50);
|
|
||||||
expect(updatedUndecidedMember.stats.hp).to.eql(50);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sends message about victory', async () => {
|
|
||||||
progress.up = 999;
|
|
||||||
|
|
||||||
await Group.processBossQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.sendChat).to.be.calledTwice;
|
|
||||||
expect(party.sendChat).to.be.calledWith('`You defeated Wailing Whale! Questing party members receive the rewards of victory.`');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls finishQuest when boss has <= 0 hp', async () => {
|
|
||||||
progress.up = 999;
|
|
||||||
sandbox.spy(party, 'finishQuest');
|
|
||||||
|
|
||||||
await Group.processBossQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.finishQuest).to.be.calledOnce;
|
|
||||||
expect(party.finishQuest).to.be.calledWith(quest);
|
|
||||||
});
|
|
||||||
|
|
||||||
context('rage quests', () => {
|
|
||||||
beforeEach(async () => {
|
|
||||||
party.quest.active = false;
|
|
||||||
party.quest.key = 'trex_undead';
|
|
||||||
quest = questScrolls[party.quest.key];
|
|
||||||
|
|
||||||
await party.save();
|
|
||||||
|
|
||||||
await party.startQuest(questLeader);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('applies down progress to boss rage', async () => {
|
|
||||||
await Group.processBossQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.quest.progress.rage).to.eql(10);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('activates rage when progress.down triggers rage bar', async () => {
|
|
||||||
progress.down = -999;
|
|
||||||
|
|
||||||
party.quest.progress.hp = 300;
|
|
||||||
|
|
||||||
await Group.processBossQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.sendChat).to.be.calledWith(quest.boss.rage.effect('en'));
|
|
||||||
expect(party.quest.progress.hp).to.eql(383.5);
|
|
||||||
expect(party.quest.progress.rage).to.eql(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('rage sets boss hp to max hp if raging would have caused hp to be higher than the max', async () => {
|
|
||||||
progress.down = -999;
|
|
||||||
|
|
||||||
party.quest.progress.hp = 490;
|
|
||||||
|
|
||||||
await Group.processBossQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.quest.progress.hp).to.eql(500);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('processCollectionQuest', () => {
|
|
||||||
let progress, quest;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
progress = {
|
|
||||||
collect: 5,
|
|
||||||
};
|
|
||||||
quest = questScrolls.atom1;
|
|
||||||
|
|
||||||
party.quest.members = {
|
|
||||||
[questLeader._id]: true,
|
|
||||||
[participatingMember._id]: true,
|
|
||||||
[nonParticipatingMember._id]: false,
|
|
||||||
[undecidedMember._id]: null,
|
|
||||||
};
|
|
||||||
party.quest.key = 'atom1';
|
|
||||||
|
|
||||||
await party.save();
|
|
||||||
await party.startQuest(questLeader);
|
|
||||||
|
|
||||||
sandbox.stub(party, 'sendChat');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('applies user\'s progress to found quest items', async () => {
|
|
||||||
await Group.processCollectionQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.quest.progress.collect.soapBars).to.eq(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sends a chat message about progress', async () => {
|
|
||||||
await Group.processCollectionQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.sendChat).to.be.calledOnce;
|
|
||||||
expect(party.sendChat).to.be.calledWith('`Participating Member found 5 Bars of Soap.`');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sends a chat message if no progress is made', async () => {
|
|
||||||
progress.collect = 0;
|
|
||||||
|
|
||||||
await Group.processCollectionQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.sendChat).to.be.calledOnce;
|
|
||||||
expect(party.sendChat).to.be.calledWith('`Participating Member found nothing.`');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('handles collection quests with multiple items', async () => {
|
|
||||||
progress.collect = 10;
|
|
||||||
party.quest.key = 'evilsanta2';
|
|
||||||
party.quest.active = false;
|
|
||||||
quest = questScrolls.evilsanta2;
|
|
||||||
|
|
||||||
await party.save();
|
|
||||||
await party.startQuest(questLeader);
|
|
||||||
|
|
||||||
await Group.processCollectionQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.sendChat).to.be.calledOnce;
|
|
||||||
expect(party.sendChat).to.be.calledWithMatch(/`Participating Member found/);;
|
|
||||||
expect(party.sendChat).to.be.calledWithMatch(/\d* (Tracks|Broken Twigs)/);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sends message about victory', async () => {
|
|
||||||
progress.collect = 500;
|
|
||||||
|
|
||||||
await Group.processCollectionQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.sendChat).to.be.calledTwice;
|
|
||||||
expect(party.sendChat).to.be.calledWith('`All items found! Party has received their rewards.`');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls finishQuest when all items are found', async () => {
|
|
||||||
progress.collect = 999;
|
|
||||||
sandbox.spy(party, 'finishQuest');
|
|
||||||
|
|
||||||
await Group.processCollectionQuest({
|
|
||||||
user: participatingMember,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group: party,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(party.finishQuest).to.be.calledOnce;
|
|
||||||
expect(party.finishQuest).to.be.calledWith(quest);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -489,54 +489,14 @@ function _isOnQuest (user, progress, group) {
|
|||||||
return group && progress && group.quest && group.quest.active && group.quest.members[user._id] === true;
|
return group && progress && group.quest && group.quest.active && group.quest.members[user._id] === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processCollectionQuest (options) {
|
schema.methods._processBossQuest = async function processBossQuest (options) {
|
||||||
let {
|
let {
|
||||||
user,
|
user,
|
||||||
progress,
|
progress,
|
||||||
quest,
|
|
||||||
group,
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
let itemsFound = {};
|
|
||||||
|
|
||||||
_.times(progress.collect, () => {
|
|
||||||
let item = shared.fns.randomVal(user, quest.collect, {key: true, seed: Math.random()});
|
|
||||||
|
|
||||||
if (!itemsFound[item]) {
|
|
||||||
itemsFound[item] = 0;
|
|
||||||
}
|
|
||||||
itemsFound[item]++;
|
|
||||||
group.quest.progress.collect[item]++;
|
|
||||||
});
|
|
||||||
|
|
||||||
let foundText = _.reduce(itemsFound, (m, v, k) => {
|
|
||||||
m.push(`${v} ${quest.collect[k].text('en')}`);
|
|
||||||
return m;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
foundText = foundText.length > 0 ? foundText.join(', ') : 'nothing';
|
|
||||||
group.sendChat(`\`${user.profile.name} found ${foundText}.\``);
|
|
||||||
group.markModified('quest.progress.collect');
|
|
||||||
|
|
||||||
// Still needs completing
|
|
||||||
if (_.find(quest.collect, (v, k) => {
|
|
||||||
return group.quest.progress.collect[k] < v.count;
|
|
||||||
})) return await group.save();
|
|
||||||
|
|
||||||
await group.finishQuest(quest);
|
|
||||||
group.sendChat('`All items found! Party has received their rewards.`');
|
|
||||||
|
|
||||||
return await group.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function processBossQuest (options) {
|
|
||||||
let {
|
|
||||||
user,
|
|
||||||
progress,
|
|
||||||
quest,
|
|
||||||
group,
|
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
|
let group = this;
|
||||||
|
let quest = questScrolls[group.quest.key];
|
||||||
let down = progress.down * quest.boss.str; // multiply by boss strength
|
let down = progress.down * quest.boss.str; // multiply by boss strength
|
||||||
|
|
||||||
group.quest.progress.hp -= progress.up;
|
group.quest.progress.hp -= progress.up;
|
||||||
@@ -580,10 +540,47 @@ async function processBossQuest (options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return await group.save();
|
return await group.save();
|
||||||
}
|
};
|
||||||
|
|
||||||
schema.statics.processBossQuest = processBossQuest;
|
schema.methods._processCollectionQuest = async function processCollectionQuest (options) {
|
||||||
schema.statics.processCollectionQuest = processCollectionQuest;
|
let {
|
||||||
|
user,
|
||||||
|
progress,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
let group = this;
|
||||||
|
let quest = questScrolls[group.quest.key];
|
||||||
|
let itemsFound = {};
|
||||||
|
|
||||||
|
_.times(progress.collect, () => {
|
||||||
|
let item = shared.fns.randomVal(user, quest.collect, {key: true, seed: Math.random()});
|
||||||
|
|
||||||
|
if (!itemsFound[item]) {
|
||||||
|
itemsFound[item] = 0;
|
||||||
|
}
|
||||||
|
itemsFound[item]++;
|
||||||
|
group.quest.progress.collect[item]++;
|
||||||
|
});
|
||||||
|
|
||||||
|
let foundText = _.reduce(itemsFound, (m, v, k) => {
|
||||||
|
m.push(`${v} ${quest.collect[k].text('en')}`);
|
||||||
|
return m;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
foundText = foundText.length > 0 ? foundText.join(', ') : 'nothing';
|
||||||
|
group.sendChat(`\`${user.profile.name} found ${foundText}.\``);
|
||||||
|
group.markModified('quest.progress.collect');
|
||||||
|
|
||||||
|
// Still needs completing
|
||||||
|
if (_.find(quest.collect, (v, k) => {
|
||||||
|
return group.quest.progress.collect[k] < v.count;
|
||||||
|
})) return await group.save();
|
||||||
|
|
||||||
|
await group.finishQuest(quest);
|
||||||
|
group.sendChat('`All items found! Party has received their rewards.`');
|
||||||
|
|
||||||
|
return await group.save();
|
||||||
|
};
|
||||||
|
|
||||||
schema.statics.processQuestProgress = async function processQuestProgress (user, progress) {
|
schema.statics.processQuestProgress = async function processQuestProgress (user, progress) {
|
||||||
let group = await this.getGroup({user, groupId: 'party'});
|
let group = await this.getGroup({user, groupId: 'party'});
|
||||||
@@ -607,10 +604,9 @@ schema.statics.processQuestProgress = async function processQuestProgress (user,
|
|||||||
|
|
||||||
let questType = quest.boss ? 'Boss' : 'Collection';
|
let questType = quest.boss ? 'Boss' : 'Collection';
|
||||||
|
|
||||||
await this[`process${questType}Quest`]({
|
await group[`_process${questType}Quest`]({
|
||||||
user,
|
user,
|
||||||
progress,
|
progress,
|
||||||
quest,
|
|
||||||
group,
|
group,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user