Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Crystal Impling Hunting #5771

Merged
merged 13 commits into from
Apr 25, 2024
26 changes: 24 additions & 2 deletions src/lib/skilling/functions/calcsHunter.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Time } from 'e';
import LootTable from 'oldschooljs/dist/structures/LootTable';

import { percentChance } from '../../util';
Expand All @@ -6,12 +7,33 @@ import { Creature } from '../types';
export function calcLootXPHunting(
currentLevel: number,
creature: Creature,
quantity: number
quantity: number,
usingStaminaPotion: boolean,
graceful: boolean,
experienceScore: number
): [number, number, number] {
let xpReceived = 0;
let successful = 0;

const chanceOfSuccess = creature.slope * currentLevel + creature.intercept;
let chanceOfSuccess = creature.slope * currentLevel + creature.intercept;

if (creature.name === 'Crystal impling') {
chanceOfSuccess = 20;
if (graceful) {
chanceOfSuccess *= 1.05;
}
if (usingStaminaPotion) {
chanceOfSuccess *= 1.2;
}

const timeInSeconds = creature.catchTime * Time.Second;
const experienceFactor = experienceScore / (Time.Hour / timeInSeconds);

const maxPercentIncrease = 10;
let percentIncrease = Math.min(Math.floor(experienceFactor), maxPercentIncrease);

chanceOfSuccess += chanceOfSuccess * (percentIncrease / 100);
}

for (let i = 0; i < quantity; i++) {
if (!percentChance(chanceOfSuccess)) {
Expand Down
12 changes: 12 additions & 0 deletions src/lib/skilling/skills/hunter/creatures/butterflyNetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ const butterflyNettingCreatures: Creature[] = [
catchTime: 5,
slope: 1.35,
intercept: 35
},
{
name: 'Crystal impling',
id: 37,
aliases: ['cimp', 'crystal imp', 'c imp', 'crystal impling'],
level: 80,
hunterXP: 280,
table: new LootTable().every('Crystal impling jar'),
huntTechnique: HunterTechniqueEnum.ButterflyNetting,
catchTime: 180,
slope: 0,
intercept: 0
}
];

Expand Down
7 changes: 7 additions & 0 deletions src/lib/util/activityInArea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import {
ActivityTaskData,
AgilityActivityTaskOptions,
HunterActivityTaskOptions,
MonsterActivityTaskOptions,
PickpocketActivityTaskOptions
} from '../types/minions';

export const enum WorldLocations {

Check warning on line 11 in src/lib/util/activityInArea.ts

View workflow job for this annotation

GitHub Actions / Node v18.12.0 - ubuntu-latest

'WorldLocations' is already declared in the upper scope on line 11 column 19

Check warning on line 11 in src/lib/util/activityInArea.ts

View workflow job for this annotation

GitHub Actions / Node v20 - ubuntu-latest

'WorldLocations' is already declared in the upper scope on line 11 column 19
Priffdinas,
World
}
Expand Down Expand Up @@ -37,6 +38,12 @@
) {
return true;
}
if (
activity.type === 'Hunter' &&
(activity as HunterActivityTaskOptions).creatureName === 'Crystal impling'
) {
return true;
}

return false;
}
Expand Down
37 changes: 30 additions & 7 deletions src/mahoji/commands/hunt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
import { HERBIBOAR_ID, RAZOR_KEBBIT_ID } from '../../lib/constants';
import { hasWildyHuntGearEquipped } from '../../lib/gear/functions/hasWildyHuntGearEquipped';
import { trackLoot } from '../../lib/lootTrack';
import { soteSkillRequirements } from '../../lib/skilling/functions/questRequirements';
import creatures from '../../lib/skilling/skills/hunter/creatures';
import Hunter from '../../lib/skilling/skills/hunter/hunter';
import { HunterTechniqueEnum, SkillsEnum } from '../../lib/skilling/types';
import { Peak } from '../../lib/tickers';
import { HunterActivityTaskOptions } from '../../lib/types/minions';
import { formatDuration, itemID } from '../../lib/util';
import { formatDuration, hasSkillReqs, itemID } from '../../lib/util';
import addSubTaskToActivityTask from '../../lib/util/addSubTaskToActivityTask';
import { calcMaxTripLength } from '../../lib/util/calcMaxTripLength';
import { updateBankSetting } from '../../lib/util/updateBankSetting';
Expand All @@ -34,7 +35,7 @@
required: true,
autocomplete: async (value: string) => {
return creatures
.filter(i => (!value ? true : i.name.toLowerCase().includes(value.toLowerCase())))

Check warning on line 38 in src/mahoji/commands/hunt.ts

View workflow job for this annotation

GitHub Actions / Node v18.12.0 - ubuntu-latest

Unexpected string value in conditional. An explicit empty string check is required

Check warning on line 38 in src/mahoji/commands/hunt.ts

View workflow job for this annotation

GitHub Actions / Node v20 - ubuntu-latest

Unexpected string value in conditional. An explicit empty string check is required
.map(i => ({
name: i.name,
value: i.name
Expand Down Expand Up @@ -80,7 +81,7 @@

let usingStaminaPotion = Boolean(options.stamina_potions);

const creature = Hunter.Creatures.find(creature =>

Check warning on line 84 in src/mahoji/commands/hunt.ts

View workflow job for this annotation

GitHub Actions / Node v18.12.0 - ubuntu-latest

'creature' is already declared in the upper scope on line 84 column 9

Check warning on line 84 in src/mahoji/commands/hunt.ts

View workflow job for this annotation

GitHub Actions / Node v20 - ubuntu-latest

'creature' is already declared in the upper scope on line 84 column 9
creature.aliases.some(
alias => stringMatches(alias, options.name) || stringMatches(alias.split(' ')[0], options.name)
)
Expand Down Expand Up @@ -118,6 +119,18 @@
}
}

let crystalImpling = creature.name === 'Crystal impling';

if (crystalImpling) {
const [hasReqs, reason] = hasSkillReqs(user, soteSkillRequirements);
if (!hasReqs) {
return `To hunt ${creature.name}, you need: ${reason}.`;
}
if (user.QP < 150) {
return `To hunt ${creature.name}, you need 150 QP.`;
}
}

// Reduce time if user is experienced hunting the creature, every hour become 1% better to a cap of 10% or 20% if tracking technique.
let [percentReduced, catchTime] = [
Math.min(
Expand Down Expand Up @@ -158,10 +171,20 @@
const maxTripLength = calcMaxTripLength(user, 'Hunter');

let { quantity } = options;
if (!quantity) quantity = Math.floor(maxTripLength / ((catchTime * Time.Second) / traps));
if (!quantity) {
if (crystalImpling) {
quantity = Math.floor(maxTripLength / Time.Minute);
} else {
quantity = Math.floor(maxTripLength / ((catchTime * Time.Second) / traps));
}
}

let duration = Math.floor(((quantity * catchTime) / traps) * Time.Second);

if (crystalImpling) {
duration = Math.floor(quantity * Time.Minute);
}

if (duration > maxTripLength) {
return `${user.minionName} can't go on trips longer than ${formatDuration(
maxTripLength
Expand All @@ -188,9 +211,9 @@

// If creatures Herbiboar or Razor-backed kebbit use Stamina potion(4)
if (usingStaminaPotion) {
if (creature.id === HERBIBOAR_ID || creature.id === RAZOR_KEBBIT_ID) {
if (creature.id === HERBIBOAR_ID || creature.id === RAZOR_KEBBIT_ID || crystalImpling) {
let staminaPotionQuantity =
creature.id === HERBIBOAR_ID
creature.id === HERBIBOAR_ID || crystalImpling
? Math.round(duration / (9 * Time.Minute))
: Math.round(duration / (18 * Time.Minute));

Expand All @@ -211,7 +234,7 @@
boosts.push(`+2 hunter level for using ${hunterPotionQuantity}x Hunter potion(4) every 2nd minute.`);
}

updateBankSetting('hunter_cost', removeBank);

Check warning on line 237 in src/mahoji/commands/hunt.ts

View workflow job for this annotation

GitHub Actions / Node v18.12.0 - ubuntu-latest

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 237 in src/mahoji/commands/hunt.ts

View workflow job for this annotation

GitHub Actions / Node v20 - ubuntu-latest

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
await user.removeItemsFromBank(removeBank);

let wildyPeak = null;
Expand Down Expand Up @@ -256,9 +279,9 @@
type: 'Hunter'
});

let response = `${user.minionName} is now ${creature.huntTechnique} ${quantity}x ${
creature.name
}, it'll take around ${formatDuration(duration)} to finish.`;
let response = `${user.minionName} is now ${crystalImpling ? 'hunting' : `${creature.huntTechnique}`} ${
crystalImpling ? '' : ` ${quantity}x `
}${creature.name}, it'll take around ${formatDuration(duration)} to finish.`;

if (boosts.length > 0) {
response += `\n\n**Boosts:** ${boosts.join(', ')}.`;
Expand Down
38 changes: 29 additions & 9 deletions src/tasks/minions/HunterActivity/hunterActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import { handleTripFinish } from '../../../lib/util/handleTripFinish';
import itemID from '../../../lib/util/itemID';
import { updateBankSetting } from '../../../lib/util/updateBankSetting';
import { userHasGracefulEquipped } from '../../../mahoji/mahojiSettings';
import { BLACK_CHIN_ID, HERBIBOAR_ID } from './../../../lib/constants';

const riskDeathNumbers = [
Expand All @@ -34,7 +35,8 @@
export const hunterTask: MinionTask = {
type: 'Hunter',
async run(data: HunterActivityTaskOptions) {
const { creatureName, quantity, userID, channelID, usingHuntPotion, wildyPeak, duration } = data;
const { creatureName, quantity, userID, channelID, usingHuntPotion, wildyPeak, duration, usingStaminaPotion } =
data;
const user = await mUserFetch(userID);
const userBank = user.bank;
const currentLevel = user.skillLevel(SkillsEnum.Hunter);
Expand All @@ -45,7 +47,7 @@
let pkStr = '';
let pkedQuantity = 0;

const creature = Hunter.Creatures.find(creature =>

Check warning on line 50 in src/tasks/minions/HunterActivity/hunterActivity.ts

View workflow job for this annotation

GitHub Actions / Node v18.12.0 - ubuntu-latest

'creature' is already declared in the upper scope on line 50 column 9

Check warning on line 50 in src/tasks/minions/HunterActivity/hunterActivity.ts

View workflow job for this annotation

GitHub Actions / Node v20 - ubuntu-latest

'creature' is already declared in the upper scope on line 50 column 9
creature.aliases.some(
alias => stringMatches(alias, creatureName) || stringMatches(alias.split(' ')[0], creatureName)
)
Expand All @@ -53,12 +55,29 @@

if (!creature) return;

let crystalImpling = creature.name === 'Crystal impling';

let graceful = false;
if (userHasGracefulEquipped(user)) {
graceful = true;
}

const experienceScore = await user.getCreatureScore(creature.id);

let [successfulQuantity, xpReceived] = calcLootXPHunting(
Math.min(Math.floor(currentLevel + (usingHuntPotion ? 2 : 0)), MAX_LEVEL),
creature,
quantity
quantity,
usingStaminaPotion,
graceful,
experienceScore
);

if (crystalImpling) {
// Limit it to a max of 22 crystal implings per hour
successfulQuantity = Math.min(successfulQuantity, Math.round((21 / 60) * duration) + 1);
}

if (creature.wildy) {
let riskPkChance = creature.id === BLACK_CHIN_ID ? 100 : 200;
riskPkChance +=
Expand Down Expand Up @@ -136,6 +155,7 @@
});
}
}

const loot = new Bank();
for (let i = 0; i < successfulQuantity - pkedQuantity; i++) {
loot.add(creatureTable.roll());
Expand All @@ -156,13 +176,13 @@
duration
});

let str = `${user}, ${user.minionName} finished hunting ${
creature.name
} ${quantity}x times, due to clever creatures you missed out on ${
quantity - successfulQuantity
}x catches. ${xpStr}`;

str += `\n\nYou received: ${loot}.${magicSecStr.length > 1 ? magicSecStr : ''}`;
let str = `${user}, ${user.minionName} finished hunting ${creature.name}${
crystalImpling
? '.'
: `${quantity}x times, due to clever creatures you missed out on ${
quantity - successfulQuantity
}x catches. `
}${xpStr}\n\nYou received: ${loot}.${magicSecStr.length > 1 ? magicSecStr : ''}`;

if (gotPked && !died) {
str += `\n${pkStr}`;
Expand All @@ -184,7 +204,7 @@
);
}

updateBankSetting('hunter_loot', loot);

Check warning on line 207 in src/tasks/minions/HunterActivity/hunterActivity.ts

View workflow job for this annotation

GitHub Actions / Node v18.12.0 - ubuntu-latest

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 207 in src/tasks/minions/HunterActivity/hunterActivity.ts

View workflow job for this annotation

GitHub Actions / Node v20 - ubuntu-latest

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
await trackLoot({
id: creature.name,
changeType: 'loot',
Expand All @@ -201,6 +221,6 @@
]
});

handleTripFinish(user, channelID, str, undefined, data, loot);

Check warning on line 224 in src/tasks/minions/HunterActivity/hunterActivity.ts

View workflow job for this annotation

GitHub Actions / Node v18.12.0 - ubuntu-latest

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator

Check warning on line 224 in src/tasks/minions/HunterActivity/hunterActivity.ts

View workflow job for this annotation

GitHub Actions / Node v20 - ubuntu-latest

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
}
};
Loading