diff --git a/src/lib/types/minions.ts b/src/lib/types/minions.ts index 26d33f24a2..5fe7a333fb 100644 --- a/src/lib/types/minions.ts +++ b/src/lib/types/minions.ts @@ -149,6 +149,7 @@ export interface FishingActivityTaskOptions extends ActivityTaskOptions { type: 'Fishing'; fishID: number; quantity: number; + flakesQuantity?: number; iQty?: number; } diff --git a/src/lib/util/repeatStoredTrip.ts b/src/lib/util/repeatStoredTrip.ts index f83374e8f0..09f230c5dd 100644 --- a/src/lib/util/repeatStoredTrip.ts +++ b/src/lib/util/repeatStoredTrip.ts @@ -306,7 +306,11 @@ const tripHandlers = { }, [activity_type_enum.Fishing]: { commandName: 'fish', - args: (data: FishingActivityTaskOptions) => ({ name: data.fishID, quantity: data.iQty }) + args: (data: FishingActivityTaskOptions) => ({ + name: data.fishID, + quantity: data.iQty, + flakes: data.flakesQuantity !== undefined + }) }, [activity_type_enum.FishingTrawler]: { commandName: 'minigames', diff --git a/src/mahoji/commands/fish.ts b/src/mahoji/commands/fish.ts index 8e585bb919..b6dd34e273 100644 --- a/src/mahoji/commands/fish.ts +++ b/src/mahoji/commands/fish.ts @@ -42,9 +42,19 @@ export const fishCommand: OSBMahojiCommand = { description: 'The quantity you want to fish (optional).', required: false, min_value: 1 + }, + { + type: ApplicationCommandOptionType.Boolean, + name: 'flakes', + description: 'Use spirit flakes?', + required: false } ], - run: async ({ options, userID, channelID }: CommandRunOptions<{ name: string; quantity?: number }>) => { + run: async ({ + options, + userID, + channelID + }: CommandRunOptions<{ name: string; quantity?: number; flakes?: boolean }>) => { const user = await mUserFetch(userID); const fish = Fishing.Fishes.find( fish => @@ -132,8 +142,22 @@ export const fishCommand: OSBMahojiCommand = { const maxTripLength = calcMaxTripLength(user, 'Fishing'); - let { quantity } = options; - if (!quantity) quantity = Math.floor(maxTripLength / scaledTimePerFish); + let { quantity, flakes } = options; + if (!quantity) { + quantity = Math.floor(maxTripLength / scaledTimePerFish); + } + let flakesQuantity: number | undefined; + const cost = new Bank(); + + if (flakes) { + if (!user.bank.has('Spirit flakes')) { + return 'You need to have at least one spirit flake!'; + } + + flakesQuantity = Math.min(user.bank.amount('Spirit flakes'), quantity); + boosts.push(`More fish from using ${flakesQuantity}x Spirit flakes`); + cost.add('Spirit flakes', flakesQuantity); + } if (fish.bait) { const baseCost = new Bank().add(fish.bait); @@ -146,11 +170,12 @@ export const fishCommand: OSBMahojiCommand = { quantity = maxCanDo; } - const cost = new Bank(); - cost.add(baseCost.multiply(quantity)); + cost.add(fish.bait, quantity); + } - // Remove the bait from their bank. - await user.removeItemsFromBank(new Bank().add(fish.bait, quantity)); + if (cost.length > 0) { + // Remove the bait and/or spirit flakes from their bank. + await user.removeItemsFromBank(cost); } let duration = quantity * scaledTimePerFish; @@ -173,7 +198,8 @@ export const fishCommand: OSBMahojiCommand = { quantity, iQty: options.quantity ? options.quantity : undefined, duration, - type: 'Fishing' + type: 'Fishing', + flakesQuantity }); let response = `${user.minionName} is now fishing ${quantity}x ${fish.name}, it'll take around ${formatDuration( diff --git a/src/tasks/minions/fishingActivity.ts b/src/tasks/minions/fishingActivity.ts index 1eb322259e..6e51ef4e63 100644 --- a/src/tasks/minions/fishingActivity.ts +++ b/src/tasks/minions/fishingActivity.ts @@ -41,6 +41,7 @@ export const fishingTask: MinionTask = { }), async run(data: FishingActivityTaskOptions) { const { fishID, quantity, userID, channelID, duration } = data; + let { flakesQuantity } = data; const user = await mUserFetch(userID); const currentLevel = user.skillLevel(SkillsEnum.Fishing); const { blessingEquipped, blessingChance } = radasBlessing(user); @@ -160,6 +161,11 @@ export const fishingTask: MinionTask = { } else { lootQuantity += blessingEquipped && percentChance(blessingChance) ? 2 : 1; } + + if (flakesQuantity && flakesQuantity > 0) { + lootQuantity += percentChance(50) ? 1 : 0; + flakesQuantity--; + } } const loot = new Bank({ diff --git a/tests/unit/commands/fish.test.ts b/tests/unit/commands/fish.test.ts index 469a6720fe..57582c0efc 100644 --- a/tests/unit/commands/fish.test.ts +++ b/tests/unit/commands/fish.test.ts @@ -92,4 +92,41 @@ describe('Fish Command', () => { **Boosts:** +9 trip minutes for having a Fish sack barrel.` }); }); + + it('should handle using flakes without flakes in bank', () => { + testRunCmd({ + cmd: fishCommand, + opts: { name: 'shrimps', flakes: true }, + user: { + skills_fishing: 999_999 + }, + result: 'You need to have at least one spirit flake!' + }); + }); + + it('should fish with flakes', () => { + testRunCmd({ + cmd: fishCommand, + opts: { name: 'shrimps', flakes: true }, + user: { + bank: new Bank({ 'Spirit flakes': 10000 }) + }, + result: `<:minion:778418736180494347> Your minion is now fishing 251x Shrimps, it'll take around 29 minutes, 58 seconds to finish. + +**Boosts:** More fish from using 251x Spirit flakes.` + }); + }); + + it('should still use flakes if bank contains fewer flakes than fish quantity', () => { + testRunCmd({ + cmd: fishCommand, + opts: { name: 'shrimps', flakes: true }, + user: { + bank: new Bank({ 'Spirit flakes': 100 }) + }, + result: `<:minion:778418736180494347> Your minion is now fishing 251x Shrimps, it'll take around 29 minutes, 58 seconds to finish. + +**Boosts:** More fish from using 100x Spirit flakes.` + }); + }); });