From 1c1d2c56381176a19870e8ef0d820d733b83794e Mon Sep 17 00:00:00 2001 From: Jonesy <69014816+nwjgit@users.noreply.github.com> Date: Wed, 7 Feb 2024 01:27:43 -0600 Subject: [PATCH 01/19] Add data for Personal XP from Tears of Guthix (#5660) --- .../lib/abstracted_commands/statCommand.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/mahoji/lib/abstracted_commands/statCommand.ts b/src/mahoji/lib/abstracted_commands/statCommand.ts index 4ac6cc766f..7b422798cf 100644 --- a/src/mahoji/lib/abstracted_commands/statCommand.ts +++ b/src/mahoji/lib/abstracted_commands/statCommand.ts @@ -3,7 +3,7 @@ import { sumArr, Time } from 'e'; import { CommandResponse } from 'mahoji/dist/lib/structures/ICommand'; import { Bank, Monsters } from 'oldschooljs'; import { SkillsEnum } from 'oldschooljs/dist/constants'; -import { ItemBank } from 'oldschooljs/dist/meta/types'; +import { ItemBank, SkillsScore } from 'oldschooljs/dist/meta/types'; import { TOBRooms } from 'oldschooljs/dist/simulation/misc/TheatreOfBlood'; import { toKMB } from 'oldschooljs/dist/util'; @@ -11,6 +11,7 @@ import { ClueTiers } from '../../../lib/clues/clueTiers'; import { getClueScoresFromOpenables } from '../../../lib/clues/clueUtils'; import { Emoji, PerkTier } from '../../../lib/constants'; import { calcCLDetails, isCLItem } from '../../../lib/data/Collections'; +import { skillEmoji } from '../../../lib/data/emojis'; import { getBankBgById } from '../../../lib/minions/data/bankBackgrounds'; import killableMonsters from '../../../lib/minions/data/killableMonsters'; import { RandomEvents } from '../../../lib/randomEvents'; @@ -952,6 +953,27 @@ GROUP BY "bankBackground";`); ).toLocaleString()}** XP from using the Ash Sanctifier.`; } }, + { + name: 'Personal XP gained from Tears of Guthix', + perkTierNeeded: PerkTier.Four, + run: async (user: MUser) => { + const result = await prisma.$queryRawUnsafe( + `SELECT skill, + SUM(xp) AS total_xp + FROM xp_gains + WHERE source = 'TearsOfGuthix' + AND user_id = ${BigInt(user.id)} + GROUP BY skill` + ); + + return `**Personal XP gained from Tears of Guthix**\n${result + .map( + (i: any) => + `${skillEmoji[i.skill as keyof typeof skillEmoji] as keyof SkillsScore} ${toKMB(i.total_xp)}` + ) + .join('\n')}`; + } + }, { name: 'Bird Eggs Offered', perkTierNeeded: null, From 1c328cfec02cdd37870e100c8b8fd1fa317e36c3 Mon Sep 17 00:00:00 2001 From: themrrobert <10122432+themrrobert@users.noreply.github.com> Date: Wed, 7 Feb 2024 05:59:24 -0800 Subject: [PATCH 02/19] `/drop` improvement - Double check drop message fix (#5664) --- src/lib/util/smallUtils.ts | 7 +++++++ src/mahoji/commands/drop.ts | 20 +++++++++++--------- src/mahoji/commands/sell.ts | 10 ++++++---- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/lib/util/smallUtils.ts b/src/lib/util/smallUtils.ts index 68b0221541..f0cc081665 100644 --- a/src/lib/util/smallUtils.ts +++ b/src/lib/util/smallUtils.ts @@ -332,3 +332,10 @@ export function containsBlacklistedWord(str: string): boolean { } return false; } + +export function ellipsize(str: string, maxLen: number = 2000) { + if (str.length > maxLen) { + return `${str.substring(0, maxLen - 3)}...`; + } + return str; +} diff --git a/src/mahoji/commands/drop.ts b/src/mahoji/commands/drop.ts index 88f4d3ffec..3840391128 100644 --- a/src/mahoji/commands/drop.ts +++ b/src/mahoji/commands/drop.ts @@ -1,7 +1,7 @@ import { ApplicationCommandOptionType, CommandRunOptions } from 'mahoji'; import { ClueTiers } from '../../lib/clues/clueTiers'; -import { itemNameFromID } from '../../lib/util'; +import { ellipsize, itemNameFromID, returnStringOrFile } from '../../lib/util'; import { handleMahojiConfirmation } from '../../lib/util/handleMahojiConfirmation'; import { parseBank } from '../../lib/util/parseStringBank'; import { updateBankSetting } from '../../lib/util/updateBankSetting'; @@ -66,23 +66,25 @@ export const dropCommand: OSBMahojiCommand = { ].flat(1); const doubleCheckItems = itemsToDoubleCheck.filter(f => bank.has(f)); + await handleMahojiConfirmation( + interaction, + `${user}, are you sure you want to drop ${ellipsize( + bank.toString(), + 1800 + )}? This is irreversible, and you will lose the items permanently.` + ); if (doubleCheckItems.length > 0) { await handleMahojiConfirmation( interaction, - `${user}, some of the items you are dropping look valuable, are you *really* sure you want to drop them? **${doubleCheckItems + `${user}, some of the items you are dropping are on your **favorites** or look valuable, are you *really* sure you want to drop them?\n**${doubleCheckItems .map(itemNameFromID) - .join(', ')}**` - ); - } else { - await handleMahojiConfirmation( - interaction, - `${user}, are you sure you want to drop ${bank}? This is irreversible, and you will lose the items permanently.` + .join(', ')}**\n\nDropping: ${ellipsize(bank.toString(), 1000)}` ); } await user.removeItemsFromBank(bank); updateBankSetting('dropped_items', bank); - return `Dropped ${bank}.`; + return returnStringOrFile(`Dropped ${bank}.`); } }; diff --git a/src/mahoji/commands/sell.ts b/src/mahoji/commands/sell.ts index 994fbd3587..c79979b8f6 100644 --- a/src/mahoji/commands/sell.ts +++ b/src/mahoji/commands/sell.ts @@ -7,7 +7,7 @@ import { Item, ItemBank } from 'oldschooljs/dist/meta/types'; import { MAX_INT_JAVA } from '../../lib/constants'; import { prisma } from '../../lib/settings/prisma'; import { NestBoxesTable } from '../../lib/simulation/misc'; -import { itemID, toKMB } from '../../lib/util'; +import { itemID, returnStringOrFile, toKMB } from '../../lib/util'; import { handleMahojiConfirmation } from '../../lib/util/handleMahojiConfirmation'; import { parseBank } from '../../lib/util/parseStringBank'; import { updateBankSetting } from '../../lib/util/updateBankSetting'; @@ -234,8 +234,10 @@ export const sellCommand: OSBMahojiCommand = { prisma.botItemSell.createMany({ data: botItemSellData }) ]); - return `Sold ${bankToSell} for **${totalPrice.toLocaleString()}gp (${toKMB(totalPrice)})**${ - user.isIronman ? ' (General store price)' : ` (${taxRatePercent}% below market price)` - }.`; + return returnStringOrFile( + `Sold ${bankToSell} for **${totalPrice.toLocaleString()}gp (${toKMB(totalPrice)})**${ + user.isIronman ? ' (General store price)' : ` (${taxRatePercent}% below market price)` + }.` + ); } }; From 11cd63d03216fd9ba31cec546d91fbcba74b58a2 Mon Sep 17 00:00:00 2001 From: Jonesy <69014816+nwjgit@users.noreply.github.com> Date: Fri, 9 Feb 2024 00:47:05 -0600 Subject: [PATCH 03/19] Fix CA command being case sensitive (#5671) --- src/mahoji/commands/ca.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mahoji/commands/ca.ts b/src/mahoji/commands/ca.ts index 4ad29b3f41..eb1c298a1c 100644 --- a/src/mahoji/commands/ca.ts +++ b/src/mahoji/commands/ca.ts @@ -140,7 +140,7 @@ export const caCommand: OSBMahojiCommand = { if (selectedMonster) { const tasksForSelectedMonster = allCombatAchievementTasks.filter( - task => task.monster === selectedMonster + task => task.monster.toLowerCase() === selectedMonster!.toLowerCase() ); if (tasksForSelectedMonster.length === 0) From 72042906f2345dcb91fa7c387ce79277acd7bd4d Mon Sep 17 00:00:00 2001 From: Jonesy <69014816+nwjgit@users.noreply.github.com> Date: Fri, 9 Feb 2024 20:11:51 -0600 Subject: [PATCH 04/19] Remove extra TOB clue scrolls (#5672) --- src/lib/simulation/tob.ts | 13 ++++++++++++- src/tasks/minions/minigames/tobActivity.ts | 9 ++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/lib/simulation/tob.ts b/src/lib/simulation/tob.ts index 1c789f1fd1..6993e2a0da 100644 --- a/src/lib/simulation/tob.ts +++ b/src/lib/simulation/tob.ts @@ -4,6 +4,7 @@ import { Bank, LootTable } from 'oldschooljs'; import { LootBank } from 'oldschooljs/dist/meta/types'; import { convertLootBanksToItemBanks, JSONClone } from 'oldschooljs/dist/util'; +import { BOT_TYPE } from '../constants'; import { TOBRooms } from '../data/tob'; import { assert } from '../util/logError'; @@ -50,7 +51,6 @@ const HardModeUniqueTable = new LootTable() .add('Avernic defender hilt', 1, 7); const NonUniqueTable = new LootTable() - .tertiary(25, 'Clue scroll (elite)') .add('Vial of blood', [50, 60], 2) .add('Death rune', [500, 600]) .add('Blood rune', [500, 600]) @@ -93,6 +93,10 @@ export class TheatreOfBloodClass { if (deaths.length === TOBRooms.length) { return new Bank().add('Cabbage'); } + + if (BOT_TYPE === 'BSO') { + NonUniqueTable.tertiary(25, 'Clue scroll (elite)'); + } const loot = new Bank(); for (let i = 0; i < 3; i++) { loot.add(NonUniqueTable.roll()); @@ -106,6 +110,13 @@ export class TheatreOfBloodClass { // Add HM Tertiary drops: dust / kits loot.add(HardModeExtraTable.roll()); } + + if (BOT_TYPE === 'OSB') { + if (roll(25)) { + loot.add('Clue scroll (elite)'); + } + } + let petChance = isHardMode ? 500 : 650; if (member.numDeaths > 0) { petChance *= member.numDeaths; diff --git a/src/tasks/minions/minigames/tobActivity.ts b/src/tasks/minions/minigames/tobActivity.ts index f25fe8ac75..8c080390c3 100644 --- a/src/tasks/minions/minigames/tobActivity.ts +++ b/src/tasks/minions/minigames/tobActivity.ts @@ -3,7 +3,7 @@ import { roll, shuffleArr } from 'e'; import { Bank } from 'oldschooljs'; import { drawChestLootImage } from '../../../lib/bankImage'; -import { Emoji, Events } from '../../../lib/constants'; +import { BOT_TYPE, Emoji, Events } from '../../../lib/constants'; import { tobMetamorphPets } from '../../../lib/data/CollectionsExport'; import { TOBRooms, TOBUniques, TOBUniquesToAnnounce } from '../../../lib/data/tob'; import { trackLoot } from '../../../lib/lootTrack'; @@ -141,6 +141,13 @@ export const tobTask: MinionTask = { // Refund initial 100k entry cost userLoot.add('Coins', 100_000); + // Remove elite clue scroll if OSB & user has one in bank + if (BOT_TYPE === 'OSB') { + if (user.owns('Clue scroll (elite)')) { + userLoot.remove('Clue scroll (elite)', 1); + } + } + // Add this raids loot to the raid's total loot: totalLoot.add(userLoot); From 2abdaff9cbccd020dffe24e49f8fa8db460c2bf5 Mon Sep 17 00:00:00 2001 From: TURBO Date: Sat, 10 Feb 2024 03:35:09 -0600 Subject: [PATCH 05/19] Fix only lowercase searches in CL issue (#5678) --- src/mahoji/commands/cl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mahoji/commands/cl.ts b/src/mahoji/commands/cl.ts index 62d5a2ea6b..b24fefd496 100644 --- a/src/mahoji/commands/cl.ts +++ b/src/mahoji/commands/cl.ts @@ -39,7 +39,7 @@ export const collectionLogCommand: OSBMahojiCommand = { ]; }) .flat(3) - ].filter(i => (!value ? true : i.name.toLowerCase().includes(value))); + ].filter(i => (!value ? true : i.name.toLowerCase().includes(value.toLowerCase()))); } }, { From a32cd7441b4b8d4ec9ff8fd3d3cfe85b272231fb Mon Sep 17 00:00:00 2001 From: TastyPumPum <79149170+TastyPumPum@users.noreply.github.com> Date: Mon, 12 Feb 2024 02:22:55 +0000 Subject: [PATCH 06/19] Add /testpotato setslayertask (#5682) --- src/lib/slayer/tasks/index.ts | 2 + src/mahoji/commands/testpotato.ts | 100 ++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/src/lib/slayer/tasks/index.ts b/src/lib/slayer/tasks/index.ts index a514c6c844..b33c3dccc0 100644 --- a/src/lib/slayer/tasks/index.ts +++ b/src/lib/slayer/tasks/index.ts @@ -18,3 +18,5 @@ export const allSlayerTasks: AssignableSlayerTask[] = [ ...vannakaTasks, ...duradelTasks ]; + +export const allSlayerMonsters = allSlayerTasks.map(m => m.monster); diff --git a/src/mahoji/commands/testpotato.ts b/src/mahoji/commands/testpotato.ts index 11e9f306af..3006ae867a 100644 --- a/src/mahoji/commands/testpotato.ts +++ b/src/mahoji/commands/testpotato.ts @@ -24,6 +24,10 @@ import { prisma } from '../../lib/settings/prisma'; import { getFarmingInfo } from '../../lib/skilling/functions/getFarmingInfo'; import Skills from '../../lib/skilling/skills'; import Farming from '../../lib/skilling/skills/farming'; +import { slayerMasterChoices } from '../../lib/slayer/constants'; +import { slayerMasters } from '../../lib/slayer/slayerMasters'; +import { getUsersCurrentSlayerInfo } from '../../lib/slayer/slayerUtil'; +import { allSlayerMonsters } from '../../lib/slayer/tasks'; import { stringMatches } from '../../lib/util'; import { calcDropRatesFromBankWithoutUniques } from '../../lib/util/calcDropRatesFromBank'; import { @@ -514,6 +518,46 @@ export const testPotatoCommand: OSBMahojiCommand | null = production } } ] + }, + { + type: ApplicationCommandOptionType.Subcommand, + name: 'setslayertask', + description: 'Set slayer task.', + options: [ + { + type: ApplicationCommandOptionType.String, + name: 'master', + description: 'The master you wish to set your task.', + required: true, + choices: slayerMasterChoices + }, + { + type: ApplicationCommandOptionType.String, + name: 'monster', + description: 'The monster you want to set your task as.', + required: true, + autocomplete: async value => { + const filteredMonsters = [...new Set(allSlayerMonsters)].filter(monster => { + if (!value) return true; + return [monster.name.toLowerCase(), ...monster.aliases].some(aliases => + aliases.includes(value.toLowerCase()) + ); + }); + return filteredMonsters.map(monster => ({ + name: monster.name, + value: monster.name + })); + } + }, + { + type: ApplicationCommandOptionType.Integer, + name: 'quantity', + description: 'The task quantity you want to assign.', + required: false, + min_value: 0, + max_value: 1000 + } + ] } ], run: async ({ @@ -534,6 +578,7 @@ export const testPotatoCommand: OSBMahojiCommand | null = production set?: { qp?: number; all_ca_tasks?: boolean }; check?: { monster_droprates?: string }; bingo_tools?: { start_bingo: string }; + setslayertask?: { master: string; monster: string; quantity: number }; }>) => { if (production) { logError('Test command ran in production', { userID: userID.toString() }); @@ -832,6 +877,61 @@ ${droprates.join('\n')}`), return userGrowingProgressStr((await getFarmingInfo(userID)).patchesDetailed); } + if (options.setslayertask) { + const user = await mUserFetch(userID); + const usersTask = await getUsersCurrentSlayerInfo(user.id); + + const { monster, master } = options.setslayertask; + + const selectedMonster = allSlayerMonsters.find(m => stringMatches(m.name, monster)); + const selectedMaster = slayerMasters.find( + sm => stringMatches(master, sm.name) || sm.aliases.some(alias => stringMatches(master, alias)) + ); + + // Set quantity to 50 if user doesn't assign a quantity + const quantity = options.setslayertask?.quantity ?? 50; + + const assignedTask = selectedMaster!.tasks.find(m => m.monster.id === selectedMonster?.id)!; + + if (!selectedMaster) return 'Invalid slayer master.'; + if (!selectedMonster) return 'Invalid monster.'; + if (!assignedTask) return `${selectedMaster.name} can not assign ${selectedMonster.name}.`; + + // Update an existing slayer task for the user + if (usersTask.currentTask?.id) { + await prisma.slayerTask.update({ + where: { + id: usersTask.currentTask?.id + }, + data: { + quantity, + quantity_remaining: quantity, + slayer_master_id: selectedMaster.id, + monster_id: selectedMonster.id, + skipped: false + } + }); + } else { + // Create a new slayer task for the user + await prisma.slayerTask.create({ + data: { + user_id: user.id, + quantity, + quantity_remaining: quantity, + slayer_master_id: selectedMaster.id, + monster_id: selectedMonster.id, + skipped: false + } + }); + } + + await user.update({ + slayer_last_task: selectedMonster.id + }); + + return `You set your slayer task to ${selectedMonster.name} using ${selectedMaster.name}.`; + } + return 'Nothin!'; } }; From 4af59edd2c59f3a2d8ef7feb9f8adea32c2f1d1c Mon Sep 17 00:00:00 2001 From: Jonesy <69014816+nwjgit@users.noreply.github.com> Date: Mon, 12 Feb 2024 20:58:53 -0600 Subject: [PATCH 07/19] Fix notifications for shades of morton cl (#5688) --- src/lib/data/Collections.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/data/Collections.ts b/src/lib/data/Collections.ts index 469215519e..c3dd7a8bd3 100644 --- a/src/lib/data/Collections.ts +++ b/src/lib/data/Collections.ts @@ -143,7 +143,7 @@ function kcProg(mon: Monster): FormatProgressFunction { } function mgProg(minigameName: MinigameName): FormatProgressFunction { - return ({ minigames }) => `${minigames[minigameName]} KC`; + return ({ minigames }) => `${minigames[minigameName]} Completions`; } function skillProg(skillName: SkillsEnum): FormatProgressFunction { @@ -807,7 +807,7 @@ export const allCollectionLogs: ICollection = { "Shades of Mort'ton": { items: shadesOfMorttonCL, isActivity: true, - fmtProg: () => '0 KC' + fmtProg: mgProg('shades_of_morton') }, 'Soul Wars': { alias: ['soul wars', 'sw'], From 326764168ab8f86940cb89f35524acb9cc6f3f37 Mon Sep 17 00:00:00 2001 From: Jonesy <69014816+nwjgit@users.noreply.github.com> Date: Mon, 12 Feb 2024 21:05:37 -0600 Subject: [PATCH 08/19] Toggle for wilderness high peak time warning (#5411) --- src/lib/constants.ts | 8 +++++++- src/mahoji/commands/config.ts | 4 ++++ src/mahoji/lib/abstracted_commands/minionKill.ts | 4 ++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/lib/constants.ts b/src/lib/constants.ts index abb085ff39..50b28b0fac 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -260,7 +260,8 @@ export enum BitField { SelfGamblingLocked = 36, DisabledFarmingReminders = 37, DisableClueButtons = 38, - DisableAutoSlayButton = 39 + DisableAutoSlayButton = 39, + DisableHighPeakTimeWarning = 40 } interface BitFieldData { @@ -350,6 +351,11 @@ export const BitFieldData: Record = { name: 'Disable Auto Slay Button', protected: false, userConfigurable: true + }, + [BitField.DisableHighPeakTimeWarning]: { + name: 'Disable Wilderness High Peak Time Warning', + protected: false, + userConfigurable: true } } as const; diff --git a/src/mahoji/commands/config.ts b/src/mahoji/commands/config.ts index ac07d20f93..6c22feff83 100644 --- a/src/mahoji/commands/config.ts +++ b/src/mahoji/commands/config.ts @@ -127,6 +127,10 @@ const toggles: UserConfigToggle[] = [ { name: 'Disable Clue Buttons', bit: BitField.DisableClueButtons + }, + { + name: 'Disable wilderness high peak time warning', + bit: BitField.DisableHighPeakTimeWarning } ]; diff --git a/src/mahoji/lib/abstracted_commands/minionKill.ts b/src/mahoji/lib/abstracted_commands/minionKill.ts index c1f71fdebb..12b1068142 100644 --- a/src/mahoji/lib/abstracted_commands/minionKill.ts +++ b/src/mahoji/lib/abstracted_commands/minionKill.ts @@ -15,7 +15,7 @@ import { Bank, Monsters } from 'oldschooljs'; import { MonsterAttribute } from 'oldschooljs/dist/meta/monsterData'; import { itemID } from 'oldschooljs/dist/util'; -import { PeakTier, PvMMethod } from '../../../lib/constants'; +import { BitField, PeakTier, PvMMethod } from '../../../lib/constants'; import { Eatables } from '../../../lib/data/eatables'; import { getSimilarItems } from '../../../lib/data/similarItems'; import { checkUserCanUseDegradeableItem, degradeablePvmBoostItems, degradeItem } from '../../../lib/degradeableItems'; @@ -689,7 +689,7 @@ export async function minionKillCommand( break; } } - if (wildyPeak?.peakTier === PeakTier.High) { + if (wildyPeak?.peakTier === PeakTier.High && !user.bitfield.includes(BitField.DisableHighPeakTimeWarning)) { if (interaction) { await handleMahojiConfirmation( interaction, From dbf35dde59fe852d0cba0af5e3e5779eeb6c72c7 Mon Sep 17 00:00:00 2001 From: TastyPumPum <79149170+TastyPumPum@users.noreply.github.com> Date: Wed, 14 Feb 2024 11:17:28 +0000 Subject: [PATCH 09/19] Allow Inferno KC to impact Fightcaves (#5689) --- .../abstracted_commands/fightCavesCommand.ts | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/mahoji/lib/abstracted_commands/fightCavesCommand.ts b/src/mahoji/lib/abstracted_commands/fightCavesCommand.ts index aaf951f314..784f7ff254 100644 --- a/src/mahoji/lib/abstracted_commands/fightCavesCommand.ts +++ b/src/mahoji/lib/abstracted_commands/fightCavesCommand.ts @@ -4,6 +4,7 @@ import { Bank, Monsters } from 'oldschooljs'; import TzTokJad from 'oldschooljs/dist/simulation/monsters/special/TzTokJad'; import { itemID } from 'oldschooljs/dist/util'; +import { getMinigameScore } from '../../../lib/settings/minigames'; import { getUsersCurrentSlayerInfo } from '../../../lib/slayer/slayerUtil'; import { FightCavesActivityTaskOptions } from '../../../lib/types/minions'; import { formatDuration } from '../../../lib/util'; @@ -24,7 +25,9 @@ async function determineDuration(user: MUser): Promise<[number, string]> { // Reduce time based on KC const jadKC = await user.getKC(TzTokJad.id); - const percentIncreaseFromKC = Math.min(50, jadKC); + const zukKC = await getMinigameScore(user.id, 'inferno'); + const experienceKC = jadKC + zukKC * 3; + const percentIncreaseFromKC = Math.min(50, experienceKC); baseTime = reduceNumByPercent(baseTime, percentIncreaseFromKC); debugStr += `${percentIncreaseFromKC}% from KC`; @@ -43,9 +46,12 @@ async function determineDuration(user: MUser): Promise<[number, string]> { return [baseTime, debugStr]; } -function determineChanceOfDeathPreJad(user: MUser, attempts: number) { +function determineChanceOfDeathPreJad(user: MUser, attempts: number, hasInfernoKC: boolean) { let deathChance = Math.max(14 - attempts * 2, 5); + // If user has killed inferno, give them the lowest chance of death pre Jad. + if (hasInfernoKC) deathChance = 5; + // -4% Chance of dying before Jad if you have SGS. if (user.hasEquipped(itemID('Saradomin godsword'))) { deathChance -= 4; @@ -54,8 +60,12 @@ function determineChanceOfDeathPreJad(user: MUser, attempts: number) { return deathChance; } -function determineChanceOfDeathInJad(attempts: number) { - const chance = Math.floor(100 - (Math.log(attempts) / Math.log(Math.sqrt(15))) * 50); +function determineChanceOfDeathInJad(attempts: number, hasInfernoKC: boolean) { + let chance = Math.floor(100 - (Math.log(attempts) / Math.log(Math.sqrt(15))) * 50); + + if (hasInfernoKC) { + chance /= 1.5; + } // Chance of death cannot be 100% or <5%. return Math.max(Math.min(chance, 99), 5); @@ -98,11 +108,14 @@ export async function fightCavesCommand(user: MUser, channelID: string): Command const { fight_caves_attempts: attempts } = await user.fetchStats({ fight_caves_attempts: true }); - const jadDeathChance = determineChanceOfDeathInJad(attempts); - const preJadDeathChance = determineChanceOfDeathPreJad(user, attempts); + const jadKC = await user.getKC(TzTokJad.id); + const zukKC = await getMinigameScore(user.id, 'inferno'); + const hasInfernoKC = zukKC > 0; + + const jadDeathChance = determineChanceOfDeathInJad(attempts, hasInfernoKC); + const preJadDeathChance = determineChanceOfDeathPreJad(user, attempts, hasInfernoKC); const usersRangeStats = user.gear.range.stats; - const jadKC = await user.getKC(TzTokJad.id); duration += (randInt(1, 5) * duration) / 100; @@ -148,6 +161,7 @@ export async function fightCavesCommand(user: MUser, channelID: string): Command **Boosts:** ${debugStr} **Range Attack Bonus:** ${usersRangeStats.attack_ranged} **Jad KC:** ${jadKC} +**Zuk KC:** ${zukKC} **Attempts:** ${attempts} **Removed from your bank:** ${fightCavesCost}`, From 8cd741b8d9cf0d66d941a51a81e58b23ce5ba00e Mon Sep 17 00:00:00 2001 From: Jonesy <69014816+nwjgit@users.noreply.github.com> Date: Mon, 19 Feb 2024 01:51:04 -0600 Subject: [PATCH 10/19] Update random events (#5695) --- src/lib/randomEvents.ts | 73 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/src/lib/randomEvents.ts b/src/lib/randomEvents.ts index 061257c0c9..c769b4896e 100644 --- a/src/lib/randomEvents.ts +++ b/src/lib/randomEvents.ts @@ -39,18 +39,36 @@ export const zombieOutfit = resolveItems([ export const mimeOutfit = resolveItems(['Mime mask', 'Mime top', 'Mime legs', 'Mime gloves', 'Mime boots']); +// Used by Mysterious Old man, Pillory, Rick Turpentine +const randomEventTable = new LootTable() + .add('Uncut sapphire', 1, 32) + .add('Uncut emerald', 1, 16) + .add('Coins', 80, 10) + .add('Coins', 160, 10) + .add('Coins', 320, 10) + .add('Coins', 480, 10) + .add('Coins', 640, 10) + .add('Uncut ruby', 1, 8) + .add('Coins', 240, 6) + .add('Cosmic talisman', 1, 4) + .add('Uncut diamond', 2, 2) + .add('Tooth half of key', 1, 1) + .add('Tooth half of key', 1, 1); + +// https://oldschool.runescape.wiki/w/Random_events#List_of_random_events +// Missing: Evil Bob, Jekyll and Hyde, Maze, Prison Pete export const RandomEvents: RandomEvent[] = [ { id: 1, name: 'Bee keeper', outfit: beekeeperOutfit, - loot: new LootTable().add('Coins', [20, 60]).add('Flax', [1, 27]) + loot: new LootTable().add('Coins', [16, 36]).add('Flax', [1, 27]) }, { id: 2, name: 'Drill Demon', outfit: camoOutfit, - loot: new LootTable().every('Coins', 500) + loot: new LootTable().every('Genie lamp') }, { id: 3, @@ -60,8 +78,8 @@ export const RandomEvents: RandomEvent[] = [ { id: 4, name: 'Freaky Forester', - loot: new LootTable().every('Coins', 500), - outfit: lederhosenOutfit + outfit: lederhosenOutfit, + loot: new LootTable().every('Genie lamp') }, { id: 5, @@ -71,8 +89,8 @@ export const RandomEvents: RandomEvent[] = [ { id: 6, name: 'Gravedigger', - loot: new LootTable().every('Coins', 500), - outfit: zombieOutfit + outfit: zombieOutfit, + loot: new LootTable().every('Genie lamp') }, { id: 7, @@ -82,8 +100,8 @@ export const RandomEvents: RandomEvent[] = [ { id: 8, name: 'Mime', - loot: new LootTable().every('Coins', 500), - outfit: mimeOutfit + outfit: mimeOutfit, + loot: new LootTable().every('Genie lamp') }, { id: 9, @@ -129,6 +147,45 @@ export const RandomEvents: RandomEvent[] = [ .add('Spinach roll') .add('Tooth half of key') .add('Loop half of key') + }, + { + id: 14, + name: 'Count Check', + loot: new LootTable().every('Genie lamp') + }, + { + id: 15, + name: 'Evil twin', + loot: new LootTable() + .add('Uncut sapphire', [2, 4]) + .add('Uncut emerald', [2, 4]) + .add('Uncut ruby', [2, 4]) + .add('Uncut diamond', [2, 4]) + }, + { + id: 16, + name: 'Mysterious Old Man', + loot: randomEventTable.add('Kebab', 1, 16).add('Spinach roll', 1, 14) + }, + { + id: 17, + name: 'Pillory', + loot: randomEventTable + }, + { + id: 18, + name: 'Pinball', + loot: new LootTable().add('Sapphire', 5, 3).add('Emerald', 5, 3).add('Ruby', 5, 3).add('Diamond', 2, 1) + }, + { + id: 19, + name: 'Rick Turpentine', + loot: randomEventTable.add('Kebab', 1, 16).add('Spinach roll', 1, 14) + }, + { + id: 20, + name: 'Strange plant', + loot: new LootTable().every('Strange fruit') } ]; From 7dbda44d6f8bf52d2d507f726c2df5fed2f8ae76 Mon Sep 17 00:00:00 2001 From: TastyPumPum <79149170+TastyPumPum@users.noreply.github.com> Date: Mon, 19 Feb 2024 07:55:57 +0000 Subject: [PATCH 11/19] Update Slayer Task Weightings (#5690) Reviewed all the slayer task weightings and matched them to the wiki, removed duplicated spiritualranger tasks when spiritualmager tasks are there. --- src/lib/slayer/tasks/chaeldarTasks.ts | 14 -------------- src/lib/slayer/tasks/duradelTasks.ts | 17 +--------------- src/lib/slayer/tasks/konarTasks.ts | 6 +++--- src/lib/slayer/tasks/mazchnaTasks.ts | 16 +++++++-------- src/lib/slayer/tasks/nieveTasks.ts | 15 +------------- src/lib/slayer/tasks/turaelTasks.ts | 28 +++++++++++++-------------- src/lib/slayer/tasks/vannakaTasks.ts | 15 +------------- 7 files changed, 28 insertions(+), 83 deletions(-) diff --git a/src/lib/slayer/tasks/chaeldarTasks.ts b/src/lib/slayer/tasks/chaeldarTasks.ts index 53da8688e5..4717015acb 100644 --- a/src/lib/slayer/tasks/chaeldarTasks.ts +++ b/src/lib/slayer/tasks/chaeldarTasks.ts @@ -438,20 +438,6 @@ export const chaeldarTasks: AssignableSlayerTask[] = [ unlocked: true, dontAssign: true }, - { - monster: Monsters.SpiritualRanger, - amount: [110, 170], - - weight: 12, - monsters: [Monsters.SpiritualRanger.id, Monsters.SpiritualWarrior.id, Monsters.SpiritualMage.id], - levelRequirements: { - slayer: 60 - }, - combatLevel: 60, - slayerLevel: 63, - questPoints: 3, - unlocked: true - }, { monster: Monsters.MountainTroll, amount: [110, 170], diff --git a/src/lib/slayer/tasks/duradelTasks.ts b/src/lib/slayer/tasks/duradelTasks.ts index 296deacdd7..12ee193008 100644 --- a/src/lib/slayer/tasks/duradelTasks.ts +++ b/src/lib/slayer/tasks/duradelTasks.ts @@ -379,7 +379,7 @@ export const duradelTasks: AssignableSlayerTask[] = [ monster: Monsters.SpiritualMage, amount: [110, 170], - weight: 12, + weight: 7, monsters: [Monsters.SpiritualRanger.id, Monsters.SpiritualWarrior.id, Monsters.SpiritualMage.id], extendedAmount: [180, 250], extendedUnlockId: SlayerTaskUnlocksEnum.SpiritualFervour, @@ -392,21 +392,6 @@ export const duradelTasks: AssignableSlayerTask[] = [ unlocked: true, dontAssign: true }, - { - monster: Monsters.SpiritualRanger, - amount: [130, 200], - weight: 7, - monsters: [Monsters.SpiritualRanger.id, Monsters.SpiritualWarrior.id, Monsters.SpiritualMage.id], - extendedAmount: [180, 250], - extendedUnlockId: SlayerTaskUnlocksEnum.SpiritualFervour, - levelRequirements: { - slayer: 60 - }, - combatLevel: 60, - slayerLevel: 63, - questPoints: 3, - unlocked: true - }, { monster: Monsters.SteelDragon, amount: [10, 20], diff --git a/src/lib/slayer/tasks/konarTasks.ts b/src/lib/slayer/tasks/konarTasks.ts index 86a13b269a..da41593d7b 100644 --- a/src/lib/slayer/tasks/konarTasks.ts +++ b/src/lib/slayer/tasks/konarTasks.ts @@ -105,7 +105,7 @@ export const konarTasks: AssignableSlayerTask[] = [ { monster: Monsters.BlueDragon, amount: [120, 170], - weight: 8, + weight: 4, monsters: [Monsters.BlueDragon.id, Monsters.BabyBlueDragon.id, Monsters.BrutalBlueDragon.id], combatLevel: 65, questPoints: 34, @@ -204,7 +204,7 @@ export const konarTasks: AssignableSlayerTask[] = [ monster: Monsters.FossilIslandWyvernSpitting, amount: [15, 30], - weight: 9, + weight: 5, monsters: [ Monsters.FossilIslandWyvernAncient.id, Monsters.FossilIslandWyvernLongTailed.id, @@ -381,7 +381,7 @@ export const konarTasks: AssignableSlayerTask[] = [ { monster: Monsters.SteelDragon, amount: [30, 50], - weight: 7, + weight: 5, monsters: [Monsters.SteelDragon.id], levelRequirements: killableMonsters.find(k => k.id === Monsters.SteelDragon.id)!.levelRequirements, extendedAmount: [40, 60], diff --git a/src/lib/slayer/tasks/mazchnaTasks.ts b/src/lib/slayer/tasks/mazchnaTasks.ts index 5e92285f82..2eb078c7c3 100644 --- a/src/lib/slayer/tasks/mazchnaTasks.ts +++ b/src/lib/slayer/tasks/mazchnaTasks.ts @@ -88,14 +88,6 @@ export const mazchnaTasks: AssignableSlayerTask[] = [ questPoints: 1, unlocked: true }, - { - monster: Monsters.Lizard, - amount: [40, 70], - weight: 8, - monsters: [Monsters.Lizard.id, Monsters.SmallLizard.id, Monsters.DesertLizard.id, Monsters.SulphurLizard.id], - slayerLevel: 22, - unlocked: true - }, { monster: Monsters.GuardDog, amount: [40, 70], @@ -185,6 +177,14 @@ export const mazchnaTasks: AssignableSlayerTask[] = [ questPoints: 4, unlocked: true }, + { + monster: Monsters.Lizard, + amount: [40, 70], + weight: 8, + monsters: [Monsters.Lizard.id, Monsters.SmallLizard.id, Monsters.DesertLizard.id, Monsters.SulphurLizard.id], + slayerLevel: 22, + unlocked: true + }, { monster: Monsters.Mogre, amount: [40, 70], diff --git a/src/lib/slayer/tasks/nieveTasks.ts b/src/lib/slayer/tasks/nieveTasks.ts index 9a8565bd85..7fe148d304 100644 --- a/src/lib/slayer/tasks/nieveTasks.ts +++ b/src/lib/slayer/tasks/nieveTasks.ts @@ -358,7 +358,7 @@ export const nieveTasks: AssignableSlayerTask[] = [ monster: Monsters.SpiritualMage, amount: [110, 170], - weight: 12, + weight: 6, monsters: [Monsters.SpiritualRanger.id, Monsters.SpiritualWarrior.id, Monsters.SpiritualMage.id], levelRequirements: { slayer: 60 @@ -369,19 +369,6 @@ export const nieveTasks: AssignableSlayerTask[] = [ unlocked: true, dontAssign: true }, - { - monster: Monsters.SpiritualRanger, - amount: [120, 185], - weight: 6, - monsters: [Monsters.SpiritualRanger.id, Monsters.SpiritualWarrior.id, Monsters.SpiritualMage.id], - levelRequirements: { - slayer: 60 - }, - combatLevel: 60, - slayerLevel: 63, - questPoints: 3, - unlocked: true - }, { monster: Monsters.SteelDragon, amount: [30, 60], diff --git a/src/lib/slayer/tasks/turaelTasks.ts b/src/lib/slayer/tasks/turaelTasks.ts index b5c92ed0c0..1aa36e7c3a 100644 --- a/src/lib/slayer/tasks/turaelTasks.ts +++ b/src/lib/slayer/tasks/turaelTasks.ts @@ -21,6 +21,20 @@ export const turaelTasks: AssignableSlayerTask[] = [ combatLevel: 5, unlocked: true }, + { + monster: Monsters.BlackBear, + amount: [15, 50], + weight: 7, + monsters: [ + Monsters.BlackBear.id, + Monsters.GrizzlyBearCub.id, + Monsters.BearCub.id, + Monsters.GrizzlyBear.id, + Monsters.Callisto.id + ], + combatLevel: 13, + unlocked: true + }, { monster: Monsters.Bird, amount: [15, 50], @@ -38,20 +52,6 @@ export const turaelTasks: AssignableSlayerTask[] = [ ], unlocked: true }, - { - monster: Monsters.BlackBear, - amount: [15, 50], - weight: 7, - monsters: [ - Monsters.BlackBear.id, - Monsters.GrizzlyBearCub.id, - Monsters.BearCub.id, - Monsters.GrizzlyBear.id, - Monsters.Callisto.id - ], - combatLevel: 13, - unlocked: true - }, { monster: Monsters.CaveBug, amount: [10, 20], diff --git a/src/lib/slayer/tasks/vannakaTasks.ts b/src/lib/slayer/tasks/vannakaTasks.ts index 1410e43438..f3b7e1bc62 100644 --- a/src/lib/slayer/tasks/vannakaTasks.ts +++ b/src/lib/slayer/tasks/vannakaTasks.ts @@ -481,7 +481,7 @@ export const vannakaTasks: AssignableSlayerTask[] = [ monster: Monsters.SpiritualMage, amount: [110, 170], - weight: 12, + weight: 8, monsters: [Monsters.SpiritualRanger.id, Monsters.SpiritualWarrior.id, Monsters.SpiritualMage.id], levelRequirements: { slayer: 60 @@ -492,19 +492,6 @@ export const vannakaTasks: AssignableSlayerTask[] = [ unlocked: true, dontAssign: true }, - { - monster: Monsters.SpiritualRanger, - amount: [60, 120], - weight: 8, - monsters: [Monsters.SpiritualRanger.id, Monsters.SpiritualWarrior.id, Monsters.SpiritualMage.id], - levelRequirements: { - slayer: 60 - }, - combatLevel: 60, - slayerLevel: 63, - questPoints: 3, - unlocked: true - }, { monster: Monsters.TerrorDog, amount: [20, 45], From 389747ff08ee23b227bed1f909e9fb0f0ceae3d3 Mon Sep 17 00:00:00 2001 From: Jonesy <69014816+nwjgit@users.noreply.github.com> Date: Mon, 19 Feb 2024 02:19:37 -0600 Subject: [PATCH 12/19] Ghommal's lucky penny, Lower vial of blood cost (#5686) --- src/lib/degradeableItems.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/lib/degradeableItems.ts b/src/lib/degradeableItems.ts index c97b4944c2..5ad9f64d04 100644 --- a/src/lib/degradeableItems.ts +++ b/src/lib/degradeableItems.ts @@ -1,3 +1,4 @@ +import { percentChance } from 'e'; import { Bank } from 'oldschooljs'; import { Item } from 'oldschooljs/dist/meta/types'; import Monster from 'oldschooljs/dist/structures/Monster'; @@ -211,7 +212,7 @@ export const degradeableItems: DegradeableItem[] = [ setup: 'melee', aliases: ['scythe of vitur'], chargeInput: { - cost: new Bank().add('Blood rune', 300).add('Vial of blood').freeze(), + cost: new Bank().add('Blood rune', 200).add('Vial of blood').freeze(), charges: 100 }, unchargedItem: getOSItem('Scythe of vitur (uncharged)'), @@ -297,6 +298,17 @@ export async function degradeItem({ const degItem = degradeableItems.find(i => i.item === item); if (!degItem) throw new Error('Invalid degradeable item'); + // 5% chance to not consume a charge when Ghommal's lucky penny is equipped + let pennyReduction = 0; + if (user.hasEquipped("Ghommal's lucky penny")) { + for (let i = 0; i < chargesToDegrade; i++) { + if (percentChance(5)) { + pennyReduction++; + } + } + } + chargesToDegrade -= pennyReduction; + const currentCharges = user.user[degItem.settingsKey]; assert(typeof currentCharges === 'number'); const newCharges = Math.floor(currentCharges - chargesToDegrade); @@ -353,7 +365,11 @@ export async function degradeItem({ const chargesAfter = user.user[degItem.settingsKey]; assert(typeof chargesAfter === 'number' && chargesAfter > 0); return { - userMessage: `Your ${item.name} degraded by ${chargesToDegrade} charges, and now has ${chargesAfter} remaining.` + userMessage: `Your ${ + item.name + } degraded by ${chargesToDegrade} charges, and now has ${chargesAfter} remaining.${ + pennyReduction > 0 ? ` Your Ghommal's lucky penny saved ${pennyReduction} charges` : '' + }` }; } From 01acb1114be7ce6322f9edc6754e280a173f4efb Mon Sep 17 00:00:00 2001 From: themrrobert <10122432+themrrobert@users.noreply.github.com> Date: Mon, 19 Feb 2024 07:46:25 -0800 Subject: [PATCH 13/19] Always show item names when opening (#5525) --- src/mahoji/lib/abstracted_commands/openCommand.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mahoji/lib/abstracted_commands/openCommand.ts b/src/mahoji/lib/abstracted_commands/openCommand.ts index c61a5c06c5..5d23e02eca 100644 --- a/src/mahoji/lib/abstracted_commands/openCommand.ts +++ b/src/mahoji/lib/abstracted_commands/openCommand.ts @@ -115,7 +115,8 @@ async function finalizeOpening({ ? `Loot from ${cost.amount(openables[0].openedItem.id)}x ${openables[0].name}` : 'Loot From Opening', user, - previousCL + previousCL, + mahojiFlags: ['show_names'] }); if (loot.has('Coins')) { From 7b554ac3909d4ecd37512c02d4972fa88644c330 Mon Sep 17 00:00:00 2001 From: TastyPumPum <79149170+TastyPumPum@users.noreply.github.com> Date: Thu, 22 Feb 2024 06:15:57 +0000 Subject: [PATCH 14/19] Fix CoX grammar in the title in various places (#5707) Removes the incorrect apostrophe from the Chambers of Xeric name in numerous places. Closes #5631 --- src/lib/data/Collections.ts | 2 +- src/lib/data/cox.ts | 4 ++-- src/lib/settings/minigames.ts | 4 ++-- src/lib/util/minionStatus.ts | 2 +- tests/unit/snapshots/clsnapshots.test.ts.snap | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib/data/Collections.ts b/src/lib/data/Collections.ts index c3dd7a8bd3..51126cbb27 100644 --- a/src/lib/data/Collections.ts +++ b/src/lib/data/Collections.ts @@ -502,7 +502,7 @@ export const allCollectionLogs: ICollection = { }, Raids: { activities: { - "Chamber's of Xeric": { + 'Chambers of Xeric': { alias: ChambersOfXeric.aliases, kcActivity: { Default: async (_, minigameScores) => diff --git a/src/lib/data/cox.ts b/src/lib/data/cox.ts index 363d56a78a..56dbe93fb8 100644 --- a/src/lib/data/cox.ts +++ b/src/lib/data/cox.ts @@ -263,10 +263,10 @@ export async function checkCoxTeam(users: MUser[], cm: boolean, quantity: number for (const user of users) { const { total } = calculateUserGearPercents(user); if (total < 20) { - return "Your gear is terrible! You do not stand a chance in the Chamber's of Xeric."; + return 'Your gear is terrible! You do not stand a chance in the Chambers of Xeric.'; } if (!hasMinRaidsRequirements(user)) { - return `${user.usernameOrMention} doesn't meet the stat requirements to do the Chamber's of Xeric.`; + return `${user.usernameOrMention} doesn't meet the stat requirements to do the Chambers of Xeric.`; } if (cm) { if (users.length === 1 && !user.hasEquippedOrInBank('Twisted bow')) { diff --git a/src/lib/settings/minigames.ts b/src/lib/settings/minigames.ts index 29838a353a..74f395aca3 100644 --- a/src/lib/settings/minigames.ts +++ b/src/lib/settings/minigames.ts @@ -97,12 +97,12 @@ export const Minigames: readonly BotMinigame[] = [ column: 'castle_wars' }, { - name: "Chamber's of Xeric", + name: 'Chambers of Xeric', aliases: ['cox', 'raid1', 'raids1', 'chambers', 'xeric'], column: 'raids' }, { - name: "Chamber's of Xeric - Challenge Mode", + name: 'Chambers of Xeric - Challenge Mode', aliases: ['coxcm', 'raid1cm', 'raids1cm', 'chamberscm', 'xericcm'], column: 'raids_challenge_mode' }, diff --git a/src/lib/util/minionStatus.ts b/src/lib/util/minionStatus.ts index 73671add3a..e770be0684 100644 --- a/src/lib/util/minionStatus.ts +++ b/src/lib/util/minionStatus.ts @@ -519,7 +519,7 @@ export function minionStatus(user: MUser) { case 'Raids': { const data = currentTask as RaidsOptions; - return `${name} is currently doing the Chamber's of Xeric${ + 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.` diff --git a/tests/unit/snapshots/clsnapshots.test.ts.snap b/tests/unit/snapshots/clsnapshots.test.ts.snap index 9da493f6c6..f439565780 100644 --- a/tests/unit/snapshots/clsnapshots.test.ts.snap +++ b/tests/unit/snapshots/clsnapshots.test.ts.snap @@ -16,7 +16,7 @@ Camdozaal (10) Capes (143) Castle Wars (39) Cerberus (7) -Chamber's of Xeric (23) +Chambers of Xeric (23) Champion's Challenge (11) Chaos Druids (3) Chaos Elemental (3) From af74d66aa57227613949b3e8aab0a44a3a7c526e Mon Sep 17 00:00:00 2001 From: gc <30398469+gc@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:38:34 +1100 Subject: [PATCH 15/19] Make ge price history use weekly averages --- src/mahoji/commands/ge.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/mahoji/commands/ge.ts b/src/mahoji/commands/ge.ts index 33cea0f5ed..d4ec891f94 100644 --- a/src/mahoji/commands/ge.ts +++ b/src/mahoji/commands/ge.ts @@ -392,11 +392,11 @@ The next buy limit reset is at: ${GrandExchange.getInterval().nextResetStr}, it return patronMsg(PerkTier.Four); } let result = await prisma.$queryRawUnsafe< - { quantity_bought: number; price_per_item_before_tax: number; created_at: Date }[] + { total_quantity_bought: number; average_price_per_item_before_tax: number; week: Date }[] >(`SELECT - sellTransactions.created_at, - sellTransactions.price_per_item_before_tax, - sellTransactions.quantity_bought + DATE_TRUNC('week', sellTransactions.created_at) AS week, + AVG(sellTransactions.price_per_item_before_tax) AS average_price_per_item_before_tax, + SUM(sellTransactions.quantity_bought) AS total_quantity_bought FROM ge_listing INNER JOIN @@ -407,15 +407,18 @@ AND ge_listing.cancelled_at IS NULL AND ge_listing.fulfilled_at IS NOT NULL +GROUP BY + week ORDER BY - sellTransactions.created_at ASC;`); - if (result.length < 2) return 'No price history found for that item.'; - if (result[0].price_per_item_before_tax <= 1_000_000) { - result = result.filter(i => i.quantity_bought > 1); + week ASC; +`); + if (result.length < 1) return 'No price history found for that item.'; + if (result[0].average_price_per_item_before_tax <= 1_000_000) { + result = result.filter(i => i.total_quantity_bought > 1); } const buffer = await lineChart( `Price History for ${item.name}`, - result.map(i => [new Date(i.created_at).toDateString(), i.price_per_item_before_tax]), + result.map(i => [new Date(i.week).toDateString(), i.average_price_per_item_before_tax]), val => val.toString(), val => val, false From c0595e800f8733d3d1d24b0ba27e1d8ff693adaf Mon Sep 17 00:00:00 2001 From: GC <30398469+gc@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:49:16 +1100 Subject: [PATCH 16/19] Cleanup ci tests (#5713) --- .github/workflows/codequality.yml | 69 ------------------- .../{inttests.yml => integration_tests.yml} | 0 .../workflows/{test.yml => unit_tests.yml} | 9 +++ 3 files changed, 9 insertions(+), 69 deletions(-) delete mode 100644 .github/workflows/codequality.yml rename .github/workflows/{inttests.yml => integration_tests.yml} (100%) rename .github/workflows/{test.yml => unit_tests.yml} (80%) diff --git a/.github/workflows/codequality.yml b/.github/workflows/codequality.yml deleted file mode 100644 index dbc51150ef..0000000000 --- a/.github/workflows/codequality.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Code Quality - -on: - push: - branches: - - master - - bso - pull_request: - -jobs: - ESLint: - name: ESLint - runs-on: ubuntu-latest - steps: - - name: Checkout Project - uses: actions/checkout@v3 - - name: Use Node.js 18.12.0 - uses: actions/setup-node@v3 - with: - node-version: 18.12.0 - cache: yarn - - name: Restore CI Cache - uses: actions/cache@v3 - with: - path: node_modules - key: ${{ runner.os }}-18-${{ hashFiles('**/yarn.lock') }} - - name: Install Dependencies - run: yarn --frozen-lockfile - - name: Generate Prisma Client - run: yarn gen - - name: Run ESLint on changed files - uses: tj-actions/eslint-changed-files@v21 - with: - skip_annotations: true - config_path: ".eslintrc.json" - ignore_path: ".eslintignore" - file_extensions: | - **/*.ts - **/*.tsx - - Typescript: - name: Typescript - runs-on: ubuntu-latest - steps: - - name: Checkout Project - uses: actions/checkout@v3 - - name: Use Node.js 18.12.0 - uses: actions/setup-node@v3 - with: - node-version: 18.12.0 - cache: yarn - - name: Restore CI Cache - uses: actions/cache@v3 - with: - path: node_modules - key: ${{ runner.os }}-18-${{ hashFiles('**/yarn.lock') }} - - name: Install Dependencies - run: yarn --frozen-lockfile - - name: Copy Configuration - run: | - pushd src && - cp config.example.ts config.ts && - popd - - name: Copy env - run: cp .env.example .env - - name: Generate Prisma Client - run: yarn gen - - name: Build code - run: yarn build diff --git a/.github/workflows/inttests.yml b/.github/workflows/integration_tests.yml similarity index 100% rename from .github/workflows/inttests.yml rename to .github/workflows/integration_tests.yml diff --git a/.github/workflows/test.yml b/.github/workflows/unit_tests.yml similarity index 80% rename from .github/workflows/test.yml rename to .github/workflows/unit_tests.yml index 82a0ad2867..bdfa62cdbc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/unit_tests.yml @@ -40,6 +40,15 @@ jobs: run: cp .env.example .env - name: Generate Prisma Client run: yarn gen + - name: Run ESLint on changed files + uses: tj-actions/eslint-changed-files@v21 + with: + skip_annotations: true + config_path: ".eslintrc.json" + ignore_path: ".eslintignore" + file_extensions: | + **/*.ts + **/*.tsx - name: Build run: yarn build - name: Test From 9f0736808e245e923c44cc85ad3786356461adb6 Mon Sep 17 00:00:00 2001 From: TastyPumPum <79149170+TastyPumPum@users.noreply.github.com> Date: Thu, 22 Feb 2024 06:51:40 +0000 Subject: [PATCH 17/19] Fix Zahur/Wesley Costs (#5706) Fix the check on wesley/zahur to pick the right cost if the users selects true to both options, it also returns the correct name. Closes #5698 --- src/mahoji/commands/mix.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mahoji/commands/mix.ts b/src/mahoji/commands/mix.ts index 14f553e2c6..900e8659a9 100644 --- a/src/mahoji/commands/mix.ts +++ b/src/mahoji/commands/mix.ts @@ -92,8 +92,10 @@ export const mixCommand: OSBMahojiCommand = { if ((zahur && mixableZahur) || (wesley && mixableWesley)) { timeToMixSingleItem = 0.000_001; - requiredItems.add('Coins', wesley ? 50 : 200); - cost = `decided to pay ${wesley ? 'Wesley 50' : 'Zahur 200'} gp for each item so they don't have to go`; + requiredItems.add('Coins', mixableWesley ? 50 : 200); + cost = `decided to pay ${ + mixableWesley ? 'Wesley 50' : 'Zahur 200' + } gp for each item so they don't have to go.`; } const maxTripLength = calcMaxTripLength(user, 'Herblore'); From cb94307932cfbf05a99856ac27c69114d6851012 Mon Sep 17 00:00:00 2001 From: gc <30398469+gc@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:52:33 +1100 Subject: [PATCH 18/19] Cant repeat stronghold --- src/lib/util/repeatStoredTrip.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/util/repeatStoredTrip.ts b/src/lib/util/repeatStoredTrip.ts index ceb8b12281..a41bbb3975 100644 --- a/src/lib/util/repeatStoredTrip.ts +++ b/src/lib/util/repeatStoredTrip.ts @@ -76,7 +76,8 @@ export const taskCanBeRepeated = (activity: Activity) => { activity_type_enum.BlastFurnace, activity_type_enum.Easter, activity_type_enum.TokkulShop, - activity_type_enum.Birdhouse + activity_type_enum.Birdhouse, + activity_type_enum.StrongholdOfSecurity ] as activity_type_enum[] ).includes(activity.type); }; From 982591e35bbbff81f59b2f25317256b7a4c82f6f Mon Sep 17 00:00:00 2001 From: gc <30398469+gc@users.noreply.github.com> Date: Thu, 22 Feb 2024 18:08:04 +1100 Subject: [PATCH 19/19] Add view_all_items rp action --- src/mahoji/commands/rp.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/mahoji/commands/rp.ts b/src/mahoji/commands/rp.ts index c7d5358205..9b653f75c6 100644 --- a/src/mahoji/commands/rp.ts +++ b/src/mahoji/commands/rp.ts @@ -21,7 +21,7 @@ import { allPerkBitfields } from '../../lib/perkTiers'; import { prisma } from '../../lib/settings/prisma'; import { TeamLoot } from '../../lib/simulation/TeamLoot'; import { ItemBank } from '../../lib/types'; -import { dateFm, formatDuration } from '../../lib/util'; +import { dateFm, formatDuration, returnStringOrFile } from '../../lib/util'; import getOSItem from '../../lib/util/getOSItem'; import { handleMahojiConfirmation } from '../../lib/util/handleMahojiConfirmation'; import { deferInteraction } from '../../lib/util/interactionReply'; @@ -72,6 +72,12 @@ export const rpCommand: OSBMahojiCommand = { name: 'patreon_reset', description: 'Reset all patreon data.', options: [] + }, + { + type: ApplicationCommandOptionType.Subcommand, + name: 'view_all_items', + description: 'View all item IDs present in banks/cls.', + options: [] } ] }, @@ -302,6 +308,7 @@ export const rpCommand: OSBMahojiCommand = { action?: { validate_ge?: {}; patreon_reset?: {}; + view_all_items?: {}; }; player?: { viewbank?: { user: MahojiUserOption; json?: boolean }; @@ -349,6 +356,18 @@ export const rpCommand: OSBMahojiCommand = { return 'Something was invalid. Check logs!'; } + if (options.action?.view_all_items) { + const result = await prisma.$queryRawUnsafe< + { item_id: number }[] + >(`SELECT DISTINCT json_object_keys(bank)::int AS item_id +FROM users +UNION +SELECT DISTINCT jsonb_object_keys("collectionLogBank")::int AS item_id +FROM users +ORDER BY item_id ASC;`); + return returnStringOrFile(`[${result.map(i => i.item_id).join(',')}]`); + } + if (options.action?.patreon_reset) { const bitfieldsToRemove = [ BitField.IsPatronTier1,