From a681b959bd747d09bd00097f3750bbaa1fa9d3f2 Mon Sep 17 00:00:00 2001 From: Ignose <128612824+Ignose@users.noreply.github.com> Date: Thu, 3 Oct 2024 23:06:17 -0400 Subject: [PATCH] Add Snapper as a valuable familiar for copyTarget freeFightFamiliars (#2132) * We snapper now * Check the right part of outfit spec * I mean - I hate this solution but it does work * I like this solution a lot better actually. * Value penguin envelopes actually * When Bill asks for a thing you do it * Change value to 50,000 per bean, improve the Snapper value logic to prevent Snapper at barf in weird circumstances * Create a denominator for snapper * Better denominator * We're learning things today * restructure implementation of `excludeFamiliar` * Back to includes it is * Update packages/garbo/src/familiar/freeFightFamiliar.ts * Update packages/garbo/src/familiar/lib.ts * Update packages/garbo/src/familiar/freeFightFamiliar.ts * Better filter and recommended changes * Update packages/garbo/src/fights.ts Co-authored-by: neil <78829653+horrible-little-slime@users.noreply.github.com> * Okeydoke. * Let's make Bill's change work by passing the entire fight. --------- Co-authored-by: horrible little slime <69secret69email69@gmail.com> Co-authored-by: Joe Kirchoff Co-authored-by: neil <78829653+horrible-little-slime@users.noreply.github.com> --- packages/garbo-lib/src/value.ts | 1 + .../garbo/src/familiar/freeFightFamiliar.ts | 31 ++++++++++++++----- packages/garbo/src/familiar/lib.ts | 17 ++++++++++ packages/garbo/src/fights.ts | 23 ++++++++++++-- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/packages/garbo-lib/src/value.ts b/packages/garbo-lib/src/value.ts index 3f5d6b9c1..ddb387c7f 100644 --- a/packages/garbo-lib/src/value.ts +++ b/packages/garbo-lib/src/value.ts @@ -199,6 +199,7 @@ export function makeValue( ), ], [$item`inflammable leaf`, inflammableLeafCurrency()], + [$item`envelope full of Meat`, () => 50_000], [ $item`crystalline cheer`, currency( diff --git a/packages/garbo/src/familiar/freeFightFamiliar.ts b/packages/garbo/src/familiar/freeFightFamiliar.ts index b8ed486c3..6e99f86b5 100644 --- a/packages/garbo/src/familiar/freeFightFamiliar.ts +++ b/packages/garbo/src/familiar/freeFightFamiliar.ts @@ -14,13 +14,14 @@ import { get, getModifier, have, + Snapper, } from "libram"; import { canOpenRedPresent } from "."; import { garboValue } from "../garboValue"; import getConstantValueFamiliars from "./constantValueFamiliars"; import getDropFamiliars from "./dropFamiliars"; import getExperienceFamiliars from "./experienceFamiliars"; -import { GeneralFamiliar, timeToMeatify } from "./lib"; +import { GeneralFamiliar, snapperValue, timeToMeatify } from "./lib"; import { meatFamiliar } from "./meatFamiliar"; import { gooseDroneEligible, valueDrops } from "../lib"; import { globalOptions } from "../config"; @@ -30,6 +31,7 @@ type MenuOptions = Partial<{ canChooseMacro: boolean; location: Location; extraFamiliars: GeneralFamiliar[]; + excludeFamiliar: Familiar[]; includeExperienceFamiliars: boolean; allowAttackFamiliars: boolean; mode: "barf" | "free" | "target"; @@ -38,6 +40,7 @@ const DEFAULT_MENU_OPTIONS = { canChooseMacro: true, location: $location`none`, extraFamiliars: [], + excludeFamiliar: [], includeExperienceFamiliars: true, allowAttackFamiliars: true, mode: "free", @@ -48,6 +51,7 @@ export function menu(options: MenuOptions = {}): GeneralFamiliar[] { canChooseMacro, location, extraFamiliars, + excludeFamiliar, allowAttackFamiliars, mode, } = { @@ -91,6 +95,16 @@ export function menu(options: MenuOptions = {}): GeneralFamiliar[] { limit: "experience", }); } + + if (mode === "target" && Snapper.have()) { + familiarMenu.push({ + familiar: $familiar`Red-Nosed Snapper`, + expectedValue: snapperValue(), + leprechaunMultiplier: 0, + limit: "special", + }); + } + if (canOpenRedPresent()) { familiarMenu.push({ familiar: $familiar`Crimbo Shrub`, @@ -128,13 +142,14 @@ export function menu(options: MenuOptions = {}): GeneralFamiliar[] { }); } - if (!allowAttackFamiliars) { - return familiarMenu.filter( - (fam) => !(fam.familiar.physicalDamage || fam.familiar.elementalDamage), - ); - } - - return familiarMenu; + return familiarMenu.filter( + ({ familiar }) => + (allowAttackFamiliars || + !(familiar.physicalDamage || familiar.elementalDamage)) && + !excludeFamiliar.some( + (excludedFamiliar) => excludedFamiliar === familiar, + ), + ); } export function getAllJellyfishDrops(): { diff --git a/packages/garbo/src/familiar/lib.ts b/packages/garbo/src/familiar/lib.ts index 7d33bfa44..aabf0831a 100644 --- a/packages/garbo/src/familiar/lib.ts +++ b/packages/garbo/src/familiar/lib.ts @@ -14,11 +14,14 @@ import { clamp, get, have, + Snapper, sumNumbers, } from "libram"; import { globalOptions } from "../config"; import { baseMeat, ESTIMATED_OVERDRUNK_TURNS, turnsToNC } from "../lib"; import { digitizedMonstersRemaining, estimatedGarboTurns } from "../turns"; +import { garboValue } from "../garboValue"; +import { copyTargetCount } from "../target"; export type GeneralFamiliar = { familiar: Familiar; @@ -131,3 +134,17 @@ export function estimatedBarfExperience(): number { return sumNumbers(sources); } + +export function snapperValue(): number { + const item = Snapper.phylumItem.get(globalOptions.target.phylum); + if (!item) return 0; + + const denominator = + 11 - + (Snapper.getTrackedPhylum() === globalOptions.target.phylum + ? Snapper.getProgress() + : 0); + if (denominator > copyTargetCount()) return 0; + + return garboValue(item) / denominator; +} diff --git a/packages/garbo/src/fights.ts b/packages/garbo/src/fights.ts index 3447bcf8c..3f2808c7c 100644 --- a/packages/garbo/src/fights.ts +++ b/packages/garbo/src/fights.ts @@ -97,6 +97,7 @@ import { Requirement, Robortender, set, + Snapper, SourceTerminal, sum, undelay, @@ -188,6 +189,7 @@ import { FreeGiantSandwormQuest, possibleFreeGiantSandwormQuestTentacleFights, } from "./tasks/freeGiantSandworm"; +import { CopyTargetFight } from "./target/fights"; const firstChainMacro = () => Macro.if_( @@ -370,13 +372,13 @@ function pygmyOptions(equip: Item[] = []): FreeFightOptions { }; } -function familiarSpec(underwater: boolean, fight: string): OutfitSpec { +function familiarSpec(underwater: boolean, fight: CopyTargetFight): OutfitSpec { if ( ChestMimic.have() && $familiar`Chest Mimic`.experience >= 50 && get("_mimicEggsObtained") < 11 && // switchmonster doesn't apply ML, meaning the target monsters die too quickly to get multiple eggs in - !["Macrometeorite", "Powerful Glove", "Backup"].includes(fight) + !["Macrometeorite", "Powerful Glove", "Backup"].includes(fight.name) ) { return { familiar: $familiar`Chest Mimic` }; } @@ -400,6 +402,14 @@ function familiarSpec(underwater: boolean, fight: string): OutfitSpec { } if (isFreeAndCopyable(globalOptions.target)) { + if (fight.gregariousReplace) { + return { + familiar: freeFightFamiliar({ + mode: "target", + excludeFamiliar: [$familiar`Red-Nosed Snapper`], + }), + }; + } return { familiar: freeFightFamiliar({ mode: "target" }) }; } @@ -528,7 +538,14 @@ export function dailyFights(): void { const location = new TargetFightRunOptions(nextFight).location; const underwater = location.environment === "underwater"; - const famSpec = familiarSpec(underwater, nextFight.name); + const famSpec = familiarSpec(underwater, nextFight); + + if ( + famSpec.familiar === $familiar`Red-Nosed Snapper` && + Snapper.getTrackedPhylum() !== globalOptions.target.phylum + ) { + Snapper.trackPhylum(globalOptions.target.phylum); + } setLocation(location); meatTargetOutfit({ ...nextFight.spec, ...famSpec }, location).dress();