From f4e01f6ebd820ba740ff9ceccb05dddfe3a1fefc Mon Sep 17 00:00:00 2001 From: Shiverwarp Date: Mon, 20 Nov 2023 14:52:46 -0700 Subject: [PATCH 1/7] Bofa wish fights, check for having the skill --- packages/garbo-lib/src/wanderer/lib.ts | 1 + packages/garbo/src/fights.ts | 80 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/packages/garbo-lib/src/wanderer/lib.ts b/packages/garbo-lib/src/wanderer/lib.ts index 4d4e5bfb2..ad686d3b5 100644 --- a/packages/garbo-lib/src/wanderer/lib.ts +++ b/packages/garbo-lib/src/wanderer/lib.ts @@ -309,6 +309,7 @@ export function bofaValue( { plentifulMonsters, itemValue, effectValue }: WandererFactoryOptions, monster: Monster, ): number { + if (!have($skill`Just the Facts`)) return 0; switch (monster.factType) { case "item": { const item = itemFact(monster); diff --git a/packages/garbo/src/fights.ts b/packages/garbo/src/fights.ts index 5974d8788..8943925d2 100644 --- a/packages/garbo/src/fights.ts +++ b/packages/garbo/src/fights.ts @@ -1,6 +1,7 @@ import { Outfit, OutfitSpec } from "grimoire-kolmafia"; import { adv1, + appearanceRates, availableAmount, buy, canAdventure, @@ -15,6 +16,7 @@ import { familiarEquippedEquipment, getAutoAttack, getCampground, + getMonsters, haveEquipped, haveOutfit, inebrietyLimit, @@ -22,6 +24,7 @@ import { Item, itemAmount, itemDropsArray, + itemFact, Location, mallPrice, maximize, @@ -179,6 +182,11 @@ import { FreeFightQuest, runGarboQuests } from "./tasks"; import { expectedFreeFights, possibleTentacleFights } from "./tasks/freeFight"; import { bestMidnightAvailable } from "./resources"; import { PostQuest } from "./tasks/post"; +import { + canAdventureOrUnlock, + canWander, + unlock, +} from "garbo-lib/dist/wanderer/lib"; const firstChainMacro = () => Macro.if_( @@ -1383,6 +1391,50 @@ const freeRunFightSources = [ }, freeRunConstraints(true), ), + // Use free runs and free kills to get our bofa wishes + new FreeRunFight( + () => + have($skill`Just the Facts`) && + get("_bookOfFactsWishes") < 3 && + findFreeKill() !== null && + getBestBofaWishLocation() !== null && + unlock( + getBestBofaWishLocation(), + (3 - get("_bookOfFactsWishes")) * garboValue($item`pocket wish`), + ), + (runSource: ActionSource) => { + const best = getBestBofaWishLocation(); + if (!best) throw `Bofa wish location should exist, but doesn't`; + const wishMonsters = getMonsters(best).filter( + (m) => itemFact(m) === $item`pocket wish`, + ); + const freeKill = findFreeKill(); + if (!freeKill) { + throw `We should have a free kill for bofa wishes, but don't`; + } + const freeKillMacro = + freeKill.macro instanceof Item + ? Macro.item(freeKill.macro) + : Macro.skill(freeKill.macro); + garboAdventure( + best, + Macro.if_( + wishMonsters.map((m) => `!monsterid ${m.id}`).join(" && "), + runSource.macro, + ).step(freeKillMacro), + ); + }, + { + spec: () => { + const freeKill = findFreeKill(); + if (!freeKill) { + throw `We should have a free kill for bofa wishes, but don't`; + } + const spec: OutfitSpec = freeKill.spec ?? {}; + return spec; + }, + }, + ), // Fire Extinguisher on best available target. new FreeRunFight( () => @@ -2667,3 +2719,31 @@ function runShadowRiftTurn(): void { adv1(bestShadowRift(), -1, ""); // We wanted to use NC forcers, but none are suitable now } } + +function bofaWishMonsterRatio(location: Location) { + const badAttributes = ["LUCKY", "ULTRARARE", "BOSS"]; + const rates = appearanceRates(location); + const monsters = getMonsters(location).filter( + (m) => + !badAttributes.some((s) => m.attributes.includes(s)) && rates[m.name] > 0, + ); + + if (monsters.length === 0) { + return 0; + } else { + return ( + sum(monsters, (m) => { + return itemFact(m) === $item`pocket wish` ? 1 : 0; + }) / monsters.length + ); + } +} + +function getBestBofaWishLocation() { + return maxBy( + Location.all().filter( + (l) => canAdventureOrUnlock(l) && canWander(l, "backup"), + ), + bofaWishMonsterRatio, + ); +} From 401b8cfb30ab5041999afd5faefaab6aa06c13e6 Mon Sep 17 00:00:00 2001 From: Shiverwarp Date: Mon, 20 Nov 2023 16:46:21 -0700 Subject: [PATCH 2/7] Add plentifulmonsters check --- packages/garbo/src/fights.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/garbo/src/fights.ts b/packages/garbo/src/fights.ts index 8943925d2..404093627 100644 --- a/packages/garbo/src/fights.ts +++ b/packages/garbo/src/fights.ts @@ -1396,6 +1396,7 @@ const freeRunFightSources = [ () => have($skill`Just the Facts`) && get("_bookOfFactsWishes") < 3 && + shouldDoBofaFishing() && findFreeKill() !== null && getBestBofaWishLocation() !== null && unlock( @@ -2747,3 +2748,25 @@ function getBestBofaWishLocation() { bofaWishMonsterRatio, ); } + +function shouldDoBofaFishing() { + const plentifulMonsters = [ + $monster`Knob Goblin Embezzler`, + ...(globalOptions.nobarf ? [] : getMonsters($location`Barf Mountain`)), + ...(have($item`Kramco Sausage-o-Maticâ„¢`) ? $monsters`sausage goblin` : []), + ...(get("questL11Worship") !== "unstarted" && + bowlOfScorpionsAvailable() && + !pygmySniffed() && + clamp(9 - get("_drunkPygmyBanishes"), 0, 9) > 3 + ? $monsters`drunk pygmy` + : []), + ]; + if ( + plentifulMonsters.some( + (monster) => itemFact(monster) === $item`pocket wish`, + ) + ) { + return false; + } + return true; +} From c01f568c491cb23593237ca72204e9b67b59a44f Mon Sep 17 00:00:00 2001 From: Shiverwarp Date: Wed, 22 Nov 2023 11:02:08 -0700 Subject: [PATCH 3/7] Cleaner pocket wish monster ratio Co-authored-by: neil <78829653+horrible-little-slime@users.noreply.github.com> --- packages/garbo/src/fights.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/garbo/src/fights.ts b/packages/garbo/src/fights.ts index 404093627..4f1475cdc 100644 --- a/packages/garbo/src/fights.ts +++ b/packages/garbo/src/fights.ts @@ -2733,9 +2733,7 @@ function bofaWishMonsterRatio(location: Location) { return 0; } else { return ( - sum(monsters, (m) => { - return itemFact(m) === $item`pocket wish` ? 1 : 0; - }) / monsters.length + monsters.filter((m) => itemFact(m) === $item`pocket wish`).length / monsters.length ); } } From 40fb01ff4c215112f6f3f6553a85461fef13be3c Mon Sep 17 00:00:00 2001 From: Shiverwarp Date: Wed, 22 Nov 2023 11:02:23 -0700 Subject: [PATCH 4/7] Cleaner spec Co-authored-by: neil <78829653+horrible-little-slime@users.noreply.github.com> --- packages/garbo/src/fights.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/garbo/src/fights.ts b/packages/garbo/src/fights.ts index 4f1475cdc..63860ccb9 100644 --- a/packages/garbo/src/fights.ts +++ b/packages/garbo/src/fights.ts @@ -1431,8 +1431,7 @@ const freeRunFightSources = [ if (!freeKill) { throw `We should have a free kill for bofa wishes, but don't`; } - const spec: OutfitSpec = freeKill.spec ?? {}; - return spec; + return freeKill.spec ?? {}; }, }, ), From 533508474d78529e2906c78661280726e8933646 Mon Sep 17 00:00:00 2001 From: Shiverwarp Date: Wed, 22 Nov 2023 11:04:15 -0700 Subject: [PATCH 5/7] Proper throw Co-authored-by: neil <78829653+horrible-little-slime@users.noreply.github.com> --- packages/garbo/src/fights.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/garbo/src/fights.ts b/packages/garbo/src/fights.ts index 63860ccb9..9b02b90ff 100644 --- a/packages/garbo/src/fights.ts +++ b/packages/garbo/src/fights.ts @@ -1405,7 +1405,7 @@ const freeRunFightSources = [ ), (runSource: ActionSource) => { const best = getBestBofaWishLocation(); - if (!best) throw `Bofa wish location should exist, but doesn't`; + if (!best) throw new Error("Bofa wish location should exist, but doesn't"); const wishMonsters = getMonsters(best).filter( (m) => itemFact(m) === $item`pocket wish`, ); From 871a1a09cfcc0e7a98cdc868edc09c413d760063 Mon Sep 17 00:00:00 2001 From: Shiverwarp Date: Wed, 22 Nov 2023 11:07:43 -0700 Subject: [PATCH 6/7] Clamp and move checks into bofaFish --- packages/garbo/src/fights.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/garbo/src/fights.ts b/packages/garbo/src/fights.ts index 9b02b90ff..b00f8c71f 100644 --- a/packages/garbo/src/fights.ts +++ b/packages/garbo/src/fights.ts @@ -1394,18 +1394,19 @@ const freeRunFightSources = [ // Use free runs and free kills to get our bofa wishes new FreeRunFight( () => - have($skill`Just the Facts`) && - get("_bookOfFactsWishes") < 3 && shouldDoBofaFishing() && findFreeKill() !== null && getBestBofaWishLocation() !== null && unlock( getBestBofaWishLocation(), - (3 - get("_bookOfFactsWishes")) * garboValue($item`pocket wish`), + clamp(3 - get("_bookOfFactsWishes"), 0, 3) * + garboValue($item`pocket wish`), ), (runSource: ActionSource) => { const best = getBestBofaWishLocation(); - if (!best) throw new Error("Bofa wish location should exist, but doesn't"); + if (!best) { + throw new Error("Bofa wish location should exist, but doesn't"); + } const wishMonsters = getMonsters(best).filter( (m) => itemFact(m) === $item`pocket wish`, ); @@ -2732,7 +2733,8 @@ function bofaWishMonsterRatio(location: Location) { return 0; } else { return ( - monsters.filter((m) => itemFact(m) === $item`pocket wish`).length / monsters.length + monsters.filter((m) => itemFact(m) === $item`pocket wish`).length / + monsters.length ); } } @@ -2761,7 +2763,9 @@ function shouldDoBofaFishing() { if ( plentifulMonsters.some( (monster) => itemFact(monster) === $item`pocket wish`, - ) + ) || + !have($skill`Just the Facts`) || + get("_bookOfFactsWishes") >= 3 ) { return false; } From 6dc717c87e332e1718cd7df191e2ede879b01a32 Mon Sep 17 00:00:00 2001 From: Shiverwarp Date: Wed, 22 Nov 2023 11:10:22 -0700 Subject: [PATCH 7/7] Clean up macro --- packages/garbo/src/fights.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/garbo/src/fights.ts b/packages/garbo/src/fights.ts index b00f8c71f..86b0299a5 100644 --- a/packages/garbo/src/fights.ts +++ b/packages/garbo/src/fights.ts @@ -1412,7 +1412,9 @@ const freeRunFightSources = [ ); const freeKill = findFreeKill(); if (!freeKill) { - throw `We should have a free kill for bofa wishes, but don't`; + throw new Error( + "We should have a free kill for bofa wishes, but don't", + ); } const freeKillMacro = freeKill.macro instanceof Item @@ -1420,10 +1422,7 @@ const freeRunFightSources = [ : Macro.skill(freeKill.macro); garboAdventure( best, - Macro.if_( - wishMonsters.map((m) => `!monsterid ${m.id}`).join(" && "), - runSource.macro, - ).step(freeKillMacro), + Macro.if_(wishMonsters, freeKillMacro).step(runSource.macro), ); }, {