Skip to content

Commit e2f9bf7

Browse files
feat: expose more drop info for bounty rewards (#682)
Co-authored-by: Matt <7128721+TobiTenno@users.noreply.github.com>
1 parent 281c52d commit e2f9bf7

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

lib/models/SyndicateJob.ts

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,17 @@ const determineLocation = (i18n: string, raw: RawSyndicateJob, isVault?: boolean
4848
return { location, locationWRot };
4949
};
5050

51-
const getBountyRewards = async (i18n: string, raw: RawSyndicateJob, isVault?: boolean): Promise<string[]> => {
51+
interface BountyReward {
52+
item: string;
53+
rarity: string;
54+
chance: number;
55+
}
56+
57+
const getBountyRewards = async (
58+
i18n: string,
59+
raw: RawSyndicateJob,
60+
isVault?: boolean
61+
): Promise<(string | BountyReward)[]> => {
5262
let location: string | undefined;
5363
let locationWRot: string | undefined;
5464
if (i18n.endsWith('PlagueStarTableRewards')) {
@@ -59,7 +69,7 @@ const getBountyRewards = async (i18n: string, raw: RawSyndicateJob, isVault?: bo
5969
({ location, locationWRot } = determineLocation(i18n, raw, isVault));
6070
}
6171
const url = `${apiBase}/drops/search/${encodeURIComponent(location!)}?grouped_by=location`;
62-
const reply: Record<string, { rewards: { item: string }[] }> = await fetch(url)
72+
const reply: Record<string, { rewards: BountyReward[] }> = await fetch(url)
6373
.then((res) => res.json())
6474
.catch(() => {}); // swallow errors
6575
const pool = reply?.[locationWRot];
@@ -68,7 +78,7 @@ const getBountyRewards = async (i18n: string, raw: RawSyndicateJob, isVault?: bo
6878
}
6979
const results = pool.rewards;
7080
if (results) {
71-
return Array.from(new Set(results.map((result) => result.item)));
81+
return Array.from(new Set(results));
7282
}
7383
return [];
7484
};
@@ -87,16 +97,30 @@ export interface RawSyndicateJob {
8797
masteryReq?: number;
8898
}
8999

100+
export interface RewardDrop extends BountyReward {
101+
count: number;
102+
}
103+
90104
/**
91105
* Represents a syndicate daily mission
92106
* @augments {WorldstateObject}
93107
*/
94108
export default class SyndicateJob extends WorldstateObject {
109+
/**
110+
* Reward pool unique name
111+
*/
112+
uniqueName: string;
113+
95114
/**
96115
* Array of strings describing rewards
97116
*/
98117
rewardPool: string[];
99118

119+
/**
120+
* A structured version of the reward pool
121+
*/
122+
rewardPoolDrops: RewardDrop[];
123+
100124
/**
101125
* The type of job this is
102126
*/
@@ -142,7 +166,21 @@ export default class SyndicateJob extends WorldstateObject {
142166
*/
143167
static async build(data: RawSyndicateJob, expiry: Date, deps: Dependency): Promise<SyndicateJob> {
144168
const job = new SyndicateJob(data, expiry, deps);
145-
job.rewardPool = await getBountyRewards(data.rewards, data, data.isVault);
169+
const rewards = await getBountyRewards(data.rewards, data, data.isVault);
170+
if (typeof rewards[0] === 'string') {
171+
job.rewardPool = rewards as string[];
172+
} else {
173+
job.rewardPoolDrops = (rewards as BountyReward[]).map((reward) => {
174+
const fragments = reward.item.split('X');
175+
return {
176+
...reward,
177+
item: fragments[fragments.length - 1].trim(),
178+
count: fragments.length > 1 ? parseInt(fragments[0], 10) : 1,
179+
};
180+
});
181+
182+
job.rewardPool = (rewards as BountyReward[]).map((reward) => reward.item);
183+
}
146184

147185
return job;
148186
}
@@ -165,11 +203,19 @@ export default class SyndicateJob extends WorldstateObject {
165203
},
166204
});
167205

206+
this.uniqueName = data.rewards;
207+
168208
this.rewardPool = [];
169209

210+
this.rewardPoolDrops = [];
211+
170212
const chamber = ((data.locationTag || '').match(/[A-Z]+(?![a-z])|[A-Z]?[a-z]+|\d+/g) || []).join(' ');
171213

172-
this.type = data.isVault ? `Isolation Vault ${chamber}` : (data.jobType ? languageString(data.jobType, locale): undefined);
214+
this.type = data.isVault
215+
? `Isolation Vault ${chamber}`
216+
: data.jobType
217+
? languageString(data.jobType, locale)
218+
: undefined;
173219

174220
this.enemyLevels = [data.minEnemyLevel, data.maxEnemyLevel];
175221

test/unit/syndicatejob.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as chai from 'chai';
22

3-
import SyndicateJob, { type RawSyndicateJob } from '../../lib/models/SyndicateJob.js';
3+
import SyndicateJob, { type RewardDrop, type RawSyndicateJob } from '../../lib/models/SyndicateJob.js';
44
import CambionFTier from '../data/CambionFTier.json' with { type: 'json' };
55
import CetusFTier from '../data/CetusFTier.json' with { type: 'json' };
66
import isoVaultBounty from '../data/isoVaultBounty.json' with { type: 'json' };
@@ -28,12 +28,13 @@ describe('SyndicateJob', () => {
2828
async function () {
2929
this.timeout(1100000000);
3030
const job = await SyndicateJob.build(data, new Date(), { locale });
31-
const verify = (rewardPool: string[]) => {
31+
const verify = (rewardPool: (string | RewardDrop)[]) => {
3232
rewardPool.should.be.an('array');
3333
rewardPool.length.should.be.at.least(1);
3434
};
3535

3636
if (job.rewardPool?.length) verify(job.rewardPool);
37+
if (job.rewardPoolDrops?.length) verify(job.rewardPoolDrops);
3738
};
3839

3940
it('should exist when requested', async () => poolTest(isoVaultBounty));

0 commit comments

Comments
 (0)