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 destroy option for Araxxor #6260

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,12 @@ const AraxxorTable = new LootTable()
.add('Bark', 15, 1)
.add(RareDropTable);

const sacrificedTable = new LootTable().tertiary(50, 'Clue scroll (elite)').tertiary(1500, 'Nid');

export const Araxxor = new SimpleMonster({
id: 13668,
name: 'Araxxor',
table: AraxxorTable,
sacrificedTable,
aliases: ['araxxor']
});
1 change: 1 addition & 0 deletions packages/oldschooljs/src/structures/LootTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export interface LootTableRollOptions {
*/
tertiaryItemPercentageChanges?: Map<string, number>;
targetBank?: Bank;
sacrificeLoot?: boolean;
}

export default class LootTable {
Expand Down
12 changes: 9 additions & 3 deletions packages/oldschooljs/src/structures/SimpleMonster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Monster from './Monster';

interface SimpleMonsterOptions extends MonsterOptions {
table?: LootTable;
sacrificedTable?: LootTable;
onTaskTable?: LootTable;
wildyCaveTable?: LootTable;
pickpocketTable?: LootTable;
Expand All @@ -23,6 +24,7 @@ interface SimpleMonsterOptions extends MonsterOptions {

export default class SimpleMonster extends Monster {
public table?: LootTable;
public sacrificedTable?: LootTable;
public onTaskTable?: LootTable;
public wildyCaveTable?: LootTable;
public pickpocketTable?: LootTable;
Expand All @@ -40,6 +42,7 @@ export default class SimpleMonster extends Monster {
this.table = options.table;
this.pickpocketTable = options.pickpocketTable;
this.onTaskTable = options.onTaskTable;
this.sacrificedTable = options.sacrificedTable;
this.wildyCaveTable = options.wildyCaveTable;
this.customKillLogic = options.customKillLogic;
}
Expand All @@ -56,8 +59,11 @@ export default class SimpleMonster extends Monster {
targetBank: loot
};

const rollTable =
this.sacrificedTable && options.lootTableOptions?.sacrificeLoot ? this.sacrificedTable : this.table;

if (!canGetBrimKey && !wildySlayer && !options.inCatacombs && !options.onSlayerTask) {
this.table?.roll(quantity, lootTableOptions);
rollTable?.roll(quantity, lootTableOptions);
if (this.customKillLogic) {
for (let i = 0; i < quantity; i++) {
this.customKillLogic(options, loot);
Expand Down Expand Up @@ -98,11 +104,11 @@ export default class SimpleMonster extends Monster {
this.onTaskTable.roll(1, lootTableOptions);
} else {
// Monster doesn't have a unique on-slayer table
this.table?.roll(1, lootTableOptions);
rollTable?.roll(1, lootTableOptions);
}
} else {
// Not on slayer task
this.table?.roll(1, lootTableOptions);
rollTable?.roll(1, lootTableOptions);
}
if (this.customKillLogic) {
this.customKillLogic(options, loot);
Expand Down
9 changes: 8 additions & 1 deletion src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ export enum BitField {
DisableClueButtons = 38,
DisableAutoSlayButton = 39,
DisableHighPeakTimeWarning = 40,
DisableOpenableNames = 41
DisableOpenableNames = 41,
SacrificeLoot = 42
}

interface BitFieldData {
Expand Down Expand Up @@ -361,6 +362,11 @@ export const BitFieldData: Record<BitField, BitFieldData> = {
name: 'Disable Names On Open',
protected: false,
userConfigurable: true
},
[BitField.SacrificeLoot]: {
name: 'Sacrifice loot for extra pet chance, where available',
protected: false,
userConfigurable: true
}
} as const;

Expand Down Expand Up @@ -417,6 +423,7 @@ export const BLACK_CHIN_ID = 9;
export const ZALCANO_ID = 9049;
export const NIGHTMARE_ID = 9415;
export const NEX_ID = 11_278;
export const ARAXXOR_DEAD_ID = 13_669;

export const LEVEL_99_XP = 13_034_431;
export const MAX_LEVEL = 99;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/minions/data/combatConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ export const CombatOptionsArray: CombatOptionsDesc[] = [
}
];

export const combatOptionChoices = CombatOptionsArray.map(o => {
return { name: o.name, value: o.name };
});

export const cannonSingleConsumables: Consumable = {
itemCost: new Bank().add('Cannonball', 1),
qtyPerMinute: 16
Expand Down
2 changes: 2 additions & 0 deletions src/lib/minions/data/killableMonsters/bosses/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Time, roll } from 'e';
import { Bank, Monsters } from 'oldschooljs';

import { deepResolveItems, resolveItems } from 'oldschooljs/dist/util/util';
import { ARAXXOR_DEAD_ID } from '../../../../constants';
import { corporealBeastCL, muspahCL } from '../../../../data/CollectionsExport';
import { GearStat } from '../../../../gear/types';
import { SkillsEnum } from '../../../../skilling/types';
Expand Down Expand Up @@ -596,6 +597,7 @@ const killableBosses: KillableMonster[] = [
difficultyRating: 8,
notifyDrops: resolveItems(['Nid']),
qpRequired: 200,
sacrificeID: ARAXXOR_DEAD_ID,
deathProps: {
hardness: 0.2,
steepness: 0.99
Expand Down
7 changes: 6 additions & 1 deletion src/lib/minions/data/killableMonsters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Time } from 'e';
import { Bank, Monsters } from 'oldschooljs';

import { deepResolveItems, resolveItems } from 'oldschooljs/dist/util/util';
import { NEX_ID, PHOSANI_NIGHTMARE_ID, ZALCANO_ID } from '../../../constants';
import { ARAXXOR_DEAD_ID, NEX_ID, PHOSANI_NIGHTMARE_ID, ZALCANO_ID } from '../../../constants';
import { GearStat } from '../../../gear/types';
import { SkillsEnum } from '../../../skilling/types';
import itemID from '../../../util/itemID';
Expand Down Expand Up @@ -393,6 +393,11 @@ export const effectiveMonsters = [
name: 'Nex',
aliases: ['nex'],
id: NEX_ID
},
{
name: 'Araxxor (destroyed)',
aliases: ['araxxor destroyed'],
id: ARAXXOR_DEAD_ID
}
];

Expand Down
1 change: 1 addition & 0 deletions src/lib/minions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export interface KillableMonster {
deathProps?: Omit<Parameters<typeof calculateSimpleMonsterDeathChance>['0'], 'currentKC'>;
diaryRequirement?: [DiaryID, DiaryTierName];
wildySlayerCave?: boolean;
sacrificeID?: number; // ID to use for incrementing KC for sacrificed loot (e.g. id for dead npc)
}
/*
* Monsters will have an array of Consumables
Expand Down
1 change: 1 addition & 0 deletions src/lib/workers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface KillWorkerArgs {
catacombs?: boolean;
slayerMaster?: MonsterSlayerMaster;
lootTableTertiaryChanges: [string, number][];
sacrificeLoot?: boolean;
}

export type KillWorkerReturn = Promise<{
Expand Down
6 changes: 4 additions & 2 deletions src/lib/workers/kill.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export default async ({
onTask,
slayerMaster,
limit,
lootTableTertiaryChanges
lootTableTertiaryChanges,
sacrificeLoot
}: KillWorkerArgs): KillWorkerReturn => {
const osjsMonster = Monsters.find(mon => mon.aliases.some(alias => stringMatches(alias, bossName)));
if (osjsMonster) {
Expand All @@ -36,7 +37,8 @@ export default async ({
onSlayerTask: onTask,
slayerMaster: slayerMaster,
lootTableOptions: {
tertiaryItemPercentageChanges: new Map(lootTableTertiaryChanges)
tertiaryItemPercentageChanges: new Map(lootTableTertiaryChanges),
sacrificeLoot
}
})
};
Expand Down
25 changes: 22 additions & 3 deletions src/mahoji/commands/kill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,28 @@ export const killCommand: OSBMahojiCommand = {
name: 'master',
description: 'On slayer task from a master?',
required: false,
choices: slayerMasterChoices
choices: slayerMasterChoices.filter(master =>
['Duradel', 'Konar quo Maten', 'Krystilia'].includes(master.name)
)
},
{
type: ApplicationCommandOptionType.Boolean,
name: 'sacrifice',
description: 'Sacrifice loot for pet chance?',
required: false
}
],
run: async ({
options,
userID,
interaction
}: CommandRunOptions<{ name: string; quantity: number; catacombs: boolean; master: string }>) => {
}: CommandRunOptions<{
name: string;
quantity: number;
catacombs: boolean;
master: string;
sacrifice: boolean;
}>) => {
const user = await mUserFetch(userID);
await deferInteraction(interaction);
const result = await Workers.kill({
Expand All @@ -106,13 +120,18 @@ export const killCommand: OSBMahojiCommand = {
user
.buildTertiaryItemChanges(false, options.master === 'Krystilia', options.master !== undefined)
.entries()
)
),
sacrificeLoot: options.sacrifice
});

if (result.error) {
return result.error;
}

const killString = `Simulated loot from killing ${options.quantity} ${options.name}, ${options.master ? `on task (${options.master})` : 'off task'}${options.catacombs ? ', in catacombs' : ''}${options.sacrifice ? ', sacrificing loot' : ''}. `;

result.content = result.content ? result.content : killString;

const image = await makeBankImage({
bank: new Bank(result.bank),
title: result.title ?? `Loot from ${options.quantity.toLocaleString()} ${toTitleCase(options.name)}`,
Expand Down
8 changes: 7 additions & 1 deletion src/mahoji/lib/abstracted_commands/minionKill/minionKill.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ChatInputCommandInteraction, InteractionReplyOptions } from 'discord.js';

import { colosseumCommand } from '../../../../lib/colosseum';
import type { PvMMethod } from '../../../../lib/constants';
import { BitField, type PvMMethod } from '../../../../lib/constants';
import { getCurrentPeak } from '../../../../lib/getCurrentPeak';
import { trackLoot } from '../../../../lib/lootTrack';
import { revenantMonsters } from '../../../../lib/minions/data/killableMonsters/revs';
Expand Down Expand Up @@ -146,6 +146,12 @@ export async function minionKillCommand(
result.duration
)} to finish. Attack styles used: ${result.attackStyles.join(', ')}.`;

if (monster.sacrificeID) {
response += user.bitfield.includes(BitField.SacrificeLoot)
? ' You are sacrificing loot for a higher chance of pet.'
: ' You are not sacrificing, so receive regular loot.';
}

if (result.messages.length > 0) {
response += `\n\n${result.messages.join(', ')}`;
}
Expand Down
22 changes: 17 additions & 5 deletions src/tasks/minions/monsterActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Time, deepClone, percentChance } from 'e';
import type { MonsterKillOptions } from 'oldschooljs';
import { Bank, EMonster, MonsterSlayerMaster, Monsters } from 'oldschooljs';

import { type BitField, Emoji } from '../../lib/constants';
import { ARAXXOR_DEAD_ID, BitField, Emoji } from '../../lib/constants';
import { userhasDiaryTierSync } from '../../lib/diaries';
import { trackLoot } from '../../lib/lootTrack';
import killableMonsters from '../../lib/minions/data/killableMonsters';
Expand Down Expand Up @@ -164,7 +164,9 @@ export function doMonsterTrip(data: newOptions) {
duration,
bitfield
} = data;
const currentKC = kcBank.amount(monster.id);
const currentKC =
kcBank.amount(monster.id) + (monster.name === 'Araxxor' ? kcBank.amount(ARAXXOR_DEAD_ID as EMonster) : 0);

const updateBank = new UpdateBank();

const isRevenantMonster = monster.name.includes('Revenant');
Expand Down Expand Up @@ -300,7 +302,8 @@ export function doMonsterTrip(data: newOptions) {
hasSuperiors: superiorTable,
inCatacombs: isInCatacombs,
lootTableOptions: {
tertiaryItemPercentageChanges
tertiaryItemPercentageChanges,
sacrificeLoot: bitfield.includes(BitField.SacrificeLoot)
}
};

Expand Down Expand Up @@ -376,6 +379,9 @@ export function doMonsterTrip(data: newOptions) {
messages.push(ashSanctifierResult.message);
}
}
if (loot.length === 0) {
messages.push('You received no loot');
}
}

if (newSuperiorCount) {
Expand Down Expand Up @@ -415,8 +421,14 @@ export function doMonsterTrip(data: newOptions) {
}
}

if (!wiped) updateBank.kcBank.add(monster.id, quantity);
const newKC = kcBank.amount(monster.id) + quantity;
if (!wiped) {
updateBank.kcBank.add(
monster.sacrificeID && bitfield.includes(BitField.SacrificeLoot) ? monster.sacrificeID : monster.id,
quantity
);
}

const newKC = currentKC + quantity;

return {
slayerContext,
Expand Down
Loading