diff --git a/src/lib/simulation/simulatedKillables.ts b/src/lib/simulation/simulatedKillables.ts index fffe925131..6f2b5f0c2f 100644 --- a/src/lib/simulation/simulatedKillables.ts +++ b/src/lib/simulation/simulatedKillables.ts @@ -5,9 +5,11 @@ import { randArrItem, randInt, roll } from 'e'; import { DOANonUniqueTable } from '../bso/doa/doaLootTable'; import { nexUniqueDrops } from '../data/CollectionsExport'; import { chanceOfDOAUnique, pickUniqueToGiveUser } from '../depthsOfAtlantis'; +import { KingGoldemarLootTable } from '../minions/data/killableMonsters/custom/bosses/KingGoldemar'; import { MoktangLootTable } from '../minions/data/killableMonsters/custom/bosses/Moktang'; import { NEX_UNIQUE_DROPRATE, nexLootTable } from '../nex'; import { zygomiteFarmingSource } from '../skilling/skills/farming/zygomites'; +import { calcDwwhChance } from '../structures/Boss'; import { WintertodtCrate } from './wintertodt'; export const winterTodtPointsTable = new SimpleTable() @@ -36,6 +38,7 @@ export const winterTodtPointsTable = new SimpleTable() interface SimulatedKillable { name: string; isCustom: boolean; + message?: string; loot: (quantity: number) => Bank; } const emptyBank = new Bank(); @@ -120,6 +123,21 @@ export const simulatedKillables: SimulatedKillable[] = [ return loot; } }, + { + name: 'King Goldemar', + isCustom: true, + message: '**Assumptions**:\n- Solo\n- Ring of Luck equipped', + loot: (quantity: number): Bank => { + const loot = new Bank(); + for (let i = 0; i < quantity; i++) { + if (roll(calcDwwhChance(1, true))) { + loot.add('Broken dwarven warhammer'); + } + } + loot.add(KingGoldemarLootTable.roll(quantity)); + return loot; + } + }, { name: 'Moktang', isCustom: true, diff --git a/src/lib/structures/Boss.ts b/src/lib/structures/Boss.ts index 72d3c6ffec..d21d7f17ab 100644 --- a/src/lib/structures/Boss.ts +++ b/src/lib/structures/Boss.ts @@ -17,8 +17,8 @@ import type { Gear } from './Gear'; export const gpCostPerKill = (user: MUser) => user.gear.melee.hasEquipped(['Ring of charos', 'Ring of charos(a)'], false) ? 5_000_000 : 10_000_000; -export const calcDwwhChance = (users: MUser[]) => { - const size = Math.min(users.length, 10); +export const calcDwwhChance = (amount: number, hasROL: boolean) => { + const size = Math.min(amount, 10); const baseRate = 850; const modDenominator = 15; @@ -26,7 +26,7 @@ export const calcDwwhChance = (users: MUser[]) => { let groupRate = Math.ceil(dropRate / size); groupRate = Math.ceil(groupRate); - if (users.some(u => u.gear.melee.hasEquipped('Ring of luck'))) { + if (hasROL) { groupRate = Math.floor(reduceNumByPercent(groupRate, 15)); } return groupRate; @@ -506,7 +506,7 @@ export class BossInstance { if (this.users.length !== bossUsers.length) { console.error('wtfffffffff'); } - const dwwhChance = calcDwwhChance(bossUsers.map(i => i.user)); + const dwwhChance = calcDwwhChance(bossUsers.length, false); results.push([ bossUsers.length, bossUsers[0].userPercentChange.toFixed(1), diff --git a/src/lib/workers/kill.worker.ts b/src/lib/workers/kill.worker.ts index 5a509c5b15..396bfed2e9 100644 --- a/src/lib/workers/kill.worker.ts +++ b/src/lib/workers/kill.worker.ts @@ -21,8 +21,20 @@ export default async ({ limit, lootTableTertiaryChanges }: KillWorkerArgs): KillWorkerReturn => { - const osjsMonster = Monsters.find(mon => mon.aliases.some(alias => stringMatches(alias, bossName))); + const simulatedKillable = simulatedKillables.find(i => stringMatches(i.name, bossName)); + if (simulatedKillable) { + if (quantity > limit) { + return { + error: `The quantity you gave exceeds your limit of ${limit.toLocaleString()}! *You can increase your limit by up to 1 million by becoming a patron at ` + }; + } + return { + content: simulatedKillable.message, + bank: simulatedKillable.loot(quantity).toJSON() + }; + } + const osjsMonster = Monsters.find(mon => mon.aliases.some(alias => stringMatches(alias, bossName))); if (osjsMonster) { if (osjsMonster.id === YETI_ID && production) { return { error: 'The bot is too scared to simulate fighting the yeti.' }; @@ -51,16 +63,5 @@ export default async ({ return { bank: result.bank.toJSON() }; } - const simulatedKillable = simulatedKillables.find(i => stringMatches(i.name, bossName)); - if (simulatedKillable) { - if (quantity > limit) { - return { - error: `The quantity you gave exceeds your limit of ${limit.toLocaleString()}! *You can increase your limit by up to 1 million by becoming a patron at ` - }; - } - - return { bank: simulatedKillable.loot(quantity).toJSON() }; - } - return { error: "I don't have that monster!" }; }; diff --git a/src/mahoji/commands/kill.ts b/src/mahoji/commands/kill.ts index 0c61f1de43..c3dac51bd0 100644 --- a/src/mahoji/commands/kill.ts +++ b/src/mahoji/commands/kill.ts @@ -52,8 +52,10 @@ export const killCommand: OSBMahojiCommand = { required: true, autocomplete: async (value: string) => { return [ - ...Monsters.map(i => ({ name: i.name, aliases: i.aliases })), - ...simulatedKillables.map(i => ({ name: i.name, aliases: [i.name] })) + ...Array.from(Monsters.values()).map(i => ({ name: i.name, aliases: i.aliases })), + ...simulatedKillables + .filter(i => !Array.from(Monsters.values()).some(monster => monster.name === i.name)) + .map(i => ({ name: i.name, aliases: [i.name] })) ] .filter(i => !value ? true : i.aliases.some(alias => alias.toLowerCase().includes(value.toLowerCase())) diff --git a/src/tasks/minions/bso/kingGoldemarActivity.ts b/src/tasks/minions/bso/kingGoldemarActivity.ts index 2fdafde797..a059fd6084 100644 --- a/src/tasks/minions/bso/kingGoldemarActivity.ts +++ b/src/tasks/minions/bso/kingGoldemarActivity.ts @@ -70,7 +70,10 @@ export const kingGoldemarTask: MinionTask = { await Promise.all(users.map(u => u.incrementKC(KingGoldemar.id, 1))); - const dwwhChance = calcDwwhChance(users); + const dwwhChance = calcDwwhChance( + users.length, + users.some(u => u.gear.melee.hasEquipped('Ring of luck')) + ); const gotDWWH = roll(dwwhChance); const dwwhRecipient = gotDWWH ? randArrItem(dwwhTable) : null;