From 0d87f209cbc614f465d5904bd3f6b3aefec03b82 Mon Sep 17 00:00:00 2001 From: Shiverwarp Date: Sat, 28 Sep 2024 17:05:24 -0600 Subject: [PATCH 1/2] Machine elf dupe (#2130) * We don't yachtzee anymore * Dupe with Machine Elf * Only dupe when ascending, value check * Check for having item, in case we lose it * encountersUntilDMTChoice does not reset on rollover * Owning melf important * billls conditional * Add comment * use retrieveItem --- packages/garbo/src/resources/realm.ts | 23 +---------- packages/garbo/src/tasks/barfTurn.ts | 56 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/packages/garbo/src/resources/realm.ts b/packages/garbo/src/resources/realm.ts index 77add5c90..3db311ba5 100644 --- a/packages/garbo/src/resources/realm.ts +++ b/packages/garbo/src/resources/realm.ts @@ -6,16 +6,7 @@ import { runChoice, visitUrl, } from "kolmafia"; -import { - $item, - get, - have, - maxBy, - property, - realmAvailable, - set, - withProperty, -} from "libram"; +import { $item, get, have, maxBy, property, set, withProperty } from "libram"; import { globalOptions } from "../config"; import { garboValue } from "../garboValue"; import { HIGHLIGHT } from "../lib"; @@ -29,17 +20,7 @@ function volcanoItemValue({ quantity, item }: VolcanoItem): number { if (!have($item`Clara's bell`) || globalOptions.clarasBellClaimed) { return Infinity; } - // Check if we can use Clara's bell for Yachtzee - // If so, we call the opportunity cost of this about 40k - if ( - realmAvailable("sleaze") && - have($item`fishy pipe`) && - !get("_fishyPipeUsed") - ) { - return quantity * 40000; - } else { - return quantity * get("valueOfAdventure"); - } + return quantity * get("valueOfAdventure"); } if (!item.tradeable) return Infinity; diff --git a/packages/garbo/src/tasks/barfTurn.ts b/packages/garbo/src/tasks/barfTurn.ts index 80f0c02ea..e04c97d60 100644 --- a/packages/garbo/src/tasks/barfTurn.ts +++ b/packages/garbo/src/tasks/barfTurn.ts @@ -4,16 +4,20 @@ import { canEquip, eat, getWorkshed, + Item, + itemAmount, Location, mallPrice, maximize, myAdventures, + myAscensions, myInebriety, myLevel, myLightning, myRain, myTurncount, outfitPieces, + retrieveItem, runChoice, totalTurnsPlayed, use, @@ -39,6 +43,7 @@ import { GingerBread, have, HeavyRains, + maxBy, questStep, realmAvailable, set, @@ -46,6 +51,7 @@ import { sum, TrainSet, undelay, + withProperty, } from "libram"; import { OutfitSpec, Quest } from "grimoire-kolmafia"; import { WanderDetails } from "garbo-lib"; @@ -321,6 +327,22 @@ function vampOut(additionalReady: () => boolean) { }; } +let bestDupeItem: Item | null = null; +function getBestDupeItem(): Item { + if (bestDupeItem === null || !have(bestDupeItem)) { + // Machine elf can dupe PVPable food, booze, spleen item or potion + const validItems = Item.all().filter( + (i) => + i.tradeable && + i.discardable && + (i.inebriety || i.fullness || i.potion || i.spleen) && + have(i), + ); + bestDupeItem = maxBy(validItems, garboValue); + } + return bestDupeItem; +} + function willDrunkAdventure() { return have($item`Drunkula's wineglass`) && globalOptions.ascend; } @@ -367,6 +389,40 @@ const NonBarfTurnTasks: AlternateTask[] = [ : 0, spendsTurn: true, }, + { + name: "Machine Elf Dupe", + ready: () => + have($familiar`Machine Elf`) && + // Dupe at end of day even if not ascending, encountersUntilDMTChoice does not reset on rollover + willDrunkAdventure() === !sober() && + get("encountersUntilDMTChoice") === 0 && + garboValue(getBestDupeItem()) > get("valueOfAdventure"), + completed: () => get("lastDMTDuplication") === myAscensions(), + do: $location`The Deep Machine Tunnels`, + prepare: () => { + if (itemAmount(getBestDupeItem()) === 0) { + withProperty("autoSatisfyWithMall", false, () => + retrieveItem(getBestDupeItem()), + ); + } + }, + outfit: () => + sober() + ? { + avoid: $items`Kramco Sausage-o-Maticâ„¢`, + familiar: $familiar`Machine Elf`, + } + : { + offhand: $item`Drunkula's wineglass`, + familiar: $familiar`Machine Elf`, + }, + combat: new GarboStrategy(() => + Macro.abortWithMsg("Hit unexpected combat!"), + ), + turns: () => 1, + spendsTurn: true, + choices: () => ({ 1119: 4, 1125: `1&iid=${getBestDupeItem().id}` }), + }, { name: "Lava Dogs (drunk)", ...lavaDogs(() => willDrunkAdventure(), { From 1fc80ed80cf9da39c05c8a73053d171f2aead6a4 Mon Sep 17 00:00:00 2001 From: neil <78829653+horrible-little-slime@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:31:23 -0400 Subject: [PATCH 2/2] slightly restructure GarboStrategy to allow customizing behavior with unexpected guests (#2140) * allow passing specific override options to `customizeMacro` * add `CustomizeMacroOptions` to the GarboStrategy constructor * basic combat for all! --- packages/garbo/src/combat.ts | 48 +++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/packages/garbo/src/combat.ts b/packages/garbo/src/combat.ts index 3b6f97da4..462e64e98 100644 --- a/packages/garbo/src/combat.ts +++ b/packages/garbo/src/combat.ts @@ -863,25 +863,42 @@ export class Macro extends StrictMacro { } } -function customizeMacro(macro: M) { +type CustomizeMacroOptions = { + freeWanderer: (macro: StrictMacro) => Macro; + tentacle: (macro: StrictMacro) => Macro; + innateWanderer: (macro: StrictMacro) => Macro; +}; +const DEFAULT_MACRO_OPTIONS = { + freeWanderer: () => Macro.basicCombat(), + tentacle: () => Macro.basicCombat(), + innateWanderer: (macro: StrictMacro) => + Macro.externalIf( + haveEquipped($item`backup camera`) && + get("_backUpUses") < 11 && + get("lastCopyableMonster") === globalOptions.target && + (!targettingMeat() || myFamiliar() === meatFamiliar()), + Macro.skill($skill`Back-Up to your Last Enemy`).step(macro), + Macro.basicCombat(), + ), +} as const satisfies CustomizeMacroOptions; + +function customizeMacro( + macro: M, + options: Partial = {}, +) { + const { freeWanderer, tentacle, innateWanderer } = { + ...DEFAULT_MACRO_OPTIONS, + ...options, + }; return Macro.if_( $monsters`giant rubber spider, time-spinner prank`, - Macro.kill(), + freeWanderer(macro), ) .externalIf( have($effect`Eldritch Attunement`), - Macro.if_($monster`Eldritch Tentacle`, Macro.basicCombat()), - ) - .ifInnateWanderer( - Macro.externalIf( - haveEquipped($item`backup camera`) && - get("_backUpUses") < 11 && - get("lastCopyableMonster") === globalOptions.target && - (!targettingMeat() || myFamiliar() === meatFamiliar()), - Macro.skill($skill`Back-Up to your Last Enemy`).step(macro), - Macro.basicCombat(), - ), + Macro.if_($monster`Eldritch Tentacle`, tentacle(macro)), ) + .ifInnateWanderer(innateWanderer(macro)) .step(macro); } @@ -964,11 +981,12 @@ export class GarboStrategy extends CombatStrategy { macro: () => Macro, postAuto = macro, useAutoAttack = () => true, + options: Partial = {}, ) { super(); - const macroCustom = () => customizeMacro(macro()); + const macroCustom = () => customizeMacro(macro(), options); if (useAutoAttack()) { - const postAutoCustom = () => customizeMacro(postAuto()); + const postAutoCustom = () => customizeMacro(postAuto(), options); this.autoattack(macroCustom).macro(postAutoCustom); } else { this.macro(macroCustom);