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

Bofa wish fights #1745

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/garbo-lib/src/wanderer/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
103 changes: 103 additions & 0 deletions packages/garbo/src/fights.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Outfit, OutfitSpec } from "grimoire-kolmafia";
import {
adv1,
appearanceRates,
availableAmount,
buy,
canAdventure,
Expand All @@ -15,13 +16,15 @@ import {
familiarEquippedEquipment,
getAutoAttack,
getCampground,
getMonsters,
haveEquipped,
haveOutfit,
inebrietyLimit,
isBanished,
Item,
itemAmount,
itemDropsArray,
itemFact,
Location,
mallPrice,
maximize,
Expand Down Expand Up @@ -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";
Comment on lines +185 to +189
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't how we should accomplish this; we should either use a new wanderer type or an existing wanderer type, or export those functions from garbo-lib through ./wanderer


const firstChainMacro = () =>
Macro.if_(
Expand Down Expand Up @@ -1383,6 +1391,51 @@ 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 &&
Shiverwarp marked this conversation as resolved.
Show resolved Hide resolved
shouldDoBofaFishing() &&
findFreeKill() !== null &&
getBestBofaWishLocation() !== null &&
unlock(
getBestBofaWishLocation(),
(3 - get("_bookOfFactsWishes")) * garboValue($item`pocket wish`),
Shiverwarp marked this conversation as resolved.
Show resolved Hide resolved
),
(runSource: ActionSource) => {
const best = getBestBofaWishLocation();
if (!best) throw `Bofa wish location should exist, but doesn't`;
Shiverwarp marked this conversation as resolved.
Show resolved Hide resolved
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),
Shiverwarp marked this conversation as resolved.
Show resolved Hide resolved
);
},
{
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;
Shiverwarp marked this conversation as resolved.
Show resolved Hide resolved
},
},
),
// Fire Extinguisher on best available target.
new FreeRunFight(
() =>
Expand Down Expand Up @@ -2667,3 +2720,53 @@ 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
Shiverwarp marked this conversation as resolved.
Show resolved Hide resolved
);
}
}

function getBestBofaWishLocation() {
return maxBy(
Location.all().filter(
(l) => canAdventureOrUnlock(l) && canWander(l, "backup"),
),
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;
}