From 3a559384f671ab1041dcac4c0f6ca435b728b84e Mon Sep 17 00:00:00 2001 From: Arodab Date: Fri, 16 Aug 2024 01:39:59 -0300 Subject: [PATCH] removed files uploaded accidentally --- fish.test.ts | 94 ------ fish.ts | 398 ------------------------ fishing.ts | 368 ----------------------- fishingActivity.ts | 211 ------------- minionStatus.ts | 668 ----------------------------------------- minions.ts | 622 -------------------------------------- repeatStoredTrip.ts | 716 -------------------------------------------- types.ts | 362 ---------------------- 8 files changed, 3439 deletions(-) delete mode 100644 fish.test.ts delete mode 100644 fish.ts delete mode 100644 fishing.ts delete mode 100644 fishingActivity.ts delete mode 100644 minionStatus.ts delete mode 100644 minions.ts delete mode 100644 repeatStoredTrip.ts delete mode 100644 types.ts diff --git a/fish.test.ts b/fish.test.ts deleted file mode 100644 index 58984166d7..0000000000 --- a/fish.test.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { Bank } from 'oldschooljs'; -import { describe, it } from 'vitest'; - -import { Gear } from '../../../src/lib/structures/Gear'; -import { fishCommand } from '../../../src/mahoji/commands/fish'; -import { testRunCmd } from '../utils'; - -describe('Fish Command', () => { - it('should handle insufficient fishing level', () => { - testRunCmd({ - cmd: fishCommand, - opts: { name: 'Trout/Salmon', quantity: 1 }, - result: '<:minion:778418736180494347> Your minion needs 20 Fishing to fish Trout/Salmon.' - }); - }); - - it('should handle insufficient QP', () => { - testRunCmd({ - cmd: fishCommand, - opts: { name: 'karambwanji', quantity: 1 }, - user: { skills_fishing: 9_999_999, QP: 0 }, - result: 'You need 15 qp to catch those!' - }); - }); - - it('should handle invalid fish', () => { - testRunCmd({ - cmd: fishCommand, - opts: { name: 'asdf' }, - result: 'Thats not a valid fish to catch.' - }); - }); - - it('should handle insufficient barb fishing levels', () => { - testRunCmd({ - cmd: fishCommand, - opts: { name: 'Barbarian fishing' }, - user: { skills_fishing: 1 }, - result: '<:minion:778418736180494347> Your minion needs 48 Fishing to fish Barbarian fishing.' - }); - }); - - it('should fish', () => { - testRunCmd({ - cmd: fishCommand, - opts: { name: 'Shrimps/Anchovies' }, - result: "<:minion:778418736180494347> Your minion is now fishing Shrimps/Anchovies, it'll take around 30 minutes to finish" - }); - }); - - it('should catch insufficient feathers', () => { - testRunCmd({ - cmd: fishCommand, - opts: { name: 'Barbarian fishing' }, - user: { - skills_fishing: 999_999, - skills_agility: 999_999, - skills_strength: 999_999, - meleeGear: new Gear({ weapon: 'Pearl barbarian rod' }) - }, - result: 'You need Feather to fish Barbarian fishing!' - }); - }); - - it('should boost', () => { - testRunCmd({ - cmd: fishCommand, - opts: { name: 'Barbarian fishing' }, - user: { - skills_fishing: 999_999, - skills_agility: 999_999, - skills_strength: 999_999, - bank: new Bank().add('Feather', 1000) - }, - result: `<:minion:778418736180494347> Your minion is now fishing 100x Barbarian fishing, it'll take around 6 minutes, 1 second to finish. - -**Boosts:** 5% for Pearl barbarian rod.` - }); - }); - - it('should fish barrel boost', () => { - testRunCmd({ - cmd: fishCommand, - opts: { name: 'shrimps' }, - user: { - skills_fishing: 999_999, - meleeGear: new Gear({ cape: 'Fish sack barrel' }) - }, - result: `<:minion:778418736180494347> Your minion is now fishing Shrimps/Anchovies, it'll take around 39 minutes, 1 second to finish. - - **Boosts:** +9 trip minutes and +28 inventory slots for having a Fish sack barrel.` - }); - }); -}); diff --git a/fish.ts b/fish.ts deleted file mode 100644 index 552dfa698b..0000000000 --- a/fish.ts +++ /dev/null @@ -1,398 +0,0 @@ -import { stringMatches } from '@oldschoolgg/toolkit'; -import type { CommandRunOptions } from '@oldschoolgg/toolkit'; -import { ApplicationCommandOptionType } from 'discord.js'; -import { Time } from 'e'; -import { Bank } from 'oldschooljs'; -import TzTokJad from 'oldschooljs/dist/simulation/monsters/special/TzTokJad'; -import { WildernessDiary, userhasDiaryTier } from '../../lib/diaries'; - -import Fishing from '../../lib/skilling/skills/fishing'; -import { Fish, SkillsEnum } from '../../lib/skilling/types'; -import type { FishingActivityTaskOptions } from '../../lib/types/minions'; -//import { formatDuration, itemID, itemNameFromID } from '../../lib/util'; -import { formatDuration, itemNameFromID } from '../../lib/util'; -import addSubTaskToActivityTask from '../../lib/util/addSubTaskToActivityTask'; -import { calcMaxTripLength } from '../../lib/util/calcMaxTripLength'; -import type { OSBMahojiCommand } from '../lib/util'; -import { MUserClass } from '../../lib/MUser'; - - - -function radasBlessing(user: MUser) { - const blessingBoosts = [ - ["Rada's blessing 4", 8], - ["Rada's blessing 3", 6], - ["Rada's blessing 2", 4], - ["Rada's blessing 1", 2] - ]; - - for (const [itemName, boostPercent] of blessingBoosts) { - if (user.hasEquipped(itemName)) { - return { blessingEquipped: true, blessingChance: boostPercent as number }; - } - } - return { blessingEquipped: false, blessingChance: 0 }; -} - - - -function rollExtraLoot( - lootAmount: number, - flakesUsed: number, - currentInv: number, - blessingChance: number, - spirit_flakes: boolean, - flakesQuantity: number -): [number, number, number] { - currentInv++; - if (Math.random() < blessingChance / 100) { - lootAmount++; - currentInv++; - } - if (spirit_flakes && flakesUsed < flakesQuantity && Math.random() < 0.5) { - lootAmount++; - flakesUsed++; - currentInv++; - } - // Return updated values - return [lootAmount, flakesUsed, currentInv]; -} - - -function determineFishingTime( - quantity: number, - tripTicks: number, - powerfish: boolean, - spirit_flakes: boolean, - fish: Fish, - user: MUserClass, - invSlots: number, - blessingChance: number, - flakesQuantity: number, - harpoonBoost: number -) { - let ticksElapsed = 0; - let catches1 = 0, catches2 = 0, catches3 = 0; - let lootAmount1 = 0, lootAmount2 = 0, lootAmount3 = 0; - let flakesUsed = 0; - let currentInv = 0; - - let fishLvl = user.skillLevel(SkillsEnum.Fishing); - let effFishLvl = fishLvl; - if (fishLvl > 68) { - if (fish.name === 'Shark' || fish.name === 'Mackerel/Cod/Bass' || fish.name === 'Lobster') { - effFishLvl += 7; // fishing guild boost - } else if (fish.name === 'Tuna/Swordfish' && !powerfish) { - effFishLvl += 7; // can't 2t in the guild - } - } - - // probabilities of catching a fish at the user's fishing lvl - let p1 = harpoonBoost * (fish.chance1Lvl99! - (99 - effFishLvl) * (fish.chance1Lvl99! - fish.chance1Lvl1!) / (99 - 1)); - let p2 = fish.id2 === undefined ? 0 : harpoonBoost * (fish.chance2Lvl99! - (99 - effFishLvl) * (fish.chance2Lvl99! - fish.chance2Lvl1!) / (99 - 1)); - let p3 = fish.id3 === undefined ? 0 : harpoonBoost * (fish.chance3Lvl99! - (99 - effFishLvl) * (fish.chance3Lvl99! - fish.chance2Lvl1!) / (99 - 1)); - - let ticksPerRoll = fish.ticksPerRoll!; - let lostTicks = fish.lostTicks!; - let bankingTime = fish.bankingTime; - - if (fish.name === 'Barbarian fishing') { - if (powerfish) { - ticksPerRoll = 3; - lostTicks = 0.02; // more focused - } - if (user.allItemsOwned.has('Fishing cape') || user.allItemsOwned.has('Fishing cape (t)') || user.allItemsOwned.has('Max cape')) { - bankingTime = 20; - } - } else if (fish.name === 'Trout/Salmon') { - if (powerfish) { - ticksPerRoll = 3; - lostTicks = 0.03; - } - } else if (fish.name === 'Tuna/Swordfish') { - if (powerfish) { - ticksPerRoll = 2; - lostTicks = 0.01; - } - } - - if (powerfish) { - while (ticksElapsed < tripTicks) { - if (p3 != 0 && Math.random() < p3) { - catches3++; // roll for the highest lvl fish first - } else if (p2 != 0 && Math.random() < p2) { - catches2++; // then the second only if first one wasn't caught - } else if (Math.random() < p1) { - catches1++; - } - ticksElapsed += ticksPerRoll! * (1 + lostTicks!); // only part of the code that's not exactly how it works in osrs approximate - - if (catches1 + catches2 + catches3 >= quantity) { - break; - } - } - } else { - while (ticksElapsed < tripTicks) { - if (p3 != 0 && Math.random() < p3) { - catches3++; - lootAmount3++; - [lootAmount3, flakesUsed, currentInv] = rollExtraLoot(lootAmount3, flakesUsed, currentInv, blessingChance, spirit_flakes, flakesQuantity); - } else if (p2 != 0 && Math.random() < p2) { - catches2++; - lootAmount2++; - [lootAmount2, flakesUsed, currentInv] = rollExtraLoot(lootAmount2, flakesUsed, currentInv, blessingChance, spirit_flakes, flakesQuantity); - } else if (Math.random() < p1) { - catches1++; - lootAmount1++; - [lootAmount1, flakesUsed, currentInv] = rollExtraLoot(lootAmount1, flakesUsed, currentInv, blessingChance, spirit_flakes, flakesQuantity); - } - - ticksElapsed += ticksPerRoll! * (1 + lostTicks!); - - if (catches1 + catches2 + catches3 >= quantity) { - break; - } - - if (currentInv >= invSlots) { - ticksElapsed += bankingTime!; - currentInv = 0; - } - - } - } - - return { catches1, catches2, catches3, lootAmount1, lootAmount2, lootAmount3, ticksElapsed, flakesUsed }; -} - - - - -export const fishCommand: OSBMahojiCommand = { - name: 'fish', - description: 'Send your minion to fish fish.', - attributes: { - requiresMinion: true, - requiresMinionNotBusy: true, - examples: ['/fish name:Shrimp'] - }, - options: [ - { - type: ApplicationCommandOptionType.String, - name: 'name', - description: 'The thing you want to fish.', - required: true, - autocomplete: async (value: string) => { - return Fishing.Fishes.filter(i => - !value ? true : i.name.toLowerCase().includes(value.toLowerCase()) - ).map(i => ({ - name: i.name, - value: i.name - })); - } - }, - { - type: ApplicationCommandOptionType.Integer, - name: 'minutes', - description: 'Trip length in minutes (optional).', - required: false, - min_value: 1 - }, - { - type: ApplicationCommandOptionType.Boolean, - name: 'powerfish', - description: 'Set this to true to powerfish. Higher xp/hour, no loot (default false, optional).', - required: false - }, - { - type: ApplicationCommandOptionType.Boolean, - name: 'spirit_flakes', - description: 'Set this to true to use spirit flakes (default false, optional).', - required: false - } - ], - run: async ({ - options, - userID, - channelID - }: CommandRunOptions<{ - name: string; - quantity?: number, - powerfish?: boolean, - spirit_flakes?: boolean - }>) => { - const user = await mUserFetch(userID); - const fish = Fishing.Fishes.find( - fish => - stringMatches(fish.id, options.name) || - stringMatches(fish.name, options.name) || - fish.alias?.some(alias => stringMatches(alias, options.name)) - ); - if (!fish) return 'Thats not a valid fish to catch.'; - - let { quantity, powerfish, spirit_flakes } = options; - - quantity = quantity ?? 3000; - powerfish = powerfish ?? false; - if (powerfish) { - spirit_flakes = false; // don't use flakes if power fishing - } - spirit_flakes = spirit_flakes ?? false; - - // requirement checks - if (user.skillLevel(SkillsEnum.Fishing) < fish.level) { - return `${user.minionName} needs ${fish.level} Fishing to fish ${fish.name}.`; - } - - if (fish.qpRequired) { - if (user.QP < fish.qpRequired) { - return `You need ${fish.qpRequired} qp to catch those!`; - } - } - - if ( - fish.name === 'Barbarian fishing' && - (user.skillLevel(SkillsEnum.Agility) < 15 || user.skillLevel(SkillsEnum.Strength) < 15) - ) { - return 'You need at least 15 Agility and Strength to do Barbarian Fishing.'; - } - - if (fish.name === 'Infernal eel') { - const jadKC = await user.getKC(TzTokJad.id); - if (jadKC === 0) { - return 'You are not worthy JalYt. Before you can fish Infernal Eels, you need to have defeated the mighty TzTok-Jad!'; - } - } - - const anglerOutfit = Object.keys(Fishing.anglerItems).map(i => itemNameFromID(Number.parseInt(i))); - if (fish.name === 'Minnow' && anglerOutfit.some(test => !user.hasEquippedOrInBank(test!))) { - return 'You need to own the Angler Outfit to fish for Minnows.'; - } - - // boosts - const boosts = []; - if (fish.name === 'Tuna/Swordfish' || fish.name === 'Shark') { - if (user.hasEquipped('Crystal harpoon')) { - boosts.push('35% for Crystal harpoon'); - } else if (user.hasEquipped('Dragon harpoon')) { - boosts.push('20% for Dragon harpoon'); - } else if (user.hasEquipped('Infernal harpoon')) { - boosts.push('20% for Infernal harpoon'); - } - } - - if (powerfish) { - boosts.push('**Powerfishing**'); - } - - if (!powerfish) { - if (user.allItemsOwned.has('Fish sack barrel') || user.allItemsOwned.has('Fish barrel')) { - if (fish.name === 'Minnow' || fish.name === 'Karambwanji' || fish.name === 'Infernal eel') { - boosts.push(`+9 trip minutes for having a ${user.allItemsOwned.has('Fish sack barrel') ? 'Fish sack barrel' : 'Fish barrel'}`); - } else { - boosts.push(`+9 trip minutes and +28 inventory slots for having a ${user.allItemsOwned.has('Fish sack barrel') ? 'Fish sack barrel' : 'Fish barrel'}`); - } - } - } - - if (fish.name === 'Dark crab') { - const [hasWildyElite] = await userhasDiaryTier(user, WildernessDiary.elite); - if (hasWildyElite) { - fish.chance1Lvl1 = 0.0961; - fish.chance1Lvl99 = 0.3439; - boosts.push('Increased dark crab catch rate from having the Elite Wilderness Diary'); - } - } - - if (spirit_flakes) { - if (!user.bank.has('Spirit flakes')) { - return 'You need to have at least one spirit flake!'; - } - - boosts.push(`\n50% more fish from using spirit flakes`); - } - - const { blessingEquipped, blessingChance } = radasBlessing(user); - if (blessingEquipped) { - boosts.push(`\nYour Rada's Blessing gives ${blessingChance}% chance of extra fish`); - } - - - let harpoonBoost = 1.0; - if (fish.name === 'Tuna/Swordfish' || fish.name === 'Shark') { - if (user.hasEquipped("Dragon harpoon") || user.hasEquipped("Infernal harpoon")) { - harpoonBoost = 1.2; - } else if (user.hasEquipped("Crystal harpoon")) { - harpoonBoost = 1.35; - } - } - - let invSlots = 26; - if (user.allItemsOwned.has('Fish sack barrel') || user.allItemsOwned.has('Fish barrel')) { - invSlots += 28; - } - - let maxTripLength = calcMaxTripLength(user, 'Fishing'); - if (!powerfish && (user.allItemsOwned.has('Fish sack barrel') || user.allItemsOwned.has('Fish barrel'))) { - maxTripLength += Time.Minute * 9; - } - let tripTicks = maxTripLength / (Time.Second * 0.6); - - let flakesQuantity = user.bank.amount('Spirit flakes'); - - if (fish.bait) { - const baseCost = new Bank().add(fish.bait); - const maxCanDo = user.bank.fits(baseCost); - if (maxCanDo === 0) { - return `You need ${itemNameFromID(fish.bait)} to fish ${fish.name}!`; - } - - if (maxCanDo < quantity) { - quantity = maxCanDo; - } - } - - // determining fish time and quantities - const { catches1: Qty1, catches2: Qty2, catches3: Qty3, lootAmount1: loot1, lootAmount2: loot2, lootAmount3: loot3, ticksElapsed: tripLength, flakesUsed: flakesToRemove } = determineFishingTime( - quantity, - tripTicks, - powerfish, - spirit_flakes, - fish, - user, - invSlots, - blessingChance, - flakesQuantity, - harpoonBoost - ); - - - let duration = Time.Second * 0.6 * tripLength; - - await addSubTaskToActivityTask({ - fishID: fish.id, - userID: user.id, - channelID: channelID.toString(), - duration: duration, - quantity: quantity, - Qty1: Qty1, - Qty2: Qty2, - Qty3: Qty3, - loot1: loot1, - loot2: loot2, - loot3: loot3, - flakesToRemove: flakesToRemove, - powerfish: powerfish, - spirit_flakes: spirit_flakes, - type: 'Fishing' - }); - - let response = `${user.minionName} is now fishing ${fish.name}, it'll take around ${formatDuration(duration)} to finish.`; - - if (boosts.length > 0) { - response += `\n\n**Boosts:** ${boosts.join(', ')}.`; - } - - return response; - } -}; - diff --git a/fishing.ts b/fishing.ts deleted file mode 100644 index 28b0d1cfbd..0000000000 --- a/fishing.ts +++ /dev/null @@ -1,368 +0,0 @@ -import { Emoji } from '../../constants'; -import itemID from '../../util/itemID'; -import type { Fish } from '../types'; -import { SkillsEnum } from '../types'; - -const fishes: Fish[] = [ - { - name: 'Shrimps/Anchovies', - level: 1, - xp: 10, - id: itemID('Raw shrimps'), - chance1Lvl1: 0.1373, // catch chance for fish 1 at lvl 1 - chance1Lvl99: 1.0000, - - level2: 15, - xp2: 40, - id2: itemID('Raw anchovies'), - chance2Lvl1: 0.0937, - chance2Lvl99: 0.5039, - - petChance: 435_165, - clueScrollChance: 870_330, - lostTicks: 0.05, // percentage of ticks spent moving/dropping, - bankingTime: 30, - ticksPerRoll: 6 - }, - { - name: 'Sardine/Herring', - level: 5, - xp: 20, - id: itemID('Raw sardine'), - chance1Lvl1: 0.1267, - chance1Lvl99: 0.7539, - - level2: 10, - xp2: 30, - id2: itemID('Raw herring'), - chance2Lvl1: 0.1273, - chance2Lvl99: 0.5039, - - bait: itemID('Fishing bait'), - petChance: 528_000, - clueScrollChance: 1_056_000, - lostTicks: 0.05, - bankingTime: 30, - ticksPerRoll: 5 - }, - { - name: 'Karambwanji', - level: 5, - xp: 20, - id: itemID('Raw karambwanji'), - chance1Lvl1: 0.3945, - chance1Lvl99: 0.9805, - - petChance: 443_697, - qpRequired: 15, - clueScrollChance: 443_697, - lostTicks: 0.01, - bankingTime: 0, - ticksPerRoll: 6 - }, - { - name: 'Mackerel/Cod/Bass', - level: 16, - xp: 20, - id: itemID('Raw mackerel'), - chance1Lvl1: 0.0645, - chance1Lvl99: 0.2897, - - level2: 23, - xp2: 45, - id2: itemID('Raw cod'), - chance2Lvl1: 0.0173, - chance2Lvl99: 0.2188, - - level3: 46, - xp3: 100, - id3: itemID('Raw bass'), - bigFish: itemID('Big bass'), - bigFishRate: 1000, - chance3Lvl1: 0.0156, - chance3Lvl99: 0.1602, - - petChance: 382_609, - clueScrollChance: 1_147_827, - lostTicks: 0.05, - bankingTime: 25, - ticksPerRoll: 6 - }, - { - name: 'Trout/Salmon', - level: 20, - xp: 50, - id: itemID('Raw trout'), - chance1Lvl1: 0.0174, - chance1Lvl99: 0.7538, - - level2: 30, - xp2: 70, - id2: itemID('Raw salmon'), - chance2Lvl1: 0.0683, - chance2Lvl99: 0.3789, - - petChance: 461_808, - bait: itemID('Feather'), - clueScrollChance: 923_616, - lostTicks: 0.05, - bankingTime: 30, - ticksPerRoll: 5 - }, - { - name: 'Pike', - level: 25, - xp: 60, - id: itemID('Raw pike'), - chance1Lvl1: 0.0685, - chance1Lvl99: 0.3789, - - petChance: 305_792, - bait: itemID('Fishing bait'), - clueScrollChance: 305_792, - lostTicks: 0.05, - bankingTime: 30, - ticksPerRoll: 5 - }, - { - name: 'Tuna/Swordfish', - alias: ['sword, sf'], - level: 35, - xp: 80, - id: itemID('Raw tuna'), - chance1Lvl1: 0.0326, - chance1Lvl99: 0.2539, - - level2: 50, - xp2: 100, - id2: itemID('Raw swordfish'), - bigFish: itemID('Big swordfish'), - bigFishRate: 2500, - chance2Lvl1: 0.0196, - chance2Lvl99: 0.1914, - - petChance: 128_885, - clueScrollChance: 257_770, - lostTicks: 0.05, - bankingTime: 25, - ticksPerRoll: 6 - }, - { - name: 'Cave eel', - level: 38, - xp: 80, - id: itemID('Raw cave eel'), - chance1Lvl1: 0.1900, - chance1Lvl99: 0.3164, - lostTicks: 0.05, - bankingTime: 40, - ticksPerRoll: 5 - }, - { - name: 'Lobster', - alias: ['lobs'], - level: 40, - xp: 90, - id: itemID('Raw lobster'), - chance1Lvl1: 0.0247, - chance1Lvl99: 0.3750, - petChance: 116_129, - clueScrollChance: 116_129, - lostTicks: 0.05, - bankingTime: 25, - ticksPerRoll: 6 - }, - { - name: 'Monkfish', - alias: ['monk'], - level: 62, - xp: 120, - id: itemID('Raw monkfish'), - chance1Lvl1: 0.1900, - chance1Lvl99: 0.3555, - petChance: 138_583, - qpRequired: 100, - clueScrollChance: 138_583, - lostTicks: 0.10, - bankingTime: 20, - ticksPerRoll: 6 - }, - { - name: 'Karambwan', - alias: ['karam'], - level: 65, - xp: 50, - id: itemID('Raw karambwan'), - chance1Lvl1: 0.0210, - chance1Lvl99: 0.6289, - petChance: 170_874, - bait: itemID('Raw karambwanji'), - clueScrollChance: 170_874, - lostTicks: 0.00, // fishing spots never moves - bankingTime: 25, - ticksPerRoll: 4 - }, - { - name: 'Shark', - alias: ['shark'], - level: 76, - xp: 110, - id: itemID('Raw shark'), - chance1Lvl1: 0.0102, - chance1Lvl99: 0.1602, - petChance: 82_243, - bigFish: itemID('Big shark'), - bigFishRate: 5000, - clueScrollChance: 82_243, - lostTicks: 0.05, - bankingTime: 25, - ticksPerRoll: 6 - }, - { - name: 'Anglerfish', - alias: ['angler'], - level: 82, - xp: 120, - id: itemID('Raw anglerfish'), - chance1Lvl1: 0.0096, - chance1Lvl99: 0.1445, - petChance: 78_649, - bait: itemID('Sandworms'), - qpRequired: 40, - clueScrollChance: 78_649, - lostTicks: 0.05, - bankingTime: 30, - ticksPerRoll: 5 - }, - { - name: 'Minnow', - alias: ['minnows'], - level: 82, - xp: 26.1, - id: itemID('Minnow'), - chance1Lvl1: 0.6666, // no info on catch chance - chance1Lvl99: 0.9259, // handpicked to match wiki rates - petChance: 977_778, - qpRequired: 1, - clueScrollChance: 977_778, - lostTicks: 0.25, - bankingTime: 0, // stackable - ticksPerRoll: 2 - }, - { - name: 'Dark crab', - alias: ['crab', 'dark'], - level: 85, - xp: 130, - id: itemID('Raw dark crab'), - chance1Lvl1: 0.0230, - chance1Lvl99: 0.1602, - petChance: 149_434, - bait: itemID('Dark fishing bait'), - clueScrollChance: 149_434, - lostTicks: 0.05, - bankingTime: 0, - ticksPerRoll: 6 - }, - { - name: 'Barbarian fishing', - alias: ['barb', 'barbarian'], - level: 48, - xp: 50, - id: itemID('Leaping trout'), - chance1Lvl1: 32 / 255, - chance1Lvl99: 192 / 255, - - level2: 58, - xp2: 70, - id2: itemID('Leaping salmon'), - chance2Lvl1: 16 / 255, - chance2Lvl99: 96 / 255, - - level3: 70, - xp3: 80, - id3: itemID('Leaping sturgeon'), - chance3Lvl1: 8 / 255, - chance3Lvl99: 64 / 255, - - petChance: 426_954, - bait: itemID('Feather'), - clueScrollChance: 1_280_862, - lostTicks: 0.05, - bankingTime: 40, - ticksPerRoll: 5 - }, - { - name: 'Infernal eel', - level: 80, - xp: 95, - id: itemID('Infernal eel'), - petChance: 160_000, - bait: itemID('Fishing bait'), - clueScrollChance: 165_000, - chance1Lvl1: 0.1253, - chance1Lvl99: 0.3672, - lostTicks: 0.10, - bankingTime: 0, - ticksPerRoll: 5 - } -]; - -// Types of fish in camdozaal -const camdozaalFishes: Fish[] = [ - { - level: 7, - xp: 8, - id: itemID('Raw guppy'), - name: 'Raw guppy', - petChance: 257_770, - timePerFish: 5.5, - clueScrollChance: 257_770 - }, - { - level: 20, - xp: 16, - id: itemID('Raw cavefish'), - name: 'Raw cavefish', - petChance: 257_770, - timePerFish: 5.5, - clueScrollChance: 257_770 - }, - { - level: 33, - xp: 24, - id: itemID('Raw tetra'), - name: 'Raw tetra', - petChance: 257_770, - timePerFish: 5.5, - clueScrollChance: 257_770 - }, - { - level: 46, - xp: 33, - id: itemID('Raw catfish'), - name: 'Raw catfish', - petChance: 257_770, - timePerFish: 5.5, - clueScrollChance: 257_770 - } -]; - -const anglerItems: { [key: number]: number } = { - [itemID('Angler hat')]: 0.4, - [itemID('Angler top')]: 0.8, - [itemID('Angler waders ')]: 0.6, - [itemID('Angler boots')]: 0.2 -}; - -const Fishing = { - aliases: ['fishing'], - Fishes: fishes, - camdozaalFishes, - id: SkillsEnum.Fishing, - emoji: Emoji.Fishing, - anglerItems, - name: 'Fishing' -}; - -export default Fishing; diff --git a/fishingActivity.ts b/fishingActivity.ts deleted file mode 100644 index 37ee34fd82..0000000000 --- a/fishingActivity.ts +++ /dev/null @@ -1,211 +0,0 @@ -//import { calcPercentOfNum, percentChance, randInt } from 'e'; -import { calcPercentOfNum } from 'e'; -import { Bank } from 'oldschooljs'; -import { z } from 'zod'; -//import { Time } from 'e'; -import { Emoji, Events } from '../../lib/constants'; -import addSkillingClueToLoot from '../../lib/minions/functions/addSkillingClueToLoot'; -import Fishing from '../../lib/skilling/skills/fishing'; -import { SkillsEnum } from '../../lib/skilling/types'; -import type { FishingActivityTaskOptions } from '../../lib/types/minions'; -import { roll, skillingPetDropRate } from '../../lib/util'; -import { handleTripFinish } from '../../lib/util/handleTripFinish'; -// itemID from '../../lib/util/itemID'; -import { anglerBoostPercent } from '../../mahoji/mahojiSettings'; - -const allFishIDs = Fishing.Fishes.flatMap(fish => [fish.id, fish.id2, fish.id3]); - -export const fishingTask: MinionTask = { - type: 'Fishing', - dataSchema: z.object({ - type: z.literal('Fishing'), - fishID: z.number().refine(fishID => allFishIDs.includes(fishID), { - message: 'Invalid fish ID' - }), - quantity: z.number().min(1) - }), - async run(data: FishingActivityTaskOptions) { - let { fishID, userID, channelID, duration, spirit_flakes, - Qty1, Qty2 = 0, Qty3 = 0, loot1 = 0, loot2 = 0, loot3 = 0, flakesToRemove } = data; - - spirit_flakes = spirit_flakes ?? false; - - const user = await mUserFetch(userID); - const fishLvl = user.skillLevel(SkillsEnum.Fishing); - - const minnowQuantity: { [key: number]: number[] } = { - 99: [10, 14], - 95: [11, 13], - 90: [10, 13], - 85: [10, 11], - 1: [10, 10] - }; - - let baseMinnow = [10, 10]; - for (const [level, quantities] of Object.entries(minnowQuantity).reverse()) { - if (fishLvl >= Number.parseInt(level)) { - baseMinnow = quantities; - break; - } - } - - const baseKarambwanji = 1 + Math.floor(fishLvl / 5); - - let xpReceived = 0; - let agilityXpReceived = 0; - let strengthXpReceived = 0; - - const fish = Fishing.Fishes.find(fish => fish.id === fishID)!; - - // adding xp and loot - - xpReceived += fish.xp * Qty1; - if (Qty2 != 0) xpReceived += fish.xp2! * Qty2; - if (Qty3 != 0) xpReceived += fish.xp3! * Qty3; - - if (fish.name === 'Barbarian fishing') { - agilityXpReceived += 7 * Qty3 + 6 * Qty2 + 5 * Qty1; - strengthXpReceived += 7 * Qty3 + 6 * Qty2 + 5 * Qty1; - } - - - // If they have the entire angler outfit, give an extra 0.5% xp bonus - let bonusXP = 0; - if ( - user.gear.skilling.hasEquipped( - Object.keys(Fishing.anglerItems).map(i => Number.parseInt(i)), - true - ) - ) { - const amountToAdd = Math.floor(xpReceived * (2.5 / 100)); - xpReceived += amountToAdd; - bonusXP += amountToAdd; - } else { - // For each angler item, check if they have it, give its' XP boost if so. - for (const [itemID, bonus] of Object.entries(Fishing.anglerItems)) { - if (user.hasEquipped(Number.parseInt(itemID))) { - const amountToAdd = Math.floor(xpReceived * (bonus / 100)); - xpReceived += amountToAdd; - bonusXP += amountToAdd; - } - } - } - - - let xpRes = await user.addXP({ - skillName: SkillsEnum.Fishing, - amount: xpReceived, - duration - }); - xpRes += - agilityXpReceived > 0 - ? await user.addXP({ - skillName: SkillsEnum.Agility, - amount: agilityXpReceived, - duration - }) - : ''; - xpRes += - strengthXpReceived > 0 - ? await user.addXP({ - skillName: SkillsEnum.Strength, - amount: strengthXpReceived, - duration - }) - : ''; - - - const loot = new Bank(); - loot.add(fish.id3!, loot3); - loot.add(fish.id2!, loot2); - - // handling stackable fish - if (fish.name === 'Minnow') { - let sum = 0; - for (let i = 0; i < loot1; i++) { - sum += Math.floor(Math.random() * (baseMinnow[1] - baseMinnow[0] + 1)) + baseMinnow[0]; - } - loot1 = sum; - } else if (fish.name === 'Karambwanji') { - loot1 *= baseKarambwanji; - } - loot.add(fish!.id, loot1); - - let str = '' - - const totalCatches = Qty1 + Qty2 + Qty3; - str = `${user}, ${user.minionName} finished fishing ${totalCatches} ${fish.name}. ${xpRes}`; - - - const cost = new Bank(); - if (spirit_flakes) { - cost.add('Spirit flakes', flakesToRemove); - } - - if (fish.bait) { - cost.add(fish.bait, totalCatches); - } - - await user.removeItemsFromBank(cost); - - // Add clue scrolls - if (fish.clueScrollChance) { - addSkillingClueToLoot(user, SkillsEnum.Fishing, totalCatches, fish.clueScrollChance, loot); - } - - const xpBonusPercent = anglerBoostPercent(user); - if (xpBonusPercent > 0) { - bonusXP += Math.ceil(calcPercentOfNum(xpBonusPercent, xpReceived)); - } - - if (bonusXP > 0) { - str += `\n\n**Bonus XP:** ${bonusXP.toLocaleString()}`; - } - - // Roll for pet - if (fish.petChance) { - const { petDropRate } = skillingPetDropRate(user, SkillsEnum.Fishing, fish.petChance); - for (let i = 0; i < totalCatches; i++) { - if (roll(petDropRate)) { - loot.add('Heron'); - str += "\nYou have a funny feeling you're being followed..."; - globalClient.emit( - Events.ServerNotification, - `${Emoji.Fishing} **${user.badgedUsername}'s** minion, ${user.minionName}, just received a Heron while fishing ${fish.name} at level ${fishLvl} Fishing!` - ); - } - } - } - - // bigFishQuantity add this - if (fish.bigFishRate && fish.bigFish) { - let bigFishQuantity = 0; - if (fish.name === 'Shark') { - bigFishQuantity = Qty1; - } - if (fish.name === 'Tuna/Swordfish') { - bigFishQuantity = Qty2; - } - if (fish.name === 'Mackerel/Cod/Bass') { - bigFishQuantity = Qty3; - } - for (let i = 0; i < bigFishQuantity!; i++) { - if (roll(fish.bigFishRate)) { - loot.add(fish.bigFish); - } - } - } - - - await transactItems({ - userID: user.id, - collectionLog: true, - itemsToAdd: loot - }); - - str += `\n\nYou received: ${loot}.`; - - handleTripFinish(user, channelID, str, undefined, data, loot); - } -} - diff --git a/minionStatus.ts b/minionStatus.ts deleted file mode 100644 index 0782428c44..0000000000 --- a/minionStatus.ts +++ /dev/null @@ -1,668 +0,0 @@ -import { toTitleCase } from '@oldschoolgg/toolkit'; -import { increaseNumByPercent, reduceNumByPercent } from 'e'; -import { SkillsEnum } from 'oldschooljs/dist/constants'; - -import { collectables } from '../../mahoji/lib/abstracted_commands/collectCommand'; -import { shades, shadesLogs } from '../../mahoji/lib/abstracted_commands/shadesOfMortonCommand'; -import { ClueTiers } from '../clues/clueTiers'; -import { Emoji } from '../constants'; -import killableMonsters from '../minions/data/killableMonsters'; -import { Planks } from '../minions/data/planks'; -import { quests } from '../minions/data/quests'; -import Agility from '../skilling/skills/agility'; -import Constructables from '../skilling/skills/construction/constructables'; -import Cooking from '../skilling/skills/cooking/cooking'; -import LeapingFish from '../skilling/skills/cooking/leapingFish'; -import Crafting from '../skilling/skills/crafting'; -import Farming from '../skilling/skills/farming'; -import Firemaking from '../skilling/skills/firemaking'; -import Fishing from '../skilling/skills/fishing'; -import Herblore from '../skilling/skills/herblore/herblore'; -import Hunter from '../skilling/skills/hunter/hunter'; -import { Castables } from '../skilling/skills/magic/castables'; -import { Enchantables } from '../skilling/skills/magic/enchantables'; -import Mining from '../skilling/skills/mining'; -import Prayer from '../skilling/skills/prayer'; -import Runecraft from '../skilling/skills/runecraft'; -import Smithing from '../skilling/skills/smithing'; -import { stealables } from '../skilling/skills/thieving/stealables'; -import Woodcutting from '../skilling/skills/woodcutting/woodcutting'; -import type { - ActivityTaskOptionsWithQuantity, - AgilityActivityTaskOptions, - AlchingActivityTaskOptions, - BuryingActivityTaskOptions, - ButlerActivityTaskOptions, - CastingActivityTaskOptions, - ClueActivityTaskOptions, - CollectingOptions, - ColoTaskOptions, - ConstructionActivityTaskOptions, - CookingActivityTaskOptions, - CraftingActivityTaskOptions, - CutLeapingFishActivityTaskOptions, - DarkAltarOptions, - EnchantingActivityTaskOptions, - FarmingActivityTaskOptions, - FightCavesActivityTaskOptions, - FiremakingActivityTaskOptions, - FishingActivityTaskOptions, - FletchingActivityTaskOptions, - GauntletOptions, - GroupMonsterActivityTaskOptions, - HerbloreActivityTaskOptions, - HunterActivityTaskOptions, - InfernoOptions, - KourendFavourActivityTaskOptions, - MinigameActivityTaskOptionsWithNoChanges, - MiningActivityTaskOptions, - MonsterActivityTaskOptions, - MotherlodeMiningActivityTaskOptions, - NexTaskOptions, - NightmareActivityTaskOptions, - OfferingActivityTaskOptions, - PickpocketActivityTaskOptions, - PlunderActivityTaskOptions, - RaidsOptions, - RunecraftActivityTaskOptions, - SawmillActivityTaskOptions, - ScatteringActivityTaskOptions, - SepulchreActivityTaskOptions, - ShadesOfMortonOptions, - SmeltingActivityTaskOptions, - SmithingActivityTaskOptions, - SpecificQuestOptions, - TOAOptions, - TheatreOfBloodTaskOptions, - TiaraRunecraftActivityTaskOptions, - WoodcuttingActivityTaskOptions, - ZalcanoActivityTaskOptions -} from '../types/minions'; -import { formatDuration, itemNameFromID, randomVariation, stringMatches } from '../util'; -import { getActivityOfUser } from './minionIsBusy'; - -export function minionStatus(user: MUser) { - const currentTask = getActivityOfUser(user.id); - const name = user.minionName; - if (!currentTask) { - return `${name} is currently doing nothing.`; - } - - const durationRemaining = currentTask.finishDate - Date.now(); - const formattedDuration = `${formatDuration(durationRemaining)} remaining.`; - - switch (currentTask.type) { - case 'MonsterKilling': { - const data = currentTask as MonsterActivityTaskOptions; - const monster = killableMonsters.find(mon => mon.id === data.monsterID); - - return `${name} is currently killing ${data.quantity}x ${monster?.name}. ${formattedDuration}`; - } - - case 'GroupMonsterKilling': { - const data = currentTask as GroupMonsterActivityTaskOptions; - const monster = killableMonsters.find(mon => mon.id === data.monsterID); - - return `${name} is currently killing ${data.quantity}x ${monster?.name} with a party of ${data.users.length - }. ${formattedDuration}`; - } - - case 'ClueCompletion': { - const data = currentTask as ClueActivityTaskOptions; - - const clueTier = ClueTiers.find(tier => tier.id === data.clueID); - - return `${name} is currently completing ${data.quantity}x ${clueTier?.name} clues. ${formattedDuration}`; - } - - case 'Crafting': { - const data = currentTask as CraftingActivityTaskOptions; - const craftable = Crafting.Craftables.find(item => item.id === data.craftableID); - - return `${name} is currently crafting ${data.quantity}x ${craftable?.name}. ${formattedDuration} Your ${Emoji.Crafting - } Crafting level is ${user.skillLevel(SkillsEnum.Crafting)}`; - } - - case 'Agility': { - const data = currentTask as AgilityActivityTaskOptions; - - const course = Agility.Courses.find(course => course.name === data.courseID); - - return `${name} is currently running ${data.quantity}x ${course?.name} laps. ${formattedDuration} Your ${Emoji.Agility - } Agility level is ${user.skillLevel(SkillsEnum.Agility)}`; - } - - case 'Cooking': { - const data = currentTask as CookingActivityTaskOptions; - - const cookable = Cooking.Cookables.find(cookable => cookable.id === data.cookableID); - - return `${name} is currently cooking ${data.quantity}x ${cookable?.name}. ${formattedDuration} Your ${Emoji.Cooking - } Cooking level is ${user.skillLevel(SkillsEnum.Cooking)}`; - } - - case 'Fishing': { - const data = currentTask as FishingActivityTaskOptions; - - const fish = Fishing.Fishes.find(fish => fish.id === data.fishID); - - return `${name} is currently fishing ${fish?.name}. ${formattedDuration} Your ${Emoji.Fishing - } Fishing level is ${user.skillLevel(SkillsEnum.Fishing)}`; - } - - case 'Mining': { - const data = currentTask as MiningActivityTaskOptions; - - const ore = Mining.Ores.find(ore => ore.id === data.oreID); - - return `${name} is currently mining ${ore?.name}. ${data.fakeDurationMax === data.fakeDurationMin - ? formattedDuration - : `approximately ${formatDuration( - randomVariation(reduceNumByPercent(durationRemaining, 25), 20) - )} **to** ${formatDuration( - randomVariation(increaseNumByPercent(durationRemaining, 25), 20) - )} remaining.` - } Your ${Emoji.Mining} Mining level is ${user.skillLevel(SkillsEnum.Mining)}`; - } - - case 'MotherlodeMining': { - const data = currentTask as MotherlodeMiningActivityTaskOptions; - - return `${name} is currently mining at the Motherlode Mine. ${data.fakeDurationMax === data.fakeDurationMin - ? formattedDuration - : `approximately ${formatDuration( - randomVariation(reduceNumByPercent(durationRemaining, 25), 20) - )} **to** ${formatDuration( - randomVariation(increaseNumByPercent(durationRemaining, 25), 20) - )} remaining.` - } Your ${Emoji.Mining} Mining level is ${user.skillLevel(SkillsEnum.Mining)}`; - } - - case 'Smelting': { - const data = currentTask as SmeltingActivityTaskOptions; - - const bar = Smithing.Bars.find(bar => bar.id === data.barID); - - return `${name} is currently smelting ${data.quantity}x ${bar?.name}. ${formattedDuration} Your ${Emoji.Smithing - } Smithing level is ${user.skillLevel(SkillsEnum.Smithing)}`; - } - - case 'Smithing': { - const data = currentTask as SmithingActivityTaskOptions; - - const SmithableItem = Smithing.SmithableItems.find(item => item.id === data.smithedBarID); - - return `${name} is currently smithing ${data.quantity}x ${SmithableItem?.name}. ${formattedDuration} Your ${Emoji.Smithing - } Smithing level is ${user.skillLevel(SkillsEnum.Smithing)}`; - } - - case 'Offering': { - const data = currentTask as OfferingActivityTaskOptions; - - const bones = Prayer.Bones.find(bones => bones.inputId === data.boneID); - - return `${name} is currently offering ${data.quantity}x ${bones?.name}. ${formattedDuration} Your ${Emoji.Prayer - } Prayer level is ${user.skillLevel(SkillsEnum.Prayer)}`; - } - - case 'Burying': { - const data = currentTask as BuryingActivityTaskOptions; - - const bones = Prayer.Bones.find(bones => bones.inputId === data.boneID); - - return `${name} is currently burying ${data.quantity}x ${bones?.name}. ${formattedDuration} Your ${Emoji.Prayer - } Prayer level is ${user.skillLevel(SkillsEnum.Prayer)}`; - } - - case 'Scattering': { - const data = currentTask as ScatteringActivityTaskOptions; - - const ashes = Prayer.Ashes.find(ashes => ashes.inputId === data.ashID); - - return `${name} is currently scattering ${data.quantity}x ${ashes?.name}. ${formattedDuration} Your ${Emoji.Prayer - } Prayer level is ${user.skillLevel(SkillsEnum.Prayer)}`; - } - - case 'Firemaking': { - const data = currentTask as FiremakingActivityTaskOptions; - - const burn = Firemaking.Burnables.find(burn => burn.inputLogs === data.burnableID); - - return `${name} is currently lighting ${data.quantity}x ${burn?.name}. ${formattedDuration} Your ${Emoji.Firemaking - } Firemaking level is ${user.skillLevel(SkillsEnum.Firemaking)}`; - } - - case 'Questing': { - return `${name} is currently Questing. ${formattedDuration} Your current Quest Point count is: ${user.QP}.`; - } - - case 'Woodcutting': { - const data = currentTask as WoodcuttingActivityTaskOptions; - - const log = Woodcutting.Logs.find(log => log.id === data.logID); - - return `${name} is currently chopping ${log?.name}. ${data.fakeDurationMax === data.fakeDurationMin - ? formattedDuration - : `approximately ${formatDuration( - randomVariation(reduceNumByPercent(durationRemaining, 25), 20) - )} **to** ${formatDuration( - randomVariation(increaseNumByPercent(durationRemaining, 25), 20) - )} remaining.` - } Your ${Emoji.Woodcutting} Woodcutting level is ${user.skillLevel(SkillsEnum.Woodcutting)}`; - } - case 'Runecraft': { - const data = currentTask as RunecraftActivityTaskOptions; - - const rune = Runecraft.Runes.find(_rune => _rune.id === data.runeID); - - return `${name} is currently turning ${data.essenceQuantity}x Essence into ${rune?.name - }. ${formattedDuration} Your ${Emoji.Runecraft} Runecraft level is ${user.skillLevel( - SkillsEnum.Runecraft - )}`; - } - - case 'TiaraRunecraft': { - const data = currentTask as TiaraRunecraftActivityTaskOptions; - const tiara = Runecraft.Tiaras.find(_tiara => _tiara.id === data.tiaraID); - - return `${name} is currently crafting ${data.tiaraQuantity} ${tiara?.name}. ${formattedDuration} Your ${Emoji.Runecraft - } Runecraft level is ${user.skillLevel(SkillsEnum.Runecraft)}`; - } - - case 'FightCaves': { - const data = currentTask as FightCavesActivityTaskOptions; - const durationRemaining = data.finishDate - data.duration + data.fakeDuration - Date.now(); - return `${name} is currently attempting the ${Emoji.AnimatedFireCape} **Fight caves** ${Emoji.TzRekJad - }. If they're successful and don't die, the trip should take ${formatDuration(durationRemaining)}.`; - } - case 'TitheFarm': { - return `${name} is currently farming at the **Tithe Farm**. ${formattedDuration}`; - } - - case 'Fletching': { - const data = currentTask as FletchingActivityTaskOptions; - - return `${name} is currently fletching ${data.quantity}x ${data.fletchableName - }. ${formattedDuration} Your ${Emoji.Fletching} Fletching level is ${user.skillLevel( - SkillsEnum.Fletching - )}`; - } - case 'Herblore': { - const data = currentTask as HerbloreActivityTaskOptions; - const mixable = Herblore.Mixables.find(i => i.item.id === data.mixableID); - - return `${name} is currently mixing ${data.quantity}x ${mixable?.item.name}. ${formattedDuration} Your ${Emoji.Herblore - } Herblore level is ${user.skillLevel(SkillsEnum.Herblore)}`; - } - case 'CutLeapingFish': { - const data = currentTask as CutLeapingFishActivityTaskOptions; - const barbarianFish = LeapingFish.find(item => item.item.id === data.id); - - return `${name} is currently cutting ${data.quantity}x ${barbarianFish?.item.name - }. ${formattedDuration} Your ${Emoji.Cooking} Cooking level is ${user.skillLevel(SkillsEnum.Cooking)}`; - } - case 'Wintertodt': { - const data = currentTask as ActivityTaskOptionsWithQuantity; - return `${name} is currently fighting Wintertodt ${data.quantity}x times. ${formattedDuration}`; - } - case 'Tempoross': { - return `${name} is currently fighting Tempoross. ${formattedDuration}`; - } - - case 'Alching': { - const data = currentTask as AlchingActivityTaskOptions; - - return `${name} is currently alching ${data.quantity}x ${itemNameFromID( - data.itemID - )}. ${formattedDuration}`; - } - - case 'Farming': { - const data = currentTask as FarmingActivityTaskOptions; - - const plants = Farming.Plants.find(plants => plants.name === data.plantsName); - - return `${name} is currently farming ${data.quantity}x ${plants?.name}. ${formattedDuration} Your ${Emoji.Farming - } Farming level is ${user.skillLevel(SkillsEnum.Farming)}.`; - } - - case 'Sawmill': { - const data = currentTask as SawmillActivityTaskOptions; - const plank = Planks.find(_plank => _plank.outputItem === data.plankID)!; - return `${name} is currently creating ${data.plankQuantity}x ${itemNameFromID( - plank.outputItem - )}s. ${formattedDuration}`; - } - - case 'Nightmare': { - const data = currentTask as NightmareActivityTaskOptions; - return `${name} is currently killing The Nightmare ${data.method === 'solo' ? 'solo' : 'in a team' - }. ${formattedDuration}`; - } - - case 'AnimatedArmour': { - return `${name} is currently fighting animated armour in the Warriors' Guild. ${formattedDuration}`; - } - - case 'Cyclops': { - return `${name} is currently fighting cyclopes in the Warriors' Guild. ${formattedDuration}`; - } - - case 'CamdozaalFishing': { - return `${name} is currently Fishing in the Ruins of Camdozaal. ${formattedDuration}`; - } - - case 'CamdozaalMining': { - return `${name} is currently Mining in the Ruins of Camdozaal. ${formattedDuration}`; - } - - case 'CamdozaalSmithing': { - return `${name} is currently Smithing in the Ruins of Camdozaal. ${formattedDuration}`; - } - - case 'Sepulchre': { - const data = currentTask as SepulchreActivityTaskOptions; - - return `${name} is currently doing ${data.quantity}x laps of the Hallowed Sepulchre. ${formattedDuration}`; - } - - case 'Plunder': { - const data = currentTask as PlunderActivityTaskOptions; - - return `${name} is currently doing Pyramid Plunder x ${data.quantity}x times. ${formattedDuration}`; - } - - case 'FishingTrawler': { - const data = currentTask as ActivityTaskOptionsWithQuantity; - return `${name} is currently aboard the Fishing Trawler, doing ${data.quantity}x trips. ${formattedDuration}`; - } - - case 'Zalcano': { - const data = currentTask as ZalcanoActivityTaskOptions; - return `${name} is currently killing Zalcano ${data.quantity}x times. ${formattedDuration}`; - } - - case 'Pickpocket': { - const data = currentTask as PickpocketActivityTaskOptions; - const obj = stealables.find(_obj => _obj.id === data.monsterID); - return `${name} is currently ${obj?.type === 'pickpockable' ? 'pickpocketing' : 'stealing'} from ${obj?.name - } ${data.quantity}x times. ${formattedDuration}`; - } - - case 'BarbarianAssault': { - const data = currentTask as MinigameActivityTaskOptionsWithNoChanges; - return `${name} is currently doing ${data.quantity} waves of Barbarian Assault. ${formattedDuration}`; - } - - case 'AgilityArena': { - return `${name} is currently doing the Brimhaven Agility Arena. ${formattedDuration}`; - } - - case 'ChampionsChallenge': { - return `${name} is currently doing the **Champion's Challenge**. ${formattedDuration}`; - } - - case 'Hunter': { - const data = currentTask as HunterActivityTaskOptions; - - const creature = Hunter.Creatures.find(creature => - creature.aliases.some( - alias => - stringMatches(alias, data.creatureName) || stringMatches(alias.split(' ')[0], data.creatureName) - ) - ); - const crystalImpling = creature?.name === 'Crystal impling'; - return `${name} is currently hunting ${crystalImpling ? creature?.name : `${data.quantity}x ${creature?.name}` - }. ${formattedDuration}`; - } - - case 'Birdhouse': { - return `${name} is currently doing a bird house run. ${formattedDuration}`; - } - - case 'AerialFishing': { - return `${name} is currently aerial fishing. ${formattedDuration}`; - } - - case 'DriftNet': { - return `${name} is currently drift net fishing. ${formattedDuration}`; - } - - case 'Construction': { - const data = currentTask as ConstructionActivityTaskOptions; - const pohObject = Constructables.find(i => i.id === data.objectID); - if (!pohObject) throw new Error(`No POH object found with ID ${data.objectID}.`); - return `${name} is currently building ${data.quantity}x ${pohObject.name}. ${formattedDuration}`; - } - - case 'Butler': { - const data = currentTask as ButlerActivityTaskOptions; - const plank = Planks.find(_plank => _plank.outputItem === data.plankID)!; - return `${name} is currently creating ${data.plankQuantity}x ${itemNameFromID( - plank.outputItem - )}s. ${formattedDuration}`; - } - - case 'MahoganyHomes': { - return `${name} is currently doing Mahogany Homes. ${formattedDuration}`; - } - - case 'Enchanting': { - const data = currentTask as EnchantingActivityTaskOptions; - const enchantable = Enchantables.find(i => i.id === data.itemID); - return `${name} is currently enchanting ${data.quantity}x ${enchantable?.name}. ${formattedDuration}`; - } - - case 'Casting': { - const data = currentTask as CastingActivityTaskOptions; - const spell = Castables.find(i => i.id === data.spellID); - return `${name} is currently casting ${data.quantity}x ${spell?.name}. ${formattedDuration}`; - } - - case 'GloryCharging': { - const data = currentTask as ActivityTaskOptionsWithQuantity; - return `${name} is currently charging ${data.quantity}x inventories of glories at the Fountain of Rune. ${formattedDuration}`; - } - - case 'WealthCharging': { - const data = currentTask as ActivityTaskOptionsWithQuantity; - return `${name} is currently charging ${data.quantity}x inventories of rings of wealth at the Fountain of Rune. ${formattedDuration}`; - } - - case 'GnomeRestaurant': { - return `${name} is currently doing Gnome Restaurant deliveries. ${formattedDuration}`; - } - - case 'SoulWars': { - const data = currentTask as MinigameActivityTaskOptionsWithNoChanges; - return `${name} is currently doing ${data.quantity}x games of Soul Wars. ${formattedDuration}`; - } - - case 'RoguesDenMaze': { - return `${name} is currently attempting the Rogues' Den maze. ${formattedDuration}`; - } - - case 'Gauntlet': { - const data = currentTask as GauntletOptions; - return `${name} is currently doing ${data.quantity}x ${data.corrupted ? 'Corrupted' : 'Normal' - } Gauntlet. ${formattedDuration}`; - } - - case 'CastleWars': { - const data = currentTask as MinigameActivityTaskOptionsWithNoChanges; - return `${name} is currently doing ${data.quantity}x Castle Wars games. ${formattedDuration}`; - } - - case 'MageArena': { - return `${name} is currently doing the Mage Arena. ${formattedDuration}`; - } - - case 'Raids': { - const data = currentTask as RaidsOptions; - return `${name} is currently doing the Chambers of Xeric${data.challengeMode ? ' in Challenge Mode' : '' - }, ${data.users.length === 1 ? 'as a solo.' : `with a team of ${data.users.length} minions.` - } ${formattedDuration}`; - } - - case 'Collecting': { - const data = currentTask as CollectingOptions; - const collectable = collectables.find(c => c.item.id === data.collectableID)!; - return `${name} is currently collecting ${data.quantity * collectable.quantity}x ${collectable.item.name - }. ${formattedDuration}`; - } - - case 'MageTrainingArena': { - return `${name} is currently training at the Mage Training Arena. ${formattedDuration}`; - } - - case 'MageArena2': { - return `${name} is currently attempting the Mage Arena II. ${formattedDuration}`; - } - - case 'BigChompyBirdHunting': { - return `${name} is currently hunting Chompy Birds! ${formattedDuration}`; - } - - case 'DarkAltar': { - const data = currentTask as DarkAltarOptions; - return `${name} is currently runecrafting ${toTitleCase( - data.rune - )} runes at the Dark Altar. ${formattedDuration}`; - } - case 'Trekking': { - return `${name} is currently Temple Trekking. ${formattedDuration}`; - } - case 'PestControl': { - const data = currentTask as MinigameActivityTaskOptionsWithNoChanges; - return `${name} is currently doing ${data.quantity} games of Pest Control. ${formattedDuration}`; - } - case 'VolcanicMine': { - const data = currentTask as ActivityTaskOptionsWithQuantity; - return `${name} is currently doing ${data.quantity} games of Volcanic Mine. ${formattedDuration}`; - } - case 'TearsOfGuthix': { - return `${name} is currently doing Tears Of Guthix. ${formattedDuration}`; - } - case 'KourendFavour': { - const data = currentTask as KourendFavourActivityTaskOptions; - return `${name} is currently doing ${data.favour} Favour tasks. ${formattedDuration}`; - } - case 'Inferno': { - const data = currentTask as InfernoOptions; - const durationRemaining = data.finishDate - data.duration + data.fakeDuration - Date.now(); - return `${name} is currently attempting the Inferno, if they're successful and don't die, the trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'TheatreOfBlood': { - const data = currentTask as TheatreOfBloodTaskOptions; - const durationRemaining = data.finishDate - data.duration + data.fakeDuration - Date.now(); - - return `${name} is currently attempting the Theatre of Blood, if your team is successful and doesn't die, the trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'LastManStanding': { - const data = currentTask as MinigameActivityTaskOptionsWithNoChanges; - - return `${name} is currently doing ${data.quantity - } Last Man Standing matches, the trip should take ${formatDuration(durationRemaining)}.`; - } - case 'BirthdayEvent': { - return `${name} is currently doing the Birthday Event! The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'TokkulShop': { - return `${name} is currently shopping at Tzhaar stores. The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'Nex': { - const data = currentTask as NexTaskOptions; - const durationRemaining = data.finishDate - data.duration + data.fakeDuration - Date.now(); - return `${name} is currently killing Nex ${data.quantity} times with a team of ${data.users.length - }. The trip should take ${formatDuration(durationRemaining)}.`; - } - case 'TroubleBrewing': { - const data = currentTask as MinigameActivityTaskOptionsWithNoChanges; - return `${name} is currently doing ${data.quantity - }x games of Trouble Brewing. The trip should take ${formatDuration(durationRemaining)}.`; - } - case 'PuroPuro': { - return `${name} is currently hunting in Puro-Puro. The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'ShootingStars': { - return `${name} is currently mining a Crashed Star. The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'GiantsFoundry': { - const data = currentTask as MinigameActivityTaskOptionsWithNoChanges; - return `${name} is currently creating ${data.quantity - }x giant weapons for Kovac in the Giants' Foundry minigame. The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'GuardiansOfTheRift': { - return `${name} is currently helping the Great Guardian to close the rift. The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'NightmareZone': { - return `${name} is currently killing Monsters in the Nightmare Zone. The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'ShadesOfMorton': { - const data = currentTask as ShadesOfMortonOptions; - const log = shadesLogs.find(i => i.normalLog.id === data.logID)!; - const shade = shades.find(i => i.shadeName === data.shadeID)!; - return `${name} is currently doing ${data.quantity} trips of Shades of Mort'ton, cremating ${shade.shadeName - } remains with ${log.oiledLog.name}! The trip should take ${formatDuration(durationRemaining)}.`; - } - case 'TombsOfAmascut': { - const data = currentTask as TOAOptions; - const durationRemaining = data.finishDate - data.duration + data.fakeDuration - Date.now(); - - return `${name} is currently attempting the Tombs of Amascut, if your team is successful and doesn't die, the trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'UnderwaterAgilityThieving': { - return `${name} is currently doing Underwater Agility and Thieving. ${formattedDuration}`; - } - case 'StrongholdOfSecurity': { - return `${name} is currently doing the Stronghold of Security! The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'CombatRing': { - return `${name} is currently fighting in the Combat Ring! The trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'SpecificQuest': { - const data = currentTask as SpecificQuestOptions; - return `${name} is currently doing the ${quests.find(i => i.id === data.questID)?.name - }! The trip should take ${formatDuration(durationRemaining)}.`; - } - case 'Colosseum': { - const data = currentTask as ColoTaskOptions; - const durationRemaining = data.finishDate - data.duration + data.fakeDuration - Date.now(); - - return `${name} is currently attempting the Colosseum, if they are successful, the trip should take ${formatDuration( - durationRemaining - )}.`; - } - case 'HalloweenEvent': { - return `${name} is doing the Halloween event! The trip should take ${formatDuration(durationRemaining)}.`; - } - case 'Easter': - case 'BlastFurnace': { - throw new Error('Removed'); - } - } -} diff --git a/minions.ts b/minions.ts deleted file mode 100644 index edeb891466..0000000000 --- a/minions.ts +++ /dev/null @@ -1,622 +0,0 @@ -import type { CropUpgradeType } from '@prisma/client'; - -import type { ItemBank } from '.'; -import type { NMZStrategy, TwitcherGloves, UnderwaterAgilityThievingTrainingSkill } from '../constants'; -import type { IPatchData } from '../minions/farming/types'; -import type { MinigameName } from '../settings/minigames'; -import type { RaidLevel } from '../simulation/toa'; -import type { Peak } from '../tickers'; -import type { BirdhouseData } from './../skilling/skills/hunter/defaultBirdHouseTrap'; - -export interface ActivityTaskOptions { - userID: string; - duration: number; - id: number; - finishDate: number; - channelID: string; -} - -export interface ActivityTaskOptionsWithNoChanges extends ActivityTaskOptions { - type: - | 'Questing' - | 'Wintertodt' - | 'Cyclops' - | 'GloryCharging' - | 'WealthCharging' - | 'BarbarianAssault' - | 'AgilityArena' - | 'ChampionsChallenge' - | 'AerialFishing' - | 'DriftNet' - | 'SoulWars' - | 'RoguesDenMaze' - | 'CastleWars' - | 'MageArena' - | 'MageTrainingArena' - | 'BlastFurnace' - | 'MageArena2' - | 'BigChompyBirdHunting' - | 'PestControl' - | 'VolcanicMine' - | 'TearsOfGuthix' - | 'LastManStanding' - | 'BirthdayEvent' - | 'TroubleBrewing' - | 'Easter' - | 'ShootingStars' - | 'HalloweenEvent' - | 'StrongholdOfSecurity' - | 'CombatRing'; -} - -export interface ActivityTaskOptionsWithQuantity extends ActivityTaskOptions { - type: - | 'VolcanicMine' - | 'Cyclops' - | 'ShootingStars' - | 'DriftNet' - | 'WealthCharging' - | 'GloryCharging' - | 'AerialFishing' - | 'FishingTrawler' - | 'CamdozaalFishing' - | 'CamdozaalMining' - | 'CamdozaalSmithing'; - quantity: number; - // iQty is 'input quantity.' This is the number specified at command time, so we can accurately repeat such trips. - iQty?: number; -} - -export interface ShootingStarsOptions extends ActivityTaskOptions { - type: 'ShootingStars'; - size: number; - usersWith: number; - totalXp: number; - lootItems: ItemBank; -} -interface ActivityTaskOptionsWithUsers extends ActivityTaskOptions { - users: string[]; -} - -export interface RunecraftActivityTaskOptions extends ActivityTaskOptions { - type: 'Runecraft'; - runeID: number; - essenceQuantity: number; - imbueCasts: number; - useStaminas?: boolean; - daeyaltEssence?: boolean; -} - -export interface TiaraRunecraftActivityTaskOptions extends ActivityTaskOptions { - type: 'TiaraRunecraft'; - tiaraID: number; - tiaraQuantity: number; -} - -export interface DarkAltarOptions extends ActivityTaskOptions { - type: 'DarkAltar'; - quantity: number; - hasElite: boolean; - rune: 'blood' | 'soul'; -} - -export interface AgilityActivityTaskOptions extends ActivityTaskOptions { - type: 'Agility'; - courseID: string; - quantity: number; - alch: { - itemID: number; - quantity: number; - } | null; -} - -export interface CookingActivityTaskOptions extends ActivityTaskOptions { - type: 'Cooking'; - cookableID: number; - quantity: number; -} - -export interface ConstructionActivityTaskOptions extends ActivityTaskOptions { - type: 'Construction'; - objectID: number; - quantity: number; -} - -export interface MonsterActivityTaskOptions extends ActivityTaskOptions { - type: 'MonsterKilling'; - monsterID: number; - quantity: number; - iQty?: number; - usingCannon?: boolean; - cannonMulti?: boolean; - chinning?: boolean; - burstOrBarrage?: number; - died?: boolean; - pkEncounters?: number; - hasWildySupplies?: boolean; - isInWilderness?: boolean; -} - -export interface ClueActivityTaskOptions extends ActivityTaskOptions { - type: 'ClueCompletion'; - - clueID: number; - quantity: number; - implingID?: number; - implingClues?: number; -} - -export interface FishingActivityTaskOptions extends ActivityTaskOptions { - type: 'Fishing'; - fishID: number; - quantity?: number; - Qty1: number; - Qty2?: number; - Qty3?: number; - loot1?: number; - loot2?: number; - loot3?: number; - flakesToRemove?: number; - powerfish?: boolean; - spirit_flakes?: boolean; -} - - -export interface MiningActivityTaskOptions extends ActivityTaskOptions { - type: 'Mining'; - fakeDurationMax: number; - fakeDurationMin: number; - oreID: number; - quantity: number; - powermine: boolean; - iQty?: number; -} - -export interface MotherlodeMiningActivityTaskOptions extends ActivityTaskOptions { - type: 'MotherlodeMining'; - fakeDurationMax: number; - fakeDurationMin: number; - quantity: number; - iQty?: number; -} - -export interface SmeltingActivityTaskOptions extends ActivityTaskOptions { - type: 'Smelting'; - barID: number; - quantity: number; - blastf: boolean; -} - -export interface SmithingActivityTaskOptions extends ActivityTaskOptions { - type: 'Smithing'; - smithedBarID: number; - quantity: number; -} - -export interface FiremakingActivityTaskOptions extends ActivityTaskOptions { - type: 'Firemaking'; - burnableID: number; - quantity: number; -} - -export interface WoodcuttingActivityTaskOptions extends ActivityTaskOptions { - type: 'Woodcutting'; - fakeDurationMax: number; - fakeDurationMin: number; - powerchopping: boolean; - forestry?: boolean; - twitchers?: TwitcherGloves; - logID: number; - quantity: number; - iQty?: number; -} - -export interface CraftingActivityTaskOptions extends ActivityTaskOptions { - type: 'Crafting'; - craftableID: number; - quantity: number; -} - -export interface FletchingActivityTaskOptions extends ActivityTaskOptions { - type: 'Fletching'; - fletchableName: string; - quantity: number; -} - -export interface EnchantingActivityTaskOptions extends ActivityTaskOptions { - type: 'Enchanting'; - itemID: number; - quantity: number; -} - -export interface CastingActivityTaskOptions extends ActivityTaskOptions { - type: 'Casting'; - spellID: number; - quantity: number; -} -export interface PickpocketActivityTaskOptions extends ActivityTaskOptions { - type: 'Pickpocket'; - monsterID: number; - quantity: number; - xpReceived: number; - successfulQuantity: number; - damageTaken: number; -} - -export interface BuryingActivityTaskOptions extends ActivityTaskOptions { - type: 'Burying'; - boneID: number; - quantity: number; -} - -export interface ScatteringActivityTaskOptions extends ActivityTaskOptions { - type: 'Scattering'; - ashID: number; - quantity: number; -} - -export interface OfferingActivityTaskOptions extends ActivityTaskOptions { - type: 'Offering'; - boneID: number; - quantity: number; -} - -export interface AnimatedArmourActivityTaskOptions extends ActivityTaskOptions { - type: 'AnimatedArmour'; - armourID: string; - quantity: number; -} - -export interface HerbloreActivityTaskOptions extends ActivityTaskOptions { - type: 'Herblore'; - mixableID: number; - quantity: number; - zahur: boolean; - wesley: boolean; -} - -export interface CutLeapingFishActivityTaskOptions extends ActivityTaskOptions { - type: 'CutLeapingFish'; - fishID: number; - quantity: number; -} - -export interface HunterActivityTaskOptions extends ActivityTaskOptions { - type: 'Hunter'; - creatureName: string; - quantity: number; - usingHuntPotion: boolean; - wildyPeak: Peak | null; - usingStaminaPotion: boolean; -} - -export interface AlchingActivityTaskOptions extends ActivityTaskOptions { - type: 'Alching'; - itemID: number; - quantity: number; - alchValue: number; -} - -export interface FightCavesActivityTaskOptions extends ActivityTaskOptions { - type: 'FightCaves'; - jadDeathChance: number; - preJadDeathChance: number; - preJadDeathTime: number | null; - fakeDuration: number; - quantity: number; -} -export interface InfernoOptions extends ActivityTaskOptions { - type: 'Inferno'; - zukDeathChance: number; - preZukDeathChance: number; - deathTime: number | null; - fakeDuration: number; - diedZuk: boolean; - diedPreZuk: boolean; - cost: ItemBank; -} - -export interface FarmingActivityTaskOptions extends ActivityTaskOptions { - type: 'Farming'; - pid?: number; - plantsName: string | null; - quantity: number; - upgradeType: CropUpgradeType | null; - payment?: boolean; - patchType: IPatchData; - planting: boolean; - currentDate: number; - autoFarmed: boolean; -} - -export interface BirdhouseActivityTaskOptions extends ActivityTaskOptions { - type: 'Birdhouse'; - birdhouseName: string | null; - placing: boolean; - gotCraft: boolean; - birdhouseData: BirdhouseData; - currentDate: number; -} - -interface MinigameActivityTaskOptions extends ActivityTaskOptions { - minigameID: MinigameName; - quantity: number; -} - -export interface MinigameActivityTaskOptionsWithNoChanges extends MinigameActivityTaskOptions { - type: - | 'Wintertodt' - | 'TroubleBrewing' - | 'TearsOfGuthix' - | 'SoulWars' - | 'RoguesDenMaze' - | 'MageTrainingArena' - | 'LastManStanding' - | 'BigChompyBirdHunting' - | 'FishingTrawler' - | 'PestControl' - | 'BarbarianAssault' - | 'ChampionsChallenge' - | 'CastleWars' - | 'AgilityArena' - | 'GiantsFoundry'; -} - -export interface MahoganyHomesActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'MahoganyHomes'; - xp: number; - quantity: number; - points: number; - tier: number; -} - -export interface NightmareActivityTaskOptions extends ActivityTaskOptions { - type: 'Nightmare'; - method: 'solo' | 'mass'; - quantity: number; - isPhosani?: boolean; -} - -export interface TemporossActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'Tempoross'; - quantity: number; - rewardBoost: number; -} - -export interface TitheFarmActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'TitheFarm'; -} - -export interface SepulchreActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'Sepulchre'; - floors: number[]; -} - -export interface PlunderActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'Plunder'; - rooms: number[]; -} - -export interface ZalcanoActivityTaskOptions extends ActivityTaskOptions { - type: 'Zalcano'; - isMVP: boolean; - performance: number; - quantity: number; -} - -export interface TempleTrekkingActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'Trekking'; - difficulty: string; -} - -export interface SawmillActivityTaskOptions extends ActivityTaskOptions { - type: 'Sawmill'; - plankID: number; - plankQuantity: number; -} - -export interface ButlerActivityTaskOptions extends ActivityTaskOptions { - type: 'Butler'; - plankID: number; - plankQuantity: number; -} - -export interface GnomeRestaurantActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'GnomeRestaurant'; - gloriesRemoved: number; -} - -export interface GauntletOptions extends ActivityTaskOptions { - type: 'Gauntlet'; - corrupted: boolean; - quantity: number; -} - -export interface GroupMonsterActivityTaskOptions extends Omit { - type: 'GroupMonsterKilling'; - leader: string; - users: string[]; -} - -export interface RaidsOptions extends ActivityTaskOptionsWithUsers { - type: 'Raids'; - leader: string; - users: string[]; - challengeMode: boolean; - quantity?: number; -} - -export interface TheatreOfBloodTaskOptions extends ActivityTaskOptionsWithUsers { - type: 'TheatreOfBlood'; - leader: string; - users: string[]; - hardMode: boolean; - fakeDuration: number; - wipedRooms: (null | number)[]; - deaths: number[][][]; - quantity: number; - solo?: boolean; -} - -export interface ColoTaskOptions extends ActivityTaskOptions { - type: 'Colosseum'; - fakeDuration: number; - diedAt?: number; - loot?: ItemBank; - maxGlory: number; -} - -type UserID = string; -type Points = number; -type RoomIDsDiedAt = number[]; - -type TOAUser = [UserID, Points[], RoomIDsDiedAt[]]; -export interface TOAOptions extends ActivityTaskOptionsWithUsers { - type: 'TombsOfAmascut'; - leader: string; - detailedUsers: TOAUser[] | [UserID, Points, RoomIDsDiedAt][][]; - raidLevel: RaidLevel; - fakeDuration: number; - wipedRoom: null | number | (number | null)[]; - quantity: number; -} - -export interface NexTaskOptions extends ActivityTaskOptionsWithUsers { - type: 'Nex'; - quantity: number; - leader: string; - userDetails: [string, number, number[]][]; - fakeDuration: number; - wipedKill: number | null; -} - -export interface CollectingOptions extends ActivityTaskOptions { - type: 'Collecting'; - collectableID: number; - quantity: number; - noStaminas?: boolean; -} - -export interface KourendFavourActivityTaskOptions extends ActivityTaskOptions { - type: 'KourendFavour'; - favour: string; - quantity: number; -} - -export interface TokkulShopOptions extends ActivityTaskOptions { - type: 'TokkulShop'; - itemID: number; - quantity: number; -} - -export interface UnderwaterAgilityThievingTaskOptions extends ActivityTaskOptions { - type: 'UnderwaterAgilityThieving'; - trainingSkill: UnderwaterAgilityThievingTrainingSkill; - quantity: number; - noStams: boolean; -} - -export interface PuroPuroActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'PuroPuro'; - quantity: number; - darkLure: boolean; - implingTier: number | null; -} - -export interface GiantsFoundryActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'GiantsFoundry'; - alloyID: number; - quantity: number; - metalScore: number; -} - -export interface GuardiansOfTheRiftActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'GuardiansOfTheRift'; - minedFragments: number; - barrierAndGuardian: number; - rolls: number; - combinationRunes: boolean; -} - -export interface NightmareZoneActivityTaskOptions extends MinigameActivityTaskOptions { - type: 'NightmareZone'; - strategy: NMZStrategy; - quantity: number; -} - -export interface ShadesOfMortonOptions extends MinigameActivityTaskOptions { - type: 'ShadesOfMorton'; - shadeID: string; - logID: number; -} -export interface SpecificQuestOptions extends ActivityTaskOptions { - type: 'SpecificQuest'; - questID: number; -} - -export type ActivityTaskData = - | MonsterActivityTaskOptions - | WoodcuttingActivityTaskOptions - | CollectingOptions - | RaidsOptions - | GauntletOptions - | CastingActivityTaskOptions - | EnchantingActivityTaskOptions - | ConstructionActivityTaskOptions - | HunterActivityTaskOptions - | ZalcanoActivityTaskOptions - | SawmillActivityTaskOptions - | ButlerActivityTaskOptions - | FarmingActivityTaskOptions - | HerbloreActivityTaskOptions - | FletchingActivityTaskOptions - | RunecraftActivityTaskOptions - | TempleTrekkingActivityTaskOptions - | TemporossActivityTaskOptions - | PuroPuroActivityTaskOptions - | KourendFavourActivityTaskOptions - | AgilityActivityTaskOptions - | InfernoOptions - | TOAOptions - | NexTaskOptions - | ZalcanoActivityTaskOptions - | TheatreOfBloodTaskOptions - | GuardiansOfTheRiftActivityTaskOptions - | GiantsFoundryActivityTaskOptions - | NightmareZoneActivityTaskOptions - | ShadesOfMortonOptions - | UnderwaterAgilityThievingTaskOptions - | PickpocketActivityTaskOptions - | BuryingActivityTaskOptions - | ScatteringActivityTaskOptions - | OfferingActivityTaskOptions - | AnimatedArmourActivityTaskOptions - | CookingActivityTaskOptions - | CraftingActivityTaskOptions - | FiremakingActivityTaskOptions - | FishingActivityTaskOptions - | MiningActivityTaskOptions - | MotherlodeMiningActivityTaskOptions - | PlunderActivityTaskOptions - | SmithingActivityTaskOptions - | SmeltingActivityTaskOptions - | TiaraRunecraftActivityTaskOptions - | ClueActivityTaskOptions - | AlchingActivityTaskOptions - | DarkAltarOptions - | GroupMonsterActivityTaskOptions - | MahoganyHomesActivityTaskOptions - | NightmareActivityTaskOptions - | TitheFarmActivityTaskOptions - | SepulchreActivityTaskOptions - | GnomeRestaurantActivityTaskOptions - | SpecificQuestOptions - | ActivityTaskOptionsWithNoChanges - | TokkulShopOptions - | BirdhouseActivityTaskOptions - | FightCavesActivityTaskOptions - | ActivityTaskOptionsWithQuantity - | MinigameActivityTaskOptionsWithNoChanges - | CutLeapingFishActivityTaskOptions - | ColoTaskOptions; - diff --git a/repeatStoredTrip.ts b/repeatStoredTrip.ts deleted file mode 100644 index 329a168b0a..0000000000 --- a/repeatStoredTrip.ts +++ /dev/null @@ -1,716 +0,0 @@ -import type { Activity, Prisma } from '@prisma/client'; -import { activity_type_enum } from '@prisma/client'; -import type { ButtonInteraction } from 'discord.js'; -import { ButtonBuilder, ButtonStyle } from 'discord.js'; -import { Time } from 'e'; - -import { autocompleteMonsters } from '../../mahoji/commands/k'; -import type { PvMMethod } from '../constants'; -import { SlayerActivityConstants } from '../minions/data/combatConstants'; -import { darkAltarRunes } from '../minions/functions/darkAltarCommand'; -import { convertStoredActivityToFlatActivity } from '../settings/prisma'; -import { runCommand } from '../settings/settings'; -import type { - ActivityTaskOptionsWithQuantity, - AgilityActivityTaskOptions, - AlchingActivityTaskOptions, - AnimatedArmourActivityTaskOptions, - BuryingActivityTaskOptions, - ButlerActivityTaskOptions, - CastingActivityTaskOptions, - ClueActivityTaskOptions, - CollectingOptions, - ConstructionActivityTaskOptions, - CookingActivityTaskOptions, - CraftingActivityTaskOptions, - CutLeapingFishActivityTaskOptions, - DarkAltarOptions, - EnchantingActivityTaskOptions, - FarmingActivityTaskOptions, - FiremakingActivityTaskOptions, - FishingActivityTaskOptions, - FletchingActivityTaskOptions, - GauntletOptions, - GiantsFoundryActivityTaskOptions, - GroupMonsterActivityTaskOptions, - GuardiansOfTheRiftActivityTaskOptions, - HerbloreActivityTaskOptions, - HunterActivityTaskOptions, - MahoganyHomesActivityTaskOptions, - MiningActivityTaskOptions, - MonsterActivityTaskOptions, - MotherlodeMiningActivityTaskOptions, - NexTaskOptions, - NightmareActivityTaskOptions, - OfferingActivityTaskOptions, - PickpocketActivityTaskOptions, - PuroPuroActivityTaskOptions, - RaidsOptions, - RunecraftActivityTaskOptions, - SawmillActivityTaskOptions, - ScatteringActivityTaskOptions, - ShadesOfMortonOptions, - SmeltingActivityTaskOptions, - SmithingActivityTaskOptions, - TOAOptions, - TempleTrekkingActivityTaskOptions, - TheatreOfBloodTaskOptions, - TiaraRunecraftActivityTaskOptions, - WoodcuttingActivityTaskOptions, - ZalcanoActivityTaskOptions -} from '../types/minions'; -import { itemNameFromID } from '../util'; -import { giantsFoundryAlloys } from './../../mahoji/lib/abstracted_commands/giantsFoundryCommand'; -import type { NightmareZoneActivityTaskOptions, UnderwaterAgilityThievingTaskOptions } from './../types/minions'; -import getOSItem from './getOSItem'; -import { deferInteraction } from './interactionReply'; - -const taskCanBeRepeated = (activity: Activity) => { - if (activity.type === activity_type_enum.ClueCompletion) { - const realActivity = convertStoredActivityToFlatActivity(activity) as ClueActivityTaskOptions; - return realActivity.implingID !== undefined; - } - return !( - [ - activity_type_enum.TearsOfGuthix, - activity_type_enum.ShootingStars, - activity_type_enum.BirthdayEvent, - activity_type_enum.BlastFurnace, - activity_type_enum.Easter, - activity_type_enum.TokkulShop, - activity_type_enum.Birdhouse, - activity_type_enum.StrongholdOfSecurity, - activity_type_enum.CombatRing - ] as activity_type_enum[] - ).includes(activity.type); -}; - -const tripHandlers = { - [activity_type_enum.ClueCompletion]: { - commandName: 'clue', - args: (data: ClueActivityTaskOptions) => ({ tier: data.clueID, implings: getOSItem(data.implingID!).name }) - }, - [activity_type_enum.SpecificQuest]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.HalloweenEvent]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.Birdhouse]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.StrongholdOfSecurity]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.CombatRing]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.TearsOfGuthix]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.TokkulShop]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.ShootingStars]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.BirthdayEvent]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.BlastFurnace]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.Easter]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.Revenants]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.KourendFavour]: { - commandName: 'm', - args: () => ({}) - }, - [activity_type_enum.AerialFishing]: { - commandName: 'activities', - args: () => ({ aerial_fishing: {} }) - }, - [activity_type_enum.Agility]: { - commandName: 'laps', - args: (data: AgilityActivityTaskOptions) => ({ - name: data.courseID, - quantity: data.quantity, - alch: Boolean(data.alch) - }) - }, - [activity_type_enum.AgilityArena]: { - commandName: 'minigames', - args: () => ({ agility_arena: { start: {} } }) - }, - [activity_type_enum.Alching]: { - commandName: 'activities', - args: (data: AlchingActivityTaskOptions) => ({ - alch: { quantity: data.quantity, item: itemNameFromID(data.itemID) } - }) - }, - [activity_type_enum.AnimatedArmour]: { - commandName: 'activities', - args: (data: AnimatedArmourActivityTaskOptions) => ({ - warriors_guild: { action: 'tokens', quantity: data.quantity } - }) - }, - [activity_type_enum.CamdozaalMining]: { - commandName: 'activities', - args: (data: ActivityTaskOptionsWithQuantity) => ({ - camdozaal: { action: 'mining', quantity: data.iQty } - }) - }, - [activity_type_enum.CamdozaalSmithing]: { - commandName: 'activities', - args: (data: ActivityTaskOptionsWithQuantity) => ({ - camdozaal: { action: 'smithing', quantity: data.quantity } - }) - }, - [activity_type_enum.CamdozaalFishing]: { - commandName: 'activities', - args: (data: ActivityTaskOptionsWithQuantity) => ({ - camdozaal: { action: 'fishing', quantity: data.iQty } - }) - }, - [activity_type_enum.BarbarianAssault]: { - commandName: 'minigames', - args: () => ({ barb_assault: { start: {} } }) - }, - [activity_type_enum.BigChompyBirdHunting]: { - commandName: 'activities', - args: () => ({ chompy_hunt: { action: 'start' } }) - }, - [activity_type_enum.Smelting]: { - commandName: 'smelt', - args: (data: SmeltingActivityTaskOptions) => ({ - name: itemNameFromID(data.barID), - quantity: data.quantity, - blast_furnace: data.blastf - }) - }, - [activity_type_enum.Burying]: { - commandName: 'activities', - args: (data: BuryingActivityTaskOptions) => ({ - bury: { quantity: data.quantity, name: itemNameFromID(data.boneID) } - }) - }, - [activity_type_enum.Scattering]: { - commandName: 'activities', - args: (data: ScatteringActivityTaskOptions) => ({ - scatter: { quantity: data.quantity, name: itemNameFromID(data.ashID) } - }) - }, - [activity_type_enum.Casting]: { - commandName: 'activities', - args: (data: CastingActivityTaskOptions) => ({ cast: { spell: data.spellID, quantity: data.quantity } }) - }, - [activity_type_enum.CastleWars]: { - commandName: 'minigames', - args: () => ({ castle_wars: { start: {} } }) - }, - [activity_type_enum.ChampionsChallenge]: { - commandName: 'activities', - args: () => ({ champions_challenge: {} }) - }, - [activity_type_enum.Collecting]: { - commandName: 'activities', - args: (data: CollectingOptions) => ({ - collect: { item: itemNameFromID(data.collectableID), no_stams: data.noStaminas, quantity: data.quantity } - }) - }, - [activity_type_enum.Construction]: { - commandName: 'build', - args: (data: ConstructionActivityTaskOptions) => ({ name: data.objectID, quantity: data.quantity }) - }, - [activity_type_enum.Cooking]: { - commandName: 'cook', - args: (data: CookingActivityTaskOptions) => ({ - name: itemNameFromID(data.cookableID), - quantity: data.quantity - }) - }, - [activity_type_enum.Crafting]: { - commandName: 'craft', - args: (data: CraftingActivityTaskOptions) => ({ - name: itemNameFromID(data.craftableID), - quantity: data.quantity - }) - }, - [activity_type_enum.Cyclops]: { - commandName: 'activities', - args: (data: ActivityTaskOptionsWithQuantity) => ({ - warriors_guild: { action: 'cyclops', quantity: data.quantity } - }) - }, - [activity_type_enum.DarkAltar]: { - commandName: 'runecraft', - args: (data: DarkAltarOptions) => ({ rune: `${darkAltarRunes[data.rune].item.name} (zeah)` }) - }, - [activity_type_enum.Runecraft]: { - commandName: 'runecraft', - args: (data: RunecraftActivityTaskOptions) => ({ - rune: itemNameFromID(data.runeID), - quantity: data.essenceQuantity, - daeyalt_essence: data.daeyaltEssence, - usestams: data.useStaminas - }) - }, - [activity_type_enum.TiaraRunecraft]: { - commandName: 'runecraft', - args: (data: TiaraRunecraftActivityTaskOptions) => ({ - rune: itemNameFromID(data.tiaraID), - quantity: data.tiaraQuantity - }) - }, - [activity_type_enum.Enchanting]: { - commandName: 'activities', - args: (data: EnchantingActivityTaskOptions) => ({ - enchant: { quantity: data.quantity, name: itemNameFromID(data.itemID) } - }) - }, - [activity_type_enum.Farming]: { - commandName: 'farming', - args: (data: FarmingActivityTaskOptions) => - data.autoFarmed - ? { - auto_farm: {} - } - : {} - }, - [activity_type_enum.FightCaves]: { - commandName: 'activities', - args: () => ({ fight_caves: {} }) - }, - [activity_type_enum.Firemaking]: { - commandName: 'light', - args: (data: FiremakingActivityTaskOptions) => ({ - name: itemNameFromID(data.burnableID), - quantity: data.quantity - }) - }, - [activity_type_enum.Fishing]: { - commandName: 'fish', - args: (data: FishingActivityTaskOptions) => ({ - name: data.fishID, - quantity: data.quantity, - powerfish: data.powerfish ?? false, - spirit_flakes: data.spirit_flakes ?? false - }) - - }, - [activity_type_enum.FishingTrawler]: { - commandName: 'minigames', - args: () => ({ fishing_trawler: { start: {} } }) - }, - [activity_type_enum.Fletching]: { - commandName: 'fletch', - args: (data: FletchingActivityTaskOptions) => ({ name: data.fletchableName, quantity: data.quantity }) - }, - [activity_type_enum.Gauntlet]: { - commandName: 'minigames', - args: (data: GauntletOptions) => ({ gauntlet: { start: { corrupted: data.corrupted } } }) - }, - [activity_type_enum.GloryCharging]: { - commandName: 'activities', - args: (data: ActivityTaskOptionsWithQuantity) => ({ charge: { item: 'glory', quantity: data.quantity } }) - }, - [activity_type_enum.GnomeRestaurant]: { - commandName: 'minigames', - args: () => ({ gnome_restaurant: { start: {} } }) - }, - [activity_type_enum.GroupMonsterKilling]: { - commandName: 'mass', - args: (data: GroupMonsterActivityTaskOptions) => ({ - monster: autocompleteMonsters.find(i => i.id === data.monsterID)?.name ?? data.monsterID.toString() - }) - }, - [activity_type_enum.Herblore]: { - commandName: 'mix', - args: (data: HerbloreActivityTaskOptions) => ({ - name: itemNameFromID(data.mixableID), - quantity: data.quantity, - zahur: data.zahur - }) - }, - [activity_type_enum.CutLeapingFish]: { - commandName: 'cook', - args: (data: CutLeapingFishActivityTaskOptions) => ({ - name: itemNameFromID(data.fishID), - quantity: data.quantity - }) - }, - [activity_type_enum.Hunter]: { - commandName: 'hunt', - args: (data: HunterActivityTaskOptions) => ({ - name: data.creatureName, - quantity: data.quantity, - hunter_potion: data.usingHuntPotion, - stamina_potions: data.usingStaminaPotion - }) - }, - [activity_type_enum.Inferno]: { - commandName: 'activities', - args: () => ({ inferno: { action: 'start' } }) - }, - [activity_type_enum.LastManStanding]: { - commandName: 'minigames', - args: () => ({ lms: { start: {} } }) - }, - [activity_type_enum.MageArena]: { - commandName: 'minigames', - args: () => ({ mage_arena: { start: {} } }) - }, - [activity_type_enum.MageArena2]: { - commandName: 'minigames', - args: () => ({ mage_arena_2: { start: {} } }) - }, - [activity_type_enum.MageTrainingArena]: { - commandName: 'minigames', - args: () => ({ mage_training_arena: { start: {} } }) - }, - [activity_type_enum.MahoganyHomes]: { - commandName: 'minigames', - args: (data: MahoganyHomesActivityTaskOptions) => ({ mahogany_homes: { start: { tier: data.tier } } }) - }, - [activity_type_enum.Mining]: { - commandName: 'mine', - args: (data: MiningActivityTaskOptions) => ({ - name: data.oreID, - quantity: data.iQty, - powermine: data.powermine - }) - }, - [activity_type_enum.MotherlodeMining]: { - commandName: 'mine', - args: (data: MotherlodeMiningActivityTaskOptions) => ({ - name: 'Motherlode mine', - quantity: data.iQty - }) - }, - [activity_type_enum.MonsterKilling]: { - commandName: 'k', - args: (data: MonsterActivityTaskOptions) => { - let method: PvMMethod = 'none'; - if (data.usingCannon) method = 'cannon'; - if (data.chinning) method = 'chinning'; - else if (data.burstOrBarrage === SlayerActivityConstants.IceBarrage) method = 'barrage'; - else if (data.burstOrBarrage === SlayerActivityConstants.IceBurst) method = 'burst'; - return { - name: autocompleteMonsters.find(i => i.id === data.monsterID)?.name ?? data.monsterID.toString(), - quantity: data.iQty, - method, - wilderness: data.isInWilderness - }; - } - }, - [activity_type_enum.Nex]: { - commandName: 'k', - args: (data: NexTaskOptions) => { - return { - name: 'nex', - quantity: data.quantity, - solo: data.userDetails.length === 1 - }; - } - }, - [activity_type_enum.Zalcano]: { - commandName: 'k', - args: (data: ZalcanoActivityTaskOptions) => ({ - name: 'zalcano', - quantity: data.quantity - }) - }, - [activity_type_enum.Tempoross]: { - commandName: 'k', - args: () => ({ - name: 'tempoross' - }) - }, - [activity_type_enum.Wintertodt]: { - commandName: 'k', - args: (data: ActivityTaskOptionsWithQuantity) => ({ - name: 'wintertodt', - quantity: data.quantity - }) - }, - [activity_type_enum.Nightmare]: { - commandName: 'k', - args: (data: NightmareActivityTaskOptions) => ({ - name: data.isPhosani ? 'phosani nightmare' : data.method === 'mass' ? 'mass nightmare' : 'solo nightmare', - quantity: data.quantity - }) - }, - [activity_type_enum.Offering]: { - commandName: 'offer', - args: (data: OfferingActivityTaskOptions) => ({ quantity: data.quantity, name: itemNameFromID(data.boneID) }) - }, - [activity_type_enum.PestControl]: { - commandName: 'minigames', - args: () => ({ pest_control: { start: {} } }) - }, - [activity_type_enum.Pickpocket]: { - commandName: 'steal', - args: (data: PickpocketActivityTaskOptions) => ({ name: data.monsterID, quantity: data.quantity }) - }, - [activity_type_enum.Plunder]: { - commandName: 'minigames', - args: () => ({ pyramid_plunder: {} }) - }, - [activity_type_enum.PuroPuro]: { - commandName: 'activities', - args: (data: PuroPuroActivityTaskOptions) => ({ - puro_puro: { implingTier: data.implingTier || '', dark_lure: data.darkLure } - }) - }, - [activity_type_enum.Questing]: { - commandName: 'activities', - args: () => ({ - quest: {} - }) - }, - [activity_type_enum.Raids]: { - commandName: 'raid', - args: (data: RaidsOptions) => ({ - cox: { - start: { - challenge_mode: data.challengeMode, - type: data.users.length === 1 ? 'solo' : 'mass', - quantity: data.quantity - } - } - }) - }, - [activity_type_enum.RoguesDenMaze]: { - commandName: 'minigames', - args: () => ({ - rogues_den: {} - }) - }, - [activity_type_enum.Sawmill]: { - commandName: 'activities', - args: (data: SawmillActivityTaskOptions) => ({ - plank_make: { action: 'sawmill', quantity: data.plankQuantity, type: itemNameFromID(data.plankID) } - }) - }, - [activity_type_enum.Butler]: { - commandName: 'activities', - args: (data: ButlerActivityTaskOptions) => ({ - plank_make: { action: 'butler', quantity: data.plankQuantity, type: itemNameFromID(data.plankID) } - }) - }, - [activity_type_enum.Sepulchre]: { - commandName: 'minigames', - args: () => ({ sepulchre: { start: {} } }) - }, - [activity_type_enum.Smithing]: { - commandName: 'smith', - args: (data: SmithingActivityTaskOptions) => ({ - name: itemNameFromID(data.smithedBarID), - quantity: data.quantity - }) - }, - [activity_type_enum.SoulWars]: { - commandName: 'minigames', - args: () => ({ soul_wars: { start: {} } }) - }, - [activity_type_enum.TheatreOfBlood]: { - commandName: 'raid', - args: (data: TheatreOfBloodTaskOptions) => ({ - tob: { - start: { - hard_mode: data.hardMode, - solo: data.solo - } - } - }) - }, - [activity_type_enum.TitheFarm]: { - commandName: 'farming', - args: () => ({ tithe_farm: {} }) - }, - [activity_type_enum.Trekking]: { - commandName: 'minigames', - args: (data: TempleTrekkingActivityTaskOptions) => ({ - temple_trek: { start: { difficulty: data.difficulty, quantity: data.quantity } } - }) - }, - [activity_type_enum.TroubleBrewing]: { - commandName: 'minigames', - args: () => ({ trouble_brewing: { start: {} } }) - }, - [activity_type_enum.VolcanicMine]: { - commandName: 'minigames', - args: (data: ActivityTaskOptionsWithQuantity) => ({ volcanic_mine: { start: { quantity: data.quantity } } }) - }, - [activity_type_enum.WealthCharging]: { - commandName: 'activities', - args: (data: ActivityTaskOptionsWithQuantity) => ({ charge: { item: 'wealth', quantity: data.quantity } }) - }, - [activity_type_enum.Woodcutting]: { - commandName: 'chop', - args: (data: WoodcuttingActivityTaskOptions) => ({ - name: itemNameFromID(data.logID), - quantity: data.iQty, - powerchop: data.powerchopping, - forestry_events: data.forestry, - twitchers_gloves: data.twitchers - }) - }, - [activity_type_enum.GiantsFoundry]: { - commandName: 'minigames', - args: (data: GiantsFoundryActivityTaskOptions) => ({ - giants_foundry: { - start: { name: giantsFoundryAlloys.find(i => i.id === data.alloyID)?.name, quantity: data.quantity } - } - }) - }, - [activity_type_enum.GuardiansOfTheRift]: { - commandName: 'minigames', - args: (data: GuardiansOfTheRiftActivityTaskOptions) => ({ - gotr: { - start: { combination_runes: data.combinationRunes } - } - }) - }, - [activity_type_enum.NightmareZone]: { - commandName: 'minigames', - args: (data: NightmareZoneActivityTaskOptions) => ({ - nmz: { - start: { strategy: data.strategy } - } - }) - }, - [activity_type_enum.ShadesOfMorton]: { - commandName: 'minigames', - args: (data: ShadesOfMortonOptions) => ({ - shades_of_morton: { - start: { shade: data.shadeID, logs: itemNameFromID(data.logID) } - } - }) - }, - [activity_type_enum.TombsOfAmascut]: { - commandName: 'raid', - args: (data: TOAOptions) => ({ - toa: { - start: { - raid_level: data.raidLevel, - max_team_size: data.users.length, - solo: data.users.length === 1, - quantity: data.quantity - } - } - }) - }, - [activity_type_enum.UnderwaterAgilityThieving]: { - commandName: 'activities', - args: (data: UnderwaterAgilityThievingTaskOptions) => ({ - underwater: { - agility_thieving: { - training_skill: data.trainingSkill, - minutes: Math.floor(data.duration / Time.Minute), - no_stams: data.noStams - } - } - }) - }, - [activity_type_enum.DriftNet]: { - commandName: 'activities', - args: (data: ActivityTaskOptionsWithQuantity) => ({ - underwater: { - drift_net_fishing: { minutes: Math.floor(data.duration / Time.Minute) } - } - }) - }, - [activity_type_enum.Colosseum]: { - commandName: 'k', - args: () => ({ - name: 'colosseum' - }) - } -} as const; - -for (const type of Object.values(activity_type_enum)) { - if (!tripHandlers[type]) { - throw new Error(`Missing trip handler for ${type}`); - } -} - -export async function fetchRepeatTrips(userID: string) { - const res: Activity[] = await prisma.activity.findMany({ - where: { - user_id: BigInt(userID), - finish_date: { - gt: new Date(Date.now() - Time.Day * 7) - } - }, - orderBy: { - id: 'desc' - }, - take: 20 - }); - const filtered: { - type: activity_type_enum; - data: Prisma.JsonValue; - }[] = []; - for (const trip of res) { - if (!taskCanBeRepeated(trip)) continue; - if (trip.type === activity_type_enum.Farming && !(trip.data as any as FarmingActivityTaskOptions).autoFarmed) { - continue; - } - if (!filtered.some(i => i.type === trip.type)) { - filtered.push(trip); - } - } - return filtered; -} - -export async function makeRepeatTripButtons(user: MUser) { - const trips = await fetchRepeatTrips(user.id); - const buttons: ButtonBuilder[] = []; - const limit = Math.min(user.perkTier() + 1, 5); - for (const trip of trips.slice(0, limit)) { - buttons.push( - new ButtonBuilder() - .setLabel(`Repeat ${trip.type}`) - .setCustomId(`REPEAT_TRIP_${trip.type}`) - .setStyle(ButtonStyle.Secondary) - ); - } - return buttons; -} - -export async function repeatTrip( - interaction: ButtonInteraction, - data: { data: Prisma.JsonValue; type: activity_type_enum } -) { - await deferInteraction(interaction); - const handler = tripHandlers[data.type]; - return runCommand({ - commandName: handler.commandName, - isContinue: true, - args: handler.args(data.data as any), - interaction, - guildID: interaction.guildId, - member: interaction.member, - channelID: interaction.channelId, - user: interaction.user, - continueDeltaMillis: interaction.createdAt.getTime() - interaction.message.createdTimestamp - }); -} - diff --git a/types.ts b/types.ts deleted file mode 100644 index a6b11fee6f..0000000000 --- a/types.ts +++ /dev/null @@ -1,362 +0,0 @@ -import type { Bank } from 'oldschooljs'; -import type { Item } from 'oldschooljs/dist/meta/types'; -import type LootTable from 'oldschooljs/dist/structures/LootTable'; - -import type { Emoji } from '../constants'; -import type { SlayerTaskUnlocksEnum } from '../slayer/slayerUnlocks'; -import type { ItemBank } from '../types'; -import type { FarmingPatchName } from '../util/farmingHelpers'; - -export enum SkillsEnum { - Agility = 'agility', - Cooking = 'cooking', - Fishing = 'fishing', - Mining = 'mining', - Smithing = 'smithing', - Woodcutting = 'woodcutting', - Firemaking = 'firemaking', - Runecraft = 'runecraft', - Crafting = 'crafting', - Prayer = 'prayer', - Fletching = 'fletching', - Farming = 'farming', - Herblore = 'herblore', - Thieving = 'thieving', - Hunter = 'hunter', - Construction = 'construction', - Magic = 'magic', - Attack = 'attack', - Strength = 'strength', - Defence = 'defence', - Ranged = 'ranged', - Hitpoints = 'hitpoints', - Slayer = 'slayer' -} - -export const SkillsArray = [ - 'agility', - 'cooking', - 'fishing', - 'mining', - 'smithing', - 'woodcutting', - 'firemaking', - 'runecraft', - 'crafting', - 'prayer', - 'fletching', - 'farming', - 'herblore', - 'thieving', - 'hunter', - 'construction', - 'magic', - 'attack', - 'strength', - 'defence', - 'ranged', - 'hitpoints', - 'slayer' -] as const; - -export type SkillNameType = (typeof SkillsArray)[number]; -for (const skill of SkillsArray) { - const matching = Object.keys(SkillsEnum).find(key => key.toLowerCase() === skill); - if (!matching) throw new Error(`Missing skill enum for ${skill}`); -} -if (SkillsArray.length !== Object.keys(SkillsEnum).length) { - throw new Error('Not all skills have been added to the SkillsArray.'); -} - -export interface Ore { - level: number; - xp: number; - id: number; - name: string; - respawnTime: number; - bankingTime: number; - slope: number; - intercept: number; - petChance?: number; - minerals?: number; - clueScrollChance?: number; - aliases?: string[]; -} - -export interface Log { - level: number; - xp: number; - id: number; - lootTable?: LootTable; - name: string; - leaf?: number; - aliases?: string[]; - findNewTreeTime: number; - bankingTime: number; - slope: number; - intercept: number; - depletionChance: number; - wcGuild?: boolean; - petChance?: number; - qpRequired: number; - clueScrollChance?: number; - clueNestsOnly?: boolean; -} - -export interface Burnable { - level: number; - xp: number; - name: string; - inputLogs: number; -} - -export interface Fish { - name: string; - alias?: string[]; - level: number; - xp: number; - id: number; - chance1Lvl1?: number; - chance1Lvl99?: number; - level2?: number; - xp2?: number; - id2?: number; - chance2Lvl1?: number; - chance2Lvl99?: number; - level3?: number; - xp3?: number; - id3?: number; - chance3Lvl1?: number; - chance3Lvl99?: number; - - petChance?: number; - clueScrollChance?: number; - lostTicks?: number; - bankingTime?: number; - ticksPerRoll?: number; - - bait?: number; - qpRequired?: number; - bigFish?: number; - bigFishRate?: number; - - timePerFish?: number; -} - -export interface Course { - id: number; - name: string; - level: number; - xp: number | ((agilityLevel: number) => number); - marksPer60?: number; - lapTime: number; - petChance: number; - aliases: string[]; - qpRequired?: number; -} - -export interface Cookable { - level: number; - xp: number; - id: number; - name: string; - inputCookables: ItemBank; - stopBurnAt: number; - stopBurnAtCG?: number; - // Burn level with hosidius/diary: [ noGauntletsHosidius, noGauntletsElite, gauntletsHosidius, gauntletsElite ] - burnKourendBonus?: number[]; - burntCookable: number; - alias?: string[]; -} - -export interface Bar { - level: number; - xp: number; - id: number; - name: string; - inputOres: Bank; - /** - * Chance that the ore will fail to smelt (i.e iron), out of 100 - */ - chanceOfFail: number; - timeToUse: number; -} - -export interface BlastableBar { - level: number; - xp: number; - id: number; - name: string; - inputOres: Bank; - timeToUse: number; -} - -export interface SmithedItem { - level: number; - xp: number; - id: number; - name: string; - inputBars: ItemBank; - timeToUse: number; - outputMultiple: number; - qpRequired?: number; -} - -export interface Craftable { - name: string; - alias?: string[]; - id: number; - level: number; - xp: number; - inputItems: Bank; - tickRate: number; - crushChance?: number[]; - bankChest?: boolean; - outputMultiple?: number; - qpRequired?: number; - wcLvl?: number; -} - -export interface Fletchable { - name: string; - id: number; - level: number; - xp: number; - inputItems: Bank; - tickRate: number; - outputMultiple?: number; - requiredSlayerUnlocks?: SlayerTaskUnlocksEnum[]; - craftingXp?: number; -} - -export interface Mixable { - item: Item; - aliases: string[]; - level: number; - xp: number; - inputItems: Bank; - tickRate: number; - bankTimePerPotion: number; - outputMultiple?: number; - zahur?: boolean; - wesley?: boolean; - qpRequired?: number; -} - -export interface CutLeapingFish { - item: Item; - aliases: string[]; - tickRate: number; -} - -export interface Bone { - level: number; - xp: number; - name: string; - inputId: number; -} - -export interface Ash { - level: number; - xp: number; - name: string; - inputId: number; -} - -export type LevelRequirements = Partial<{ - [key in SkillsEnum]: number; -}>; - -export interface Skill { - aliases: string[]; - id: SkillsEnum; - emoji: Emoji; - name: string; -} - -export interface Plankable { - name: string; - inputItem: number; - outputItem: number; - gpCost: number; -} - -export interface Plant { - id: number; - level: number; - plantXp: number; - checkXp: number; - harvestXp: number; - name: string; - inputItems: Bank; - aliases: string[]; - outputCrop?: number; - cleanHerbCrop?: number; - herbXp?: number; - herbLvl?: number; - outputLogs?: number; - outputRoots?: number; - treeWoodcuttingLevel?: number; - fixedOutputAmount?: number; - variableYield?: boolean; - variableOutputAmount?: [string | null, number, number][]; - woodcuttingXp?: number; - needsChopForHarvest: boolean; - fixedOutput: boolean; - givesLogs: boolean; - givesCrops: boolean; - petChance: number; - seedType: FarmingPatchName; - growthTime: number; - numOfStages: number; - chance1: number; - chance99: number; - chanceOfDeath: number; - protectionPayment?: Bank; - defaultNumOfPatches: number; - canPayFarmer: boolean; - canCompostPatch: boolean; - canCompostandPay: boolean; - additionalPatchesByQP: number[][]; - additionalPatchesByFarmLvl: number[][]; - additionalPatchesByFarmGuildAndLvl: number[][]; - timePerPatchTravel: number; - timePerHarvest: number; -} - -export enum HunterTechniqueEnum { - AerialFishing = 'aerial fishing', - DriftNet = 'drift net fishing', - BirdSnaring = 'bird snaring', - BoxTrapping = 'box trapping', - ButterflyNetting = 'butterfly netting', - DeadfallTrapping = 'deadfall trapping', - Falconry = 'falconry', - MagicBoxTrapping = 'magic box trapping', - NetTrapping = 'net trapping', - PitfallTrapping = 'pitfall trapping', - RabbitSnaring = 'rabbit snaring', - Tracking = 'tracking' -} - -export interface Creature { - name: string; - id: number; - aliases: string[]; - level: number; - hunterXP: number; - fishLvl?: number; - fishingXP?: number; - itemsRequired?: Bank; - itemsConsumed?: Bank; - table: LootTable; - huntTechnique: HunterTechniqueEnum; - multiTraps?: boolean; - wildy?: boolean; - prayerLvl?: number; - herbloreLvl?: number; - catchTime: number; - qpRequired?: number; - slope: number; - intercept: number; -}