From c804bda44daf6d9a2f7ecd12de2b2f81db80c680 Mon Sep 17 00:00:00 2001
From: gc <30398469+gc@users.noreply.github.com>
Date: Wed, 16 Oct 2024 15:47:38 +1100
Subject: [PATCH] Mining command/trip refactoring and wiki page
---
docs/src/content/docs/getting-started/wiki.md | 40 ++-
.../mining => Activities}/motherlode-mine.md | 0
.../mining => Activities}/shooting-stars.md | 0
.../mining => Activities}/volcanic-mine.md | 0
.../mining => Miscelleanous}/zalcano.md | 0
.../Skills/{mining/README.md => mining.md} | 50 +++-
scripts/wiki.ts | 6 +-
scripts/wiki/miningXphr.ts | 54 ++++
src/lib/MUser.ts | 3 +-
.../functions/addSkillingClueToLoot.ts | 5 +-
.../skilling/functions/determineMiningTime.ts | 14 +-
src/lib/skilling/skills/mining.ts | 5 +
src/lib/structures/GearBank.ts | 13 +-
src/lib/structures/XPBank.ts | 11 +
src/lib/util.ts | 3 +-
src/mahoji/commands/mine.ts | 234 ++++++++++--------
.../abstracted_commands/camdozaalCommand.ts | 5 +-
.../motherlodeMineCommand.ts | 6 +-
.../shootingStarsCommand.ts | 5 +-
src/tasks/minions/miningActivity.ts | 233 ++++++++---------
tests/unit/utils.ts | 3 +-
21 files changed, 429 insertions(+), 261 deletions(-)
rename docs/src/content/docs/osb/{Skills/mining => Activities}/motherlode-mine.md (100%)
rename docs/src/content/docs/osb/{Skills/mining => Activities}/shooting-stars.md (100%)
rename docs/src/content/docs/osb/{Skills/mining => Activities}/volcanic-mine.md (100%)
rename docs/src/content/docs/osb/{Skills/mining => Miscelleanous}/zalcano.md (100%)
rename docs/src/content/docs/osb/Skills/{mining/README.md => mining.md} (72%)
create mode 100644 scripts/wiki/miningXphr.ts
diff --git a/docs/src/content/docs/getting-started/wiki.md b/docs/src/content/docs/getting-started/wiki.md
index f762a00fb4..3677c6010a 100644
--- a/docs/src/content/docs/getting-started/wiki.md
+++ b/docs/src/content/docs/getting-started/wiki.md
@@ -151,9 +151,9 @@ This is an automatically generated list of pages with possible issues to be look
[/bso/leagues.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/leagues.md): Doesnt use the new command formatting
-[/bso/Minigames/balthazars-big-bonanza.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Minigames/balthazars-big-bonanza.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. `
`)
+[/bso/Minigames/balthazars-big-bonanza.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Minigames/balthazars-big-bonanza.md): Doesnt use the new command formatting
-[/bso/Minigames/baxtorian-bathhouses.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Minigames/baxtorian-bathhouses.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
+[/bso/Minigames/baxtorian-bathhouses.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Minigames/baxtorian-bathhouses.md): Doesnt use the new command formatting
[/bso/Minigames/emerged-zuk-inferno.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Minigames/emerged-zuk-inferno.md): Doesnt use the new command formatting
@@ -227,13 +227,9 @@ This is an automatically generated list of pages with possible issues to be look
[/bso/Skills/crafting.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/crafting.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
-[/bso/Skills/Divination/efficient-divination-training.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/Divination/efficient-divination-training.md): Doesnt use the new command formatting
+[/bso/Skills/divination.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/divination.md): Doesnt use the new command formatting
-[/bso/Skills/Divination/README.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/Divination/README.md): Doesnt use the new command formatting
-
-[/bso/Skills/Dungeoneering Training/dg-rewards.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/Dungeoneering%20Training/dg-rewards.md): Doesnt use the new command formatting
-
-[/bso/Skills/Dungeoneering Training/README.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/Dungeoneering%20Training/README.md): Doesnt use the new command formatting
+[/bso/Skills/dungeoneering.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/dungeoneering.md): Doesnt use the new command formatting
[/bso/Skills/farming.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/farming.md): Doesnt use the new command formatting
@@ -247,9 +243,7 @@ This is an automatically generated list of pages with possible issues to be look
[/bso/Skills/hunter.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/hunter.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
-[/bso/Skills/Invention/efficient-disassembling-to-99.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/Invention/efficient-disassembling-to-99.md): Doesnt use the new command formatting
-
-[/bso/Skills/Invention/README.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/Invention/README.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
+[/bso/Skills/invention.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/invention.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
[/bso/Skills/mining.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Skills/mining.md): Doesnt use the new command formatting
@@ -269,16 +263,12 @@ This is an automatically generated list of pages with possible issues to be look
[/bso/Tames/eagle-tame.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Tames/eagle-tame.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
-[/bso/Tames/igne-equipment.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Tames/igne-equipment.md): Doesnt use the new command formatting
-
[/bso/Tames/igne-tame.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Tames/igne-tame.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
-[/bso/Tames/monkey-staff-and-spells.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Tames/monkey-staff-and-spells.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
+[/bso/Tames/introduction.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Tames/introduction.md): Doesnt use the new command formatting
[/bso/Tames/monkey-tame.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Tames/monkey-tame.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
-[/bso/Tames/README.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/bso/Tames/README.md): Doesnt use the new command formatting
-
[/getting-started/bingo.mdx](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/getting-started/bingo.mdx): Doesnt use the new command formatting
[/getting-started/BSO.mdx](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/getting-started/BSO.mdx): Doesnt use the new command formatting
@@ -307,6 +297,12 @@ This is an automatically generated list of pages with possible issues to be look
[/osb/Activities/mahogany-homes.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Activities/mahogany-homes.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
+[/osb/Activities/motherlode-mine.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Activities/motherlode-mine.md): Doesnt use the new command formatting
+
+[/osb/Activities/shooting-stars.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Activities/shooting-stars.md): Doesnt use the new command formatting
+
+[/osb/Activities/volcanic-mine.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Activities/volcanic-mine.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
+
[/osb/Activities/wintertodt.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Activities/wintertodt.md): Doesnt use the new command formatting
[/osb/Bosses/colosseum.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Bosses/colosseum.md): Doesnt use the new command formatting
@@ -387,6 +383,8 @@ This is an automatically generated list of pages with possible issues to be look
[/osb/Miscelleanous/tears-of-guthix.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Miscelleanous/tears-of-guthix.md): Doesnt use the new command formatting
+[/osb/Miscelleanous/zalcano.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Miscelleanous/zalcano.md): Doesnt use the new command formatting
+
[/osb/monsters.mdx](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/monsters.mdx): Doesnt use the new command formatting
[/osb/quests.mdx](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/quests.mdx): Doesnt use the new command formatting
@@ -449,15 +447,7 @@ This is an automatically generated list of pages with possible issues to be look
[/osb/Skills/magic.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Skills/magic.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
-[/osb/Skills/mining/motherlode-mine.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Skills/mining/motherlode-mine.md): Doesnt use the new command formatting
-
-[/osb/Skills/mining/README.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Skills/mining/README.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
-
-[/osb/Skills/mining/shooting-stars.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Skills/mining/shooting-stars.md): Doesnt use the new command formatting
-
-[/osb/Skills/mining/volcanic-mine.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Skills/mining/volcanic-mine.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
-
-[/osb/Skills/mining/zalcano.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Skills/mining/zalcano.md): Doesnt use the new command formatting
+[/osb/Skills/mining.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Skills/mining.md): Doesnt use the new command formatting, Contains unintended HTML (e.g. ` | `)
[/osb/Skills/prayer.md](https://github.com/oldschoolgg/oldschoolbot/blob/master/docs/src/content/docs/osb/Skills/prayer.md): Doesnt use the new command formatting
diff --git a/docs/src/content/docs/osb/Skills/mining/motherlode-mine.md b/docs/src/content/docs/osb/Activities/motherlode-mine.md
similarity index 100%
rename from docs/src/content/docs/osb/Skills/mining/motherlode-mine.md
rename to docs/src/content/docs/osb/Activities/motherlode-mine.md
diff --git a/docs/src/content/docs/osb/Skills/mining/shooting-stars.md b/docs/src/content/docs/osb/Activities/shooting-stars.md
similarity index 100%
rename from docs/src/content/docs/osb/Skills/mining/shooting-stars.md
rename to docs/src/content/docs/osb/Activities/shooting-stars.md
diff --git a/docs/src/content/docs/osb/Skills/mining/volcanic-mine.md b/docs/src/content/docs/osb/Activities/volcanic-mine.md
similarity index 100%
rename from docs/src/content/docs/osb/Skills/mining/volcanic-mine.md
rename to docs/src/content/docs/osb/Activities/volcanic-mine.md
diff --git a/docs/src/content/docs/osb/Skills/mining/zalcano.md b/docs/src/content/docs/osb/Miscelleanous/zalcano.md
similarity index 100%
rename from docs/src/content/docs/osb/Skills/mining/zalcano.md
rename to docs/src/content/docs/osb/Miscelleanous/zalcano.md
diff --git a/docs/src/content/docs/osb/Skills/mining/README.md b/docs/src/content/docs/osb/Skills/mining.md
similarity index 72%
rename from docs/src/content/docs/osb/Skills/mining/README.md
rename to docs/src/content/docs/osb/Skills/mining.md
index 2654773a45..35856455ea 100644
--- a/docs/src/content/docs/osb/Skills/mining/README.md
+++ b/docs/src/content/docs/osb/Skills/mining.md
@@ -100,6 +100,50 @@ The only other thing unidentified minerals can be used to purchase are:
- [[/buy name\:Bag full of gems (minerals)]] - 20 Unidentified minerals
-## Ores
-
-Ore Name | Minerals | Required Level | Experience | XP/Hr @ 99 |
---|
Ore Name | Minerals | Required Level | Experience | XP/Hr @ 99 | Rune essence | | 1 | 5 | 10,288 | Copper ore | | 1 | 17.5 | 26,881 | Tin ore | | 1 | 17.5 | 26,881 | Saltpetre | | 1 | 0 | 0 | Iron ore | ✔ | 15 | 35 | 50,332 | Silver ore | | 20 | 40 | 22,454 | Volcanic ash | | 22 | 10 | 9,810 | Pure essence | | 30 | 5 | 10,288 | Coal | ✔ | 30 | 50 | 31,644 | Gold ore | | 40 | 65 | 36,556 | Gem rock | | 40 | 65 | 20,865 | Mithril ore | | 55 | 80 | 17,231 | Adamantite ore | | 70 | 95 | 12,654 | Runite ore | | 85 | 125 | 6,731 | Amethyst | ✔ | 92 | 240 | 14,321 |
+## XP/hr
+
+[[embed.miningxphr.start]]
+{/_ DO NOT EDIT - This section is auto-generated by the build script _/}
+| Ore | XP/hr | Powermining |
+| --- | --- | --- |
+| [[6983]] | 114,000 | Yes |
+| [[6975]] | 81,000 | Yes |
+| [[440]] | 77,000 | Yes |
+| [[6975]] | 73,000 | No |
+| [[442]] | 62,000 | Yes |
+| [[6983]] | 60,000 | No |
+| [[442]] | 57,000 | No |
+| [[440]] | 55,000 | No |
+| [[453]] | 44,000 | Yes |
+| [[453]] | 38,000 | No |
+| [[436]] | 38,000 | Yes |
+| [[1625]] | 38,000 | Yes |
+| [[444]] | 38,000 | Yes |
+| [[438]] | 38,000 | Yes |
+| [[444]] | 37,000 | No |
+| [[1625]] | 36,000 | No |
+| [[447]] | 27,000 | Yes |
+| [[447]] | 26,000 | No |
+| [[21347]] | 23,000 | Yes |
+| [[21347]] | 22,000 | No |
+| [[436]] | 19,000 | No |
+| [[438]] | 19,000 | No |
+| [[449]] | 16,000 | Yes |
+| [[449]] | 15,000 | No |
+| [[21622]] | 13,000 | Yes |
+| [[21622]] | 13,000 | No |
+| [[434]] | 11,000 | Yes |
+| [[24706]] | 10,000 | Yes |
+| [[24706]] | 10,000 | No |
+| [[7936]] | 10,000 | Yes |
+| [[1436]] | 10,000 | Yes |
+| [[451]] | 10,000 | Yes |
+| [[451]] | 10,000 | No |
+| [[7936]] | 7,000 | No |
+| [[1436]] | 7,000 | No |
+| [[434]] | 5,000 | No |
+| [[13421]] | 0 | Yes |
+| [[13421]] | 0 | No |
+
+{/_ DO NOT EDIT - This section is auto-generated by the build script _/}
+[[embed.miningxphr.end]]
diff --git a/scripts/wiki.ts b/scripts/wiki.ts
index 0aba2c506d..c88644157a 100644
--- a/scripts/wiki.ts
+++ b/scripts/wiki.ts
@@ -4,6 +4,7 @@ import { glob } from 'glob';
import { Bank, Monsters } from 'oldschooljs';
import '../src/lib/safeglobals';
+import process from 'node:process';
import { groupBy } from 'remeda';
import { type CombatAchievement, CombatAchievements } from '../src/lib/combat_achievements/combatAchievements';
import { COXMaxMageGear, COXMaxMeleeGear, COXMaxRangeGear, itemBoosts } from '../src/lib/data/cox';
@@ -12,6 +13,7 @@ import { quests } from '../src/lib/minions/data/quests';
import { sorts } from '../src/lib/sorts';
import { itemNameFromID } from '../src/lib/util';
import { Markdown, Tab, Tabs } from './markdown/markdown';
+import { miningXpHr } from './wiki/miningXphr';
function combatAchievementHowToFinish(ca: CombatAchievement) {
if ('rng' in ca) {
@@ -27,7 +29,7 @@ function combatAchievementHowToFinish(ca: CombatAchievement) {
throw ca;
}
-function handleMarkdownEmbed(identifier: string, filePath: string, contentToInject: string) {
+export function handleMarkdownEmbed(identifier: string, filePath: string, contentToInject: string) {
const contentToReplace = readFileSync(`./docs/src/content/docs/${filePath}`, 'utf8');
const startMarker = `[[embed.${identifier}.start]]`;
const endMarker = `[[embed.${identifier}.end]]`;
@@ -435,7 +437,9 @@ async function wiki() {
renderQuestsMarkdown();
rendeCoxMarkdown();
wikiIssues();
+ miningXpHr();
await Promise.all([renderCAMarkdown(), renderMonstersMarkdown()]);
+ process.exit(0);
}
wiki();
diff --git a/scripts/wiki/miningXphr.ts b/scripts/wiki/miningXphr.ts
new file mode 100644
index 0000000000..119b37ffc2
--- /dev/null
+++ b/scripts/wiki/miningXphr.ts
@@ -0,0 +1,54 @@
+import { calcPerHour } from '@oldschoolgg/toolkit';
+import { Time } from 'e';
+
+import Mining from '../../src/lib/skilling/skills/mining';
+import type { Ore } from '../../src/lib/skilling/types';
+import { determineMiningTrip } from '../../src/mahoji/commands/mine';
+import { determineMiningResult } from '../../src/tasks/minions/miningActivity';
+import { makeGearBank } from '../../tests/unit/utils';
+import { Table } from '../markdown/markdown';
+import { handleMarkdownEmbed } from '../wiki';
+
+export function miningXpHr() {
+ const gearBank = makeGearBank();
+ gearBank.skillsAsLevels.mining = 99;
+ gearBank.skillsAsXP.mining = 13_500_000;
+ gearBank.gear.skilling.equip('Varrock armour 4');
+ gearBank.gear.skilling.equip('Expert mining gloves');
+ gearBank.gear.skilling.equip('Crystal pickaxe');
+ gearBank.skillsAsLevels.crafting = 99;
+
+ const results: { xpHr: number; ore: Ore; isPowermining: boolean }[] = [];
+ for (const ore of Mining.Ores) {
+ for (const isPowermining of [true, false]) {
+ const trip = determineMiningTrip({
+ gearBank,
+ ore,
+ maxTripLength: Time.Hour * 1000,
+ isPowermining,
+ quantityInput: undefined
+ });
+ const result = determineMiningResult({
+ ore,
+ quantity: trip.quantity,
+ gearBank,
+ duration: trip.duration,
+ isPowermining
+ });
+ const xp = result.updateBank.xpBank.amount('mining');
+ const xpHr = Math.floor(calcPerHour(xp, trip.duration) / 1000) * 1000;
+ results.push({ xpHr, ore, isPowermining });
+ }
+ }
+
+ results.sort((a, b) => a.ore.name.localeCompare(b.ore.name));
+ results.sort((a, b) => b.xpHr - a.xpHr);
+
+ const table = new Table();
+ table.addHeader('Ore', 'XP/hr', 'Powermining');
+ for (const result of results) {
+ table.addRow(`[[${result.ore.id}]]`, result.xpHr.toLocaleString(), result.isPowermining ? 'Yes' : 'No');
+ }
+
+ handleMarkdownEmbed('miningxphr', 'osb/Skills/mining.md', table.toString());
+}
diff --git a/src/lib/MUser.ts b/src/lib/MUser.ts
index 55cfe934fa..f0c34d3530 100644
--- a/src/lib/MUser.ts
+++ b/src/lib/MUser.ts
@@ -145,7 +145,8 @@ export class MUserClass {
gear: this.gear,
bank: this.bank,
skillsAsLevels: this.skillsAsLevels,
- chargeBank: this.ownedChargeBank()
+ chargeBank: this.ownedChargeBank(),
+ skillsAsXP: this.skillsAsXP
});
}
diff --git a/src/lib/minions/functions/addSkillingClueToLoot.ts b/src/lib/minions/functions/addSkillingClueToLoot.ts
index a605422286..9c19fb4c39 100644
--- a/src/lib/minions/functions/addSkillingClueToLoot.ts
+++ b/src/lib/minions/functions/addSkillingClueToLoot.ts
@@ -11,6 +11,7 @@ import {
treeSeedsNest
} from '../../simulation/birdsNest';
import { SkillsEnum } from '../../skilling/types';
+import { GearBank } from '../../structures/GearBank';
import { randFloat, roll } from '../../util';
import itemID from '../../util/itemID';
@@ -22,7 +23,7 @@ const clues = [
];
export default function addSkillingClueToLoot(
- user: MUser,
+ user: MUser | GearBank,
skill: SkillsEnum,
quantity: number,
clueChance: number,
@@ -32,7 +33,7 @@ export default function addSkillingClueToLoot(
twitcherSetting?: string,
wcCapeNestBoost?: boolean
) {
- const userLevel = user.skillLevel(skill);
+ const userLevel = user instanceof GearBank ? user.skillsAsLevels[skill] : user.skillLevel(skill);
const nestChance = wcCapeNestBoost ? Math.floor(256 * 0.9) : 256;
const cluesTotalWeight = sumArr(clues.map(c => c[1]));
let chance = Math.floor(clueChance / (100 + userLevel));
diff --git a/src/lib/skilling/functions/determineMiningTime.ts b/src/lib/skilling/functions/determineMiningTime.ts
index b60c1eb4fc..7516752518 100644
--- a/src/lib/skilling/functions/determineMiningTime.ts
+++ b/src/lib/skilling/functions/determineMiningTime.ts
@@ -1,11 +1,10 @@
import { Time, percentChance } from 'e';
-import { calcMaxTripLength } from '../../util/calcMaxTripLength';
+import type { GearBank } from '../../structures/GearBank';
import type { Ore } from './../types';
interface MiningTimeOptions {
quantity: number | undefined;
- user: MUser;
ore: Ore;
ticksBetweenRolls: number;
glovesRate: number;
@@ -15,11 +14,12 @@ interface MiningTimeOptions {
goldSilverBoost: boolean;
miningLvl: number;
passedDuration?: number;
+ maxTripLength: number;
+ gearBank: GearBank;
}
export function determineMiningTime({
quantity,
- user,
ore,
ticksBetweenRolls,
glovesRate,
@@ -28,10 +28,12 @@ export function determineMiningTime({
powermining,
goldSilverBoost,
miningLvl,
- passedDuration
+ passedDuration,
+ maxTripLength,
+ gearBank
}: MiningTimeOptions): [number, number] {
let { intercept } = ore;
- if (ore.name === 'Gem rock' && user.hasEquipped('Amulet of glory')) {
+ if (ore.name === 'Gem rock' && gearBank.hasEquipped('Amulet of glory')) {
intercept *= 3;
}
let timeElapsed = 0;
@@ -46,7 +48,7 @@ export function determineMiningTime({
passedDuration = 0;
}
- let userMaxTripTicks = (calcMaxTripLength(user, 'Mining') - passedDuration) / (Time.Second * 0.6);
+ let userMaxTripTicks = (maxTripLength - passedDuration) / (Time.Second * 0.6);
if (ore.name === 'Amethyst' || ore.name === 'Daeyalt essence rock') {
userMaxTripTicks *= 1.5;
diff --git a/src/lib/skilling/skills/mining.ts b/src/lib/skilling/skills/mining.ts
index 0202ace93d..96b05851c7 100644
--- a/src/lib/skilling/skills/mining.ts
+++ b/src/lib/skilling/skills/mining.ts
@@ -296,6 +296,11 @@ const prospectorItems: { [key: number]: number } = {
[itemID('Prospector boots')]: 0.2
};
+export const prospectorItemsArr = Object.entries(prospectorItems).map(([itemID, bonus]) => ({
+ id: Number.parseInt(itemID),
+ boostPercent: bonus
+}));
+
const Mining = {
aliases: ['mining'],
Ores: ores,
diff --git a/src/lib/structures/GearBank.ts b/src/lib/structures/GearBank.ts
index ba22793e9a..28154f47b8 100644
--- a/src/lib/structures/GearBank.ts
+++ b/src/lib/structures/GearBank.ts
@@ -10,18 +10,27 @@ export class GearBank {
gear: UserFullGearSetup;
bank: Bank;
skillsAsLevels: SkillsRequired;
+ skillsAsXP: SkillsRequired;
chargeBank: ChargeBank;
constructor({
gear,
bank,
skillsAsLevels,
- chargeBank
- }: { gear: UserFullGearSetup; bank: Bank; skillsAsLevels: SkillsRequired; chargeBank: ChargeBank }) {
+ chargeBank,
+ skillsAsXP
+ }: {
+ gear: UserFullGearSetup;
+ bank: Bank;
+ skillsAsLevels: SkillsRequired;
+ chargeBank: ChargeBank;
+ skillsAsXP: SkillsRequired;
+ }) {
this.gear = gear;
this.bank = bank;
this.skillsAsLevels = skillsAsLevels;
this.chargeBank = chargeBank;
+ this.skillsAsXP = skillsAsXP;
}
wildyGearCheck(item: string | number, isWildy: boolean) {
diff --git a/src/lib/structures/XPBank.ts b/src/lib/structures/XPBank.ts
index f371094653..de67f81251 100644
--- a/src/lib/structures/XPBank.ts
+++ b/src/lib/structures/XPBank.ts
@@ -1,6 +1,8 @@
import { sumArr } from 'e';
+import { skillEmoji } from '../data/emojis';
import type { AddXpParams } from '../minions/types';
import type { SkillNameType, SkillsEnum } from '../skilling/types';
+import type { Skills } from '../types';
export class XPBank {
public xpList: AddXpParams[] = [];
@@ -32,4 +34,13 @@ export class XPBank {
public amount(skill: SkillNameType) {
return sumArr(this.xpList.filter(i => i.skillName === skill).map(i => i.amount));
}
+
+ toString() {
+ if (this.xpList.length === 0) return 'No XP';
+ const grouped: Skills = {};
+ for (const i of this.xpList) grouped[i.skillName] = (grouped[i.skillName] ?? 0) + i.amount;
+ return Object.entries(grouped)
+ .map(([skill, xp]) => `${xp.toLocaleString()} ${skillEmoji[skill as keyof typeof skillEmoji]} XP`)
+ .join(', ');
+ }
}
diff --git a/src/lib/util.ts b/src/lib/util.ts
index 9be3535089..025ebd9ccb 100644
--- a/src/lib/util.ts
+++ b/src/lib/util.ts
@@ -37,6 +37,7 @@ import type { Consumable } from './minions/types';
import type { POHBoosts } from './poh';
import { SkillsEnum } from './skilling/types';
import type { Gear } from './structures/Gear';
+import type { GearBank } from './structures/GearBank';
import type { Skills } from './types';
import type {
GroupMonsterActivityTaskOptions,
@@ -279,7 +280,7 @@ export function roughMergeMahojiResponse(
}
export function skillingPetDropRate(
- user: MUserClass,
+ user: MUserClass | GearBank,
skill: SkillsEnum,
baseDropRate: number
): { petDropRate: number } {
diff --git a/src/mahoji/commands/mine.ts b/src/mahoji/commands/mine.ts
index 3ee0dbd8c5..95c082bfbf 100644
--- a/src/mahoji/commands/mine.ts
+++ b/src/mahoji/commands/mine.ts
@@ -7,14 +7,135 @@ import { determineMiningTime } from '../../lib/skilling/functions/determineMinin
import { miningCapeOreEffect, miningGloves, pickaxes, varrockArmours } from '../../lib/skilling/functions/miningBoosts';
import { sinsOfTheFatherSkillRequirements } from '../../lib/skilling/functions/questRequirements';
import Mining from '../../lib/skilling/skills/mining';
+import type { Ore } from '../../lib/skilling/types';
+import type { GearBank } from '../../lib/structures/GearBank';
import type { MiningActivityTaskOptions } from '../../lib/types/minions';
import { formatDuration, formatSkillRequirements, itemNameFromID, randomVariation } from '../../lib/util';
import addSubTaskToActivityTask from '../../lib/util/addSubTaskToActivityTask';
+import { calcMaxTripLength } from '../../lib/util/calcMaxTripLength';
import itemID from '../../lib/util/itemID';
import { minionName } from '../../lib/util/minionUtils';
import { motherlodeMineCommand } from '../lib/abstracted_commands/motherlodeMineCommand';
import type { OSBMahojiCommand } from '../lib/util';
+export function determineMiningTrip({
+ gearBank,
+ ore,
+ maxTripLength,
+ isPowermining,
+ quantityInput
+}: {
+ gearBank: GearBank;
+ ore: Ore;
+ maxTripLength: number;
+ isPowermining: boolean;
+ quantityInput: number | undefined;
+}) {
+ const boosts = [];
+ // Invisible mining level, dosen't help equip pickaxe etc
+ let miningLevel = gearBank.skillsAsLevels.mining;
+ if (ore.minerals && miningLevel >= 60) {
+ boosts.push('+7 invisible Mining lvls at the Mining guild');
+ miningLevel += 7;
+ }
+ // Checks if user own Celestial ring or Celestial signet
+ if (gearBank.hasEquippedOrInBank(['Celestial ring (uncharged)'])) {
+ boosts.push('+4 invisible Mining lvls for Celestial ring');
+ miningLevel += 4;
+ }
+ // Default bronze pickaxe, last in the array
+ let currentPickaxe = pickaxes[pickaxes.length - 1];
+ boosts.push(`**${currentPickaxe.ticksBetweenRolls}** ticks between rolls for ${itemNameFromID(currentPickaxe.id)}`);
+
+ // For each pickaxe, if they have it, give them its' bonus and break.
+ for (const pickaxe of pickaxes) {
+ if (!gearBank.hasEquippedOrInBank([pickaxe.id]) || gearBank.skillsAsLevels.mining < pickaxe.miningLvl) continue;
+ currentPickaxe = pickaxe;
+ boosts.pop();
+ boosts.push(`**${pickaxe.ticksBetweenRolls}** ticks between rolls for ${itemNameFromID(pickaxe.id)}`);
+ break;
+ }
+
+ let glovesRate = 0;
+ if (gearBank.skillsAsLevels.mining >= 60) {
+ for (const glove of miningGloves) {
+ if (!gearBank.hasEquipped(glove.id) || !glove.Percentages[ore.name]) continue;
+ glovesRate = glove.Percentages[ore.name];
+ if (glovesRate) {
+ boosts.push(`Lowered rock depletion rate by **${glovesRate}%** for ${itemNameFromID(glove.id)}`);
+ break;
+ }
+ }
+ }
+
+ let armourEffect = 0;
+ for (const armour of varrockArmours) {
+ if (!gearBank.hasEquippedOrInBank(armour.id) || !armour.Percentages[ore.name]) continue;
+ armourEffect = armour.Percentages[ore.name];
+ if (armourEffect) {
+ boosts.push(`**${armourEffect}%** chance to mine an extra ore using ${itemNameFromID(armour.id)}`);
+ break;
+ }
+ }
+
+ let goldSilverBoost = false;
+ if (gearBank.skillsAsLevels.crafting >= 99 && (ore.name === 'Gold ore' || ore.name === 'Silver ore')) {
+ goldSilverBoost = true;
+ boosts.push(`**70%** faster ${ore.name} banking for 99 Crafting`);
+ }
+
+ let miningCapeEffect = 0;
+ if (gearBank.hasEquippedOrInBank([itemID('Mining cape')]) && miningCapeOreEffect[ore.name]) {
+ miningCapeEffect = miningCapeOreEffect[ore.name];
+ if (miningCapeEffect) {
+ boosts.push(`**${miningCapeEffect}%** chance to mine an extra ore using Mining cape`);
+ }
+ }
+
+ if (ore.bankingTime === 0) {
+ isPowermining = false;
+ } else {
+ boosts.push('**Powermining**');
+ }
+
+ // Calculate the time it takes to mine specific quantity or as many as possible
+ const [timeToMine, newQuantity] = determineMiningTime({
+ quantity: quantityInput,
+ gearBank,
+ ore,
+ ticksBetweenRolls: currentPickaxe.ticksBetweenRolls,
+ glovesRate,
+ armourEffect,
+ miningCapeEffect,
+ powermining: isPowermining,
+ goldSilverBoost,
+ miningLvl: miningLevel,
+ maxTripLength
+ });
+
+ const duration = timeToMine;
+
+ const fakeDurationMin = quantityInput ? randomVariation(reduceNumByPercent(duration, 25), 20) : duration;
+ const fakeDurationMax = quantityInput ? randomVariation(increaseNumByPercent(duration, 25), 20) : duration;
+
+ if (ore.name === 'Gem rock' && gearBank.hasEquipped('Amulet of glory')) {
+ boosts.push('3x success rate for having an Amulet of glory equipped');
+ }
+
+ if (Number.isNaN(newQuantity) || newQuantity < 1) {
+ throw new Error(`Invalid quantity ${newQuantity} for mining ${ore.name}`);
+ }
+
+ return {
+ duration,
+ quantity: newQuantity,
+ boosts,
+ fakeDurationMin,
+ fakeDurationMax,
+ isPowermining
+ };
+}
+
export const mineCommand: OSBMahojiCommand = {
name: 'mine',
description: 'Send your minion to mine things.',
@@ -58,7 +179,7 @@ export const mineCommand: OSBMahojiCommand = {
channelID
}: CommandRunOptions<{ name: string; quantity?: number; powermine?: boolean }>) => {
const user = await mUserFetch(userID);
- let { quantity, powermine } = options;
+ const { quantity, powermine } = options;
const motherlodeMine =
stringMatches(Mining.MotherlodeMine.name, options.name) ||
@@ -95,107 +216,24 @@ export const mineCommand: OSBMahojiCommand = {
}
}
- const boosts = [];
- // Invisible mining level, dosen't help equip pickaxe etc
- let miningLevel = user.skillsAsLevels.mining;
- if (ore.minerals && miningLevel >= 60) {
- boosts.push('+7 invisible Mining lvls at the Mining guild');
- miningLevel += 7;
- }
- // Checks if user own Celestial ring or Celestial signet
- if (user.hasEquippedOrInBank(['Celestial ring (uncharged)'])) {
- boosts.push('+4 invisible Mining lvls for Celestial ring');
- miningLevel += 4;
- }
- // Default bronze pickaxe, last in the array
- let currentPickaxe = pickaxes[pickaxes.length - 1];
- boosts.push(
- `**${currentPickaxe.ticksBetweenRolls}** ticks between rolls for ${itemNameFromID(currentPickaxe.id)}`
- );
-
- // For each pickaxe, if they have it, give them its' bonus and break.
- for (const pickaxe of pickaxes) {
- if (!user.hasEquippedOrInBank([pickaxe.id]) || user.skillsAsLevels.mining < pickaxe.miningLvl) continue;
- currentPickaxe = pickaxe;
- boosts.pop();
- boosts.push(`**${pickaxe.ticksBetweenRolls}** ticks between rolls for ${itemNameFromID(pickaxe.id)}`);
- break;
- }
-
- let glovesRate = 0;
- if (user.skillsAsLevels.mining >= 60) {
- for (const glove of miningGloves) {
- if (!user.hasEquipped(glove.id) || !glove.Percentages[ore.name]) continue;
- glovesRate = glove.Percentages[ore.name];
- if (glovesRate) {
- boosts.push(`Lowered rock depletion rate by **${glovesRate}%** for ${itemNameFromID(glove.id)}`);
- break;
- }
- }
- }
-
- let armourEffect = 0;
- for (const armour of varrockArmours) {
- if (!user.hasEquippedOrInBank(armour.id) || !armour.Percentages[ore.name]) continue;
- armourEffect = armour.Percentages[ore.name];
- if (armourEffect) {
- boosts.push(`**${armourEffect}%** chance to mine an extra ore using ${itemNameFromID(armour.id)}`);
- break;
- }
- }
-
- let goldSilverBoost = false;
- if (user.skillsAsLevels.crafting >= 99 && (ore.name === 'Gold ore' || ore.name === 'Silver ore')) {
- goldSilverBoost = true;
- boosts.push(`**70%** faster ${ore.name} banking for 99 Crafting`);
- }
-
- let miningCapeEffect = 0;
- if (user.hasEquippedOrInBank([itemID('Mining cape')]) && miningCapeOreEffect[ore.name]) {
- miningCapeEffect = miningCapeOreEffect[ore.name];
- if (miningCapeEffect) {
- boosts.push(`**${miningCapeEffect}%** chance to mine an extra ore using Mining cape`);
- }
- }
-
- if (!powermine || ore.bankingTime === 0) {
- powermine = false;
- } else {
- boosts.push('**Powermining**');
- }
- // Calculate the time it takes to mine specific quantity or as many as possible
- const [timeToMine, newQuantity] = determineMiningTime({
- quantity,
- user,
+ const res = determineMiningTrip({
+ gearBank: user.gearBank,
ore,
- ticksBetweenRolls: currentPickaxe.ticksBetweenRolls,
- glovesRate,
- armourEffect,
- miningCapeEffect,
- powermining: powermine,
- goldSilverBoost,
- miningLvl: miningLevel
+ maxTripLength: calcMaxTripLength(user, 'Mining'),
+ isPowermining: !!powermine,
+ quantityInput: quantity
});
- const duration = timeToMine;
-
- const fakeDurationMin = quantity ? randomVariation(reduceNumByPercent(duration, 25), 20) : duration;
- const fakeDurationMax = quantity ? randomVariation(increaseNumByPercent(duration, 25), 20) : duration;
-
- if (ore.name === 'Gem rock' && user.hasEquipped('Amulet of glory')) {
- boosts.push('3x success rate for having an Amulet of glory equipped');
- }
-
await addSubTaskToActivityTask({
oreID: ore.id,
userID: userID.toString(),
channelID: channelID.toString(),
- quantity: newQuantity,
+ quantity: res.quantity,
iQty: options.quantity ? options.quantity : undefined,
- powermine,
- duration,
- fakeDurationMax,
- fakeDurationMin,
+ powermine: res.isPowermining,
+ duration: res.duration,
+ fakeDurationMax: res.fakeDurationMax,
+ fakeDurationMin: res.fakeDurationMin,
type: 'Mining'
});
@@ -203,12 +241,12 @@ export const mineCommand: OSBMahojiCommand = {
quantity ? `mined ${quantity}x or gets tired` : 'is satisfied'
}, it'll take ${
quantity
- ? `between ${formatDuration(fakeDurationMin)} **and** ${formatDuration(fakeDurationMax)}`
- : formatDuration(duration)
+ ? `between ${formatDuration(res.fakeDurationMin)} **and** ${formatDuration(res.fakeDurationMax)}`
+ : formatDuration(res.duration)
} to finish.`;
- if (boosts.length > 0) {
- response += `\n\n**Boosts:** ${boosts.join(', ')}.`;
+ if (res.boosts.length > 0) {
+ response += `\n\n**Boosts:** ${res.boosts.join(', ')}.`;
}
return response;
diff --git a/src/mahoji/lib/abstracted_commands/camdozaalCommand.ts b/src/mahoji/lib/abstracted_commands/camdozaalCommand.ts
index 5d6a720a47..f735502e1d 100644
--- a/src/mahoji/lib/abstracted_commands/camdozaalCommand.ts
+++ b/src/mahoji/lib/abstracted_commands/camdozaalCommand.ts
@@ -47,7 +47,7 @@ async function miningCommand(user: MUser, channelID: string, quantity: number |
// Calculate the time it takes to mine specific quantity or as many as possible
const [duration, newQuantity] = determineMiningTime({
quantity,
- user,
+ gearBank: user.gearBank,
ore: barroniteRocks,
ticksBetweenRolls: currentPickaxe.ticksBetweenRolls,
glovesRate,
@@ -55,7 +55,8 @@ async function miningCommand(user: MUser, channelID: string, quantity: number |
miningCapeEffect,
powermining: powermine,
goldSilverBoost,
- miningLvl: miningLevel
+ miningLvl: miningLevel,
+ maxTripLength: calcMaxTripLength(user, 'CamdozaalMining')
});
const fakeDurationMin = quantity ? randomVariation(reduceNumByPercent(duration, 25), 20) : duration;
diff --git a/src/mahoji/lib/abstracted_commands/motherlodeMineCommand.ts b/src/mahoji/lib/abstracted_commands/motherlodeMineCommand.ts
index 7883c01ff5..7d3d99e431 100644
--- a/src/mahoji/lib/abstracted_commands/motherlodeMineCommand.ts
+++ b/src/mahoji/lib/abstracted_commands/motherlodeMineCommand.ts
@@ -7,6 +7,7 @@ import Mining from '../../../lib/skilling/skills/mining';
import type { MotherlodeMiningActivityTaskOptions } from '../../../lib/types/minions';
import { formatDuration, itemNameFromID } from '../../../lib/util';
import addSubTaskToActivityTask from '../../../lib/util/addSubTaskToActivityTask';
+import { calcMaxTripLength } from '../../../lib/util/calcMaxTripLength';
import { minionName } from '../../../lib/util/minionUtils';
export async function motherlodeMineCommand({
@@ -63,7 +64,7 @@ export async function motherlodeMineCommand({
// Calculate the time it takes to mine specific quantity or as many as possible
const [duration, newQuantity] = determineMiningTime({
quantity,
- user,
+ gearBank: user.gearBank,
ore: motherlode,
ticksBetweenRolls: currentPickaxe.ticksBetweenRolls,
glovesRate,
@@ -71,7 +72,8 @@ export async function motherlodeMineCommand({
miningCapeEffect,
powermining: powermine,
goldSilverBoost,
- miningLvl: miningLevel
+ miningLvl: miningLevel,
+ maxTripLength: calcMaxTripLength(user, 'MotherlodeMining')
});
const fakeDurationMin = quantity ? randomVariation(reduceNumByPercent(duration, 25), 20) : duration;
diff --git a/src/mahoji/lib/abstracted_commands/shootingStarsCommand.ts b/src/mahoji/lib/abstracted_commands/shootingStarsCommand.ts
index 38d48d13a0..93c38493b2 100644
--- a/src/mahoji/lib/abstracted_commands/shootingStarsCommand.ts
+++ b/src/mahoji/lib/abstracted_commands/shootingStarsCommand.ts
@@ -206,7 +206,7 @@ export async function shootingStarsCommand(channelID: string, user: MUserClass,
for (const star of stars) {
const [timeToMine, newQuantity] = determineMiningTime({
quantity: Math.round(star.dustAvailable / usersWith),
- user,
+ gearBank: user.gearBank,
ore: star,
ticksBetweenRolls: currentPickaxe.ticksBetweenRolls,
glovesRate: 0,
@@ -215,7 +215,8 @@ export async function shootingStarsCommand(channelID: string, user: MUserClass,
powermining: false,
goldSilverBoost: false,
miningLvl: miningLevel,
- passedDuration: duration
+ passedDuration: duration,
+ maxTripLength: calcMaxTripLength(user, 'ShootingStars')
});
duration += timeToMine;
dustReceived += newQuantity;
diff --git a/src/tasks/minions/miningActivity.ts b/src/tasks/minions/miningActivity.ts
index 141ac8fbc6..7d765e222b 100644
--- a/src/tasks/minions/miningActivity.ts
+++ b/src/tasks/minions/miningActivity.ts
@@ -1,143 +1,146 @@
-import { Time, randInt, roll } from 'e';
-import { Bank } from 'oldschooljs';
+import { Time, increaseNumByPercent, randInt, roll, sumArr } from 'e';
import { Emoji, Events } from '../../lib/constants';
import addSkillingClueToLoot from '../../lib/minions/functions/addSkillingClueToLoot';
-import Mining from '../../lib/skilling/skills/mining';
-import { SkillsEnum } from '../../lib/skilling/types';
+import Mining, { prospectorItemsArr } from '../../lib/skilling/skills/mining';
+import { type Ore, SkillsEnum } from '../../lib/skilling/types';
+import type { GearBank } from '../../lib/structures/GearBank';
+import { UpdateBank } from '../../lib/structures/UpdateBank';
import type { MiningActivityTaskOptions } from '../../lib/types/minions';
import { skillingPetDropRate } from '../../lib/util';
import { handleTripFinish } from '../../lib/util/handleTripFinish';
-export const miningTask: MinionTask = {
- type: 'Mining',
- async run(data: MiningActivityTaskOptions) {
- const { oreID, userID, channelID, duration, powermine } = data;
- const { quantity } = data;
- const user = await mUserFetch(userID);
- const ore = Mining.Ores.find(ore => ore.id === oreID)!;
+export function determineMiningResult({
+ ore,
+ quantity,
+ gearBank,
+ duration,
+ isPowermining
+}: { ore: Ore; quantity: number; gearBank: GearBank; duration: number; isPowermining: boolean }) {
+ const miningLvl = gearBank.skillsAsLevels.mining;
+ const messages: string[] = [];
+ let xpToReceive = quantity * ore.xp;
+
+ const equippedProsItems = prospectorItemsArr.filter(item => gearBank.hasEquipped(item.id));
+ const bonusPercent =
+ equippedProsItems.length === 4 ? 2.5 : sumArr(equippedProsItems.map(item => item.boostPercent));
+ if (bonusPercent > 0) {
+ const newXP = Math.floor(increaseNumByPercent(xpToReceive, bonusPercent));
+ messages.push(`${bonusPercent}% (${newXP - xpToReceive}) XP for prospector`);
+ xpToReceive = newXP;
+ }
- let xpReceived = quantity * ore.xp;
- let bonusXP = 0;
-
- // If they have the entire prospector outfit, give an extra 0.5% xp bonus
- if (
- user.gear.skilling.hasEquipped(
- Object.keys(Mining.prospectorItems).map(i => Number.parseInt(i)),
- true
- )
- ) {
- const amountToAdd = Math.floor(xpReceived * (2.5 / 100));
- xpReceived += amountToAdd;
- bonusXP += amountToAdd;
- } else {
- // For each prospector item, check if they have it, give its' XP boost if so.
- for (const [itemID, bonus] of Object.entries(Mining.prospectorItems)) {
- if (user.hasEquipped(Number.parseInt(itemID))) {
- const amountToAdd = Math.floor(xpReceived * (bonus / 100));
- xpReceived += amountToAdd;
- bonusXP += amountToAdd;
- }
- }
- }
- const currentLevel = user.skillLevel(SkillsEnum.Mining);
- const xpRes = await user.addXP({
- skillName: SkillsEnum.Mining,
- amount: xpReceived,
- duration
- });
+ const updateBank = new UpdateBank();
+ if (ore.xp) {
+ updateBank.xpBank.add('mining', xpToReceive, { duration });
+ }
+
+ // Add clue scrolls
+ if (ore.clueScrollChance) {
+ addSkillingClueToLoot(gearBank, SkillsEnum.Mining, quantity, ore.clueScrollChance, updateBank.itemLootBank);
+ }
- let str = `${user}, ${user.minionName} finished mining ${quantity} ${ore.name}. ${xpRes}`;
+ // Roll for pet
+ if (ore.petChance) {
+ const { petDropRate } = skillingPetDropRate(gearBank, SkillsEnum.Mining, ore.petChance);
+ if (roll(petDropRate / quantity)) {
+ updateBank.itemLootBank.add('Rock golem');
+ messages.push("You have a funny feeling you're being followed...");
+ }
+ }
- const loot = new Bank();
+ const numberOfMinutes = duration / Time.Minute;
- // Add clue scrolls
- if (ore.clueScrollChance) {
- addSkillingClueToLoot(user, SkillsEnum.Mining, quantity, ore.clueScrollChance, loot);
+ if (numberOfMinutes > 10 && ore.minerals && miningLvl >= 60) {
+ let numberOfMinerals = 0;
+ for (let i = 0; i < quantity; i++) {
+ if (roll(ore.minerals)) numberOfMinerals++;
}
- // Roll for pet
- if (ore.petChance) {
- const { petDropRate } = skillingPetDropRate(user, SkillsEnum.Mining, ore.petChance);
- if (roll(petDropRate / quantity)) {
- loot.add('Rock golem');
- str += "\nYou have a funny feeling you're being followed...";
- globalClient.emit(
- Events.ServerNotification,
- `${Emoji.Mining} **${user.badgedUsername}'s** minion, ${user.minionName}, just received a Rock golem while mining ${ore.name} at level ${currentLevel} Mining!`
- );
- }
+ if (numberOfMinerals > 0) {
+ updateBank.itemLootBank.add('Unidentified minerals', numberOfMinerals);
}
+ }
- const numberOfMinutes = duration / Time.Minute;
+ let daeyaltQty = 0;
- if (numberOfMinutes > 10 && ore.minerals && user.skillLevel(SkillsEnum.Mining) >= 60) {
- let numberOfMinerals = 0;
+ if (!isPowermining) {
+ // Gem rocks roll off the GemRockTable
+ if (ore.name === 'Gem rock') {
for (let i = 0; i < quantity; i++) {
- if (roll(ore.minerals)) numberOfMinerals++;
+ updateBank.itemLootBank.add(Mining.GemRockTable.roll());
}
-
- if (numberOfMinerals > 0) {
- loot.add('Unidentified minerals', numberOfMinerals);
+ } else if (ore.name === 'Volcanic ash') {
+ // Volcanic ash
+ const tiers = [
+ [22, 1],
+ [37, 2],
+ [52, 3],
+ [67, 4],
+ [82, 5],
+ [97, 6]
+ ];
+ for (const [lvl, multiplier] of tiers.reverse()) {
+ if (miningLvl >= lvl) {
+ updateBank.itemLootBank.add(ore.id, quantity * multiplier);
+ break;
+ }
+ }
+ } else if (ore.name === 'Sandstone') {
+ // Sandstone roll off the SandstoneRockTable
+ for (let i = 0; i < quantity; i++) {
+ updateBank.itemLootBank.add(Mining.SandstoneRockTable.roll());
}
+ } else if (ore.name === 'Granite') {
+ // Granite roll off the GraniteRockTable
+ for (let i = 0; i < quantity; i++) {
+ updateBank.itemLootBank.add(Mining.GraniteRockTable.roll());
+ }
+ } else if (ore.name === 'Daeyalt essence rock') {
+ for (let i = 0; i < quantity; i++) {
+ daeyaltQty += randInt(2, 3);
+ }
+ updateBank.itemLootBank.add(ore.id, daeyaltQty);
+ } else {
+ updateBank.itemLootBank.add(ore.id, quantity);
}
+ }
- let daeyaltQty = 0;
+ return {
+ updateBank,
+ messages
+ };
+}
- if (!powermine) {
- // Gem rocks roll off the GemRockTable
- if (ore.name === 'Gem rock') {
- for (let i = 0; i < quantity; i++) {
- loot.add(Mining.GemRockTable.roll());
- }
- } else if (ore.name === 'Volcanic ash') {
- // Volcanic ash
- const userLevel = user.skillLevel(SkillsEnum.Mining);
- const tiers = [
- [22, 1],
- [37, 2],
- [52, 3],
- [67, 4],
- [82, 5],
- [97, 6]
- ];
- for (const [lvl, multiplier] of tiers.reverse()) {
- if (userLevel >= lvl) {
- loot.add(ore.id, quantity * multiplier);
- break;
- }
- }
- } else if (ore.name === 'Sandstone') {
- // Sandstone roll off the SandstoneRockTable
- for (let i = 0; i < quantity; i++) {
- loot.add(Mining.SandstoneRockTable.roll());
- }
- } else if (ore.name === 'Granite') {
- // Granite roll off the GraniteRockTable
- for (let i = 0; i < quantity; i++) {
- loot.add(Mining.GraniteRockTable.roll());
- }
- } else if (ore.name === 'Daeyalt essence rock') {
- for (let i = 0; i < quantity; i++) {
- daeyaltQty += randInt(2, 3);
- }
- loot.add(ore.id, daeyaltQty);
- } else {
- loot.add(ore.id, quantity);
- }
- }
+export const miningTask: MinionTask = {
+ type: 'Mining',
+ async run(data: MiningActivityTaskOptions) {
+ const { oreID, userID, channelID, duration, powermine } = data;
+ const { quantity } = data;
+ const user = await mUserFetch(userID);
+ const ore = Mining.Ores.find(ore => ore.id === oreID)!;
- str += `\n\nYou received: ${loot}.`;
- if (bonusXP > 0) {
- str += `\n\n**Bonus XP:** ${bonusXP.toLocaleString()}`;
+ const { updateBank, messages } = determineMiningResult({
+ ore,
+ quantity,
+ gearBank: user.gearBank,
+ duration,
+ isPowermining: powermine
+ });
+ const updateResult = await updateBank.transact(user);
+ if (typeof updateResult === 'string') throw new Error(updateResult);
+ let str = `${user}, ${user.minionName} finished mining ${quantity} ${ore.name}. You received ${updateResult.itemTransactionResult?.itemsAdded} and ${updateBank.xpBank}.`;
+ if (messages.length > 0) {
+ str += `\n${messages.join(', ')}.`;
}
- await transactItems({
- userID: user.id,
- collectionLog: true,
- itemsToAdd: loot
- });
+ if (updateBank.itemLootBank.has('Rock golem')) {
+ globalClient.emit(
+ Events.ServerNotification,
+ `${Emoji.Mining} **${user.badgedUsername}'s** minion, ${user.minionName}, just received a Rock golem while mining ${ore.name} at level ${user.skillsAsLevels.mining} Mining!`
+ );
+ }
- handleTripFinish(user, channelID, str, undefined, data, loot);
+ handleTripFinish(user, channelID, str, undefined, data, updateResult.itemTransactionResult?.itemsAdded ?? null);
}
};
diff --git a/tests/unit/utils.ts b/tests/unit/utils.ts
index fa86797109..87c9a810dd 100644
--- a/tests/unit/utils.ts
+++ b/tests/unit/utils.ts
@@ -28,7 +28,8 @@ export function makeGearBank({ bank }: { bank?: Bank } = {}) {
gear: makeFullGear(),
bank: bank ?? new Bank(),
skillsAsLevels: makeSkillsAsLevels(),
- chargeBank: new ChargeBank()
+ chargeBank: new ChargeBank(),
+ skillsAsXP: makeSkillsAsLevels(13034431)
});
}
|