diff --git a/package.json b/package.json index a30d796..33531ac 100644 --- a/package.json +++ b/package.json @@ -25,15 +25,15 @@ "esbuild-plugin-babel": "^0.2.3", "eslint": "8.56.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-libram": "^0.4.27", + "eslint-plugin-libram": "^0.4.28", "eslint-plugin-prettier": "^4.2.1", "prettier": "^2.7.1", "typescript": "^4.7.4" }, "dependencies": { - "grimoire-kolmafia": "^0.3.29", + "grimoire-kolmafia": "^0.3.33", "kolmafia": "^5.28481.0", - "libram": "^0.11.0" + "libram": "^0.11.6" }, "author": "Phreddrickkv2", "license": "ISC", diff --git a/src/boozedrop.ts b/src/boozedrop.ts index 2934761..1a5e8aa 100644 --- a/src/boozedrop.ts +++ b/src/boozedrop.ts @@ -1,5 +1,5 @@ import { CSStrategy, Macro } from "./combat"; -import { aprilTask, asdonTask, deckTask, potionTask, skillTask, songTask } from "./commons"; +import { aprilTask, asdonTask, deckTask, potionTask, skillTask } from "./commons"; import { CSQuest } from "./engine"; import uniform from "./outfit"; import { OutfitSpec } from "grimoire-kolmafia"; @@ -64,7 +64,6 @@ const BoozeDrop: CSQuest = { class: $classes`Sauceror, Turtle Tamer`, core: "hard", }, - songTask($effect`Fat Leon's Phat Loot Lyric`, $effect`Ode to Booze`), { name: "Items.enh", completed: () => have($effect`items.enh`), diff --git a/src/combat.ts b/src/combat.ts index cb0526c..0cf5ca9 100644 --- a/src/combat.ts +++ b/src/combat.ts @@ -14,11 +14,11 @@ import { export class CSStrategy extends CombatStrategy { constructor( - macro: Delayed = () => Macro.defaultKill(), + macro: Delayed = () => Macro.defaultKill(), { fallthrough, fightHolidayWanderer, - }: { fallthrough?: Delayed; fightHolidayWanderer?: boolean } = {} + }: { fallthrough?: Delayed; fightHolidayWanderer?: boolean } = {} ) { super(); this.macro( diff --git a/src/commons.ts b/src/commons.ts index 81060fb..4c9e6f4 100644 --- a/src/commons.ts +++ b/src/commons.ts @@ -2,14 +2,17 @@ import { CSStrategy, Macro } from "./combat"; import { CSTask, currentBirdHas, favouriteBirdHas } from "./lib"; import uniform from "./outfit"; import { + abort, adv1, availableAmount, buy, + canEquip, cliExecute, create, eat, Effect, effectModifier, + equippedItem, getFuel, getProperty, handlingChoice, @@ -17,10 +20,12 @@ import { mpCost, myLevel, myMp, + npcPrice, runChoice, Skill, toEffect, toSkill, + toSlot, use, useSkill, } from "kolmafia"; @@ -147,13 +152,7 @@ export function commonFamiliarWeightBuffs(): CSTask[] { return [ potionTask($item`green candy heart`), ...restoreBuffTasks(buffs), - { - name: "Witchess", - completed: () => get("_witchessBuff"), - do: () => cliExecute("witchess"), - }, skillTask({ skill: $skill`Empathy of the Newt`, effect: $effect`Thoughtful Empathy` }, true), - beachTask($effect`Do I Know You From Somewhere?`), ]; } @@ -268,3 +267,34 @@ export function aprilTask(song: AprilingBandHelmet.MarchingSong): CSTask { do: () => AprilingBandHelmet.changeSong(song), }; } + +export function buskTask(hat: Item, shirt: Item, pants: Item, index: number): CSTask { + return { + name: `Busk #${index + 1}: ${hat}. ${shirt}, and ${pants}`, + outfit: { + hat, + shirt, + pants, + ...(hat === $item`prismatic beret` + ? {} + : { familiar: $familiar`Mad Hatrack`, famequip: $item`prismatic beret` }), + }, + acquire: () => + [hat, pants, shirt] + .filter((i) => i !== $item.none && !have(i) && npcPrice(i) > 0) + .map((item) => ({ item })), + ready: () => + [hat, shirt, pants].every( + (it) => it === $item.none || (canEquip(it) && (have(it) || npcPrice(it) > 0)) + ), + completed: () => get("_beretBuskingUses") !== index, + do: () => { + for (const [slotName, item] of Object.entries({ hat, shirt, pants })) { + if (equippedItem(toSlot(slotName)) !== item) + abort(`Failed to equip ${item} to ${slotName} for Busking!`); + } + useSkill($skill`Beret Busking`); + }, + core: "soft", + }; +} diff --git a/src/drinking.ts b/src/drinking.ts deleted file mode 100644 index 3a40f90..0000000 --- a/src/drinking.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { songTask } from "./commons"; -import { CSQuest } from "./engine"; -import { drink, itemAmount, myInebriety, use } from "kolmafia"; -import { $effect, $item, byStat, clamp, get, have } from "libram"; - -const totalInebriety = () => myInebriety() + get("_sweatOutSomeBoozeUsed"); -const Drink: CSQuest = { - name: "Drink Pilsners", - type: "MISC", - completed: () => totalInebriety() >= 5, - tasks: [ - { - name: "Open Pilsners", - completed: () => !have($item`astral six-pack`), - do: () => use($item`astral six-pack`), - }, - songTask( - $effect`Ode to Booze`, - byStat({ - Mysticality: $effect`The Magical Mojomuscular Melody`, - Muscle: $effect`Power Ballad of the Arrowsmith`, - Moxie: $effect`The Moxious Madrigal`, - }) - ), - { - name: "Drink Pilsners", - ready: () => have($item`astral pilsner`), - completed: () => totalInebriety() >= 5, - do: () => - drink( - $item`astral pilsner`, - clamp(itemAmount($item`astral pilsner`), 0, 5 - totalInebriety()) - ), - }, - ], -}; - -export default Drink; diff --git a/src/engine.ts b/src/engine.ts index 9583aea..83a5f3c 100644 --- a/src/engine.ts +++ b/src/engine.ts @@ -130,7 +130,9 @@ export class CSEngine extends Engine { Outfit.from( spec, new Error( - `Failed to equip outfit for ${this.name}. Also, that outfit is ${toJson(spec)}` + `Failed to equip outfit for ${this.name}. Also, that outfit is ${toJson( + Object.fromEntries(Object.entries(spec).filter(([key]) => key !== "afterDress")) + )}` ) ).dress(); burnLibrams(); diff --git a/src/familiarweight.ts b/src/familiarweight.ts index f0224c7..b7190f6 100644 --- a/src/familiarweight.ts +++ b/src/familiarweight.ts @@ -3,7 +3,7 @@ import { commonFamiliarWeightBuffs, meteorShower, potionTask } from "./commons"; import { CSQuest } from "./engine"; import { availableFights, unequip } from "./lib"; import uniform from "./outfit"; -import { create, mySign, runCombat, toInt, use, visitUrl } from "kolmafia"; +import { buy, create, mySign, runCombat, toInt, use, visitUrl } from "kolmafia"; import { $effect, $familiar, @@ -137,6 +137,8 @@ const FamiliarWeight: CSQuest = { ready: () => mySign() !== "Platypus", completed: () => get("moonTuned"), do: (): void => { + buy(1, $item`frilly skirt`); + buy(1, $item`maiden wig`); unequip($item`hewn moon-rune spoon`); visitUrl("inv_use.php?whichitem=10254&pwd&doit=96&whichsign=4"); }, diff --git a/src/gash/cs.ts b/src/gash/cs.ts index 71373d2..24c9d00 100644 --- a/src/gash/cs.ts +++ b/src/gash/cs.ts @@ -84,14 +84,7 @@ const SPECIAL_REQUIREMENTS: Record< bootRequirement($item`mountain lion skin`), ], Muscle: [bootRequirement($item`grizzled bearskin`)], - Mysticality: [ - { - name: "Meteor Necklace", - meets: () => !args.softcore || have($item`meteorite necklace`), - reason: "we don't start in a canadian moonsign!", - }, - bootRequirement($item`frontwinder skin`), - ], + Mysticality: [bootRequirement($item`frontwinder skin`)], }; export function main(input = ""): void { diff --git a/src/index.ts b/src/index.ts index 36d07d6..49d0d57 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,5 @@ import BoozeDrop from "./boozedrop"; import CoilWire from "./coilwire"; -import Drink from "./drinking"; import { CSEngine } from "./engine"; import FamiliarWeight from "./familiarweight"; import HotRes from "./hotres"; @@ -10,19 +9,21 @@ import Prologue from "./prologue"; import Spell from "./spell"; import StatTests from "./stattests"; import Weapon from "./weapon"; -import { sinceKolmafiaRevision } from "libram"; +import { logger, LogLevels, sinceKolmafiaRevision } from "libram"; -sinceKolmafiaRevision(28500); -CSEngine.runTests( - Prologue, - CoilWire, - Level, - ...StatTests, - Drink, - HotRes, - Noncombat, - FamiliarWeight, - Weapon, - Spell, - BoozeDrop -); +export function main() { + sinceKolmafiaRevision(28500); + logger.setLevel(LogLevels.DEBUG); + CSEngine.runTests( + Prologue, + CoilWire, + Level, + ...StatTests, + HotRes, + Noncombat, + FamiliarWeight, + Weapon, + Spell, + BoozeDrop + ); +} diff --git a/src/level.ts b/src/level.ts index 352dd7b..7c2d195 100644 --- a/src/level.ts +++ b/src/level.ts @@ -1,6 +1,7 @@ import { CSStrategy, Macro } from "./combat"; import { beachTask, + buskTask, favouriteBirdTask, innerElf, potionTask, @@ -9,7 +10,14 @@ import { skillTask, } from "./commons"; import { CSQuest } from "./engine"; -import { burnLibrams, guildQuestZone, peridotChoice, SYNTH_EFFECT, synthExp } from "./lib"; +import { + availableEmbers, + burnLibrams, + guildQuestZone, + peridotChoice, + SYNTH_EFFECT, + synthExp, +} from "./lib"; import uniform from "./outfit"; import { OutfitSpec } from "grimoire-kolmafia"; import { @@ -17,10 +25,10 @@ import { cliExecute, create, effectModifier, + equip, mpCost, myFamiliar, myHp, - myLevel, myMp, myPrimestat, numericModifier, @@ -34,6 +42,7 @@ import { visitUrl, } from "kolmafia"; import { + $coinmaster, $effect, $effects, $familiar, @@ -57,16 +66,12 @@ import { withProperties, } from "libram"; -const levellingComplete = myLevel() >= 13 && get("_neverendingPartyFreeTurns") >= 10; +const levellingComplete = get("csServicesPerformed").split(",").length > 1; let lovePotionConsidered = false; -const foldshirt = (): void => { - if (!have($item`makeshift garbage shirt`)) cliExecute("fold makeshift garbage shirt"); -}; - let queenPrep = false; const CastSkills = [ - ...$skills`Advanced Saucecrafting, Advanced Cocktailcrafting, Acquire Rhinestones, Prevent Scurvy and Sobriety, Stevedave's Shanty of Superiority, Fat Leon's Phat Loot Lyric, Paul's Passionate Pop Song, Leash of Linguini, Blood Bond, Blood Bubble, Song of Bravado, Get Big, Mathematical Precision, Ruthless Efficiency, Carol of the Bulls, Rage of the Reindeer, Disco Aerobics, Manicotti Meditation, Moxie of the Mariachi, Patience of the Tortoise, Sauce Contemplation, Seal Clubbing Frenzy`, + ...$skills`Advanced Saucecrafting, Advanced Cocktailcrafting, Acquire Rhinestones, Prevent Scurvy and Sobriety, Stevedave's Shanty of Superiority, Fat Leon's Phat Loot Lyric, Paul's Passionate Pop Song, Leash of Linguini, Blood Bond, Blood Bubble, Song of Bravado, Get Big, Mathematical Precision, Ruthless Efficiency, Carol of the Bulls, Rage of the Reindeer, Disco Aerobics, Manicotti Meditation, Moxie of the Mariachi, Patience of the Tortoise, Sauce Contemplation, Seal Clubbing Frenzy, Bend Hell, Astral Shell, Elemental Saucesphere, Scarysauce`, byStat({ Mysticality: $skill`The Magical Mojomuscular Melody`, Muscle: $skill`The Power Ballad of the Arrowsmith`, @@ -113,6 +118,65 @@ const Level: CSQuest = { name: "Level", completed: () => levellingComplete, tasks: [ + { + name: "Fold Shirt", + completed: () => have($item`makeshift garbage shirt`), + do: () => cliExecute("fold makeshift garbage shirt"), + }, + buskTask($item`norwhal helmet`, $item.none, $item`repaid diaper`, 0), + buskTask( + $item`Apriling band helmet`, + $item`makeshift garbage shirt`, + $item`union scalemail pants`, + 1 + ), + buskTask($item`coconut shell`, $item`fresh coat of paint`, $item.none, 2), + buskTask($item`norwhal helmet`, $item`fresh coat of paint`, $item`union scalemail pants`, 3), + buskTask($item.none, $item.none, $item`repaid diaper`, 4), + { + name: "Ember", + ready: () => + get("_beretBuskingUses") >= 5 && get("_loveTunnelUsed") && have($effect`Entauntauned`), + completed: () => availableEmbers() <= 0, + do: () => { + buy($coinmaster`Sept-Ember Censer`, 1, $item`Mmm-brr! brand mouthwash`); + use($item`Mmm-brr! brand mouthwash`); + }, + outfit: { + hat: $item`prismatic beret`, + weapon: $item`McHugeLarge right pole`, + offhand: $item`McHugeLarge left pole`, + back: $item`McHugeLarge duffel bag`, + shirt: $item`Jurassic Parka`, + modes: { parka: "kachungasaur" }, + pants: $item`repaid diaper`, + acc1: $item`your cowboy boots`, + acc2: $item`McHugeLarge left ski`, + acc3: $item`McHugeLarge right ski`, + // eslint-disable-next-line libram/verify-constants + familiar: $familiar`cooler yeti`, + famequip: $item`tiny stillsuit`, + beforeDress: [() => equip($familiar`Shorter-Order Cook`, $item`blue plate`)], + ...byStat({ + Muscle: { shirt: $item`LOV Eardigan` }, + Moxie: { acc1: $item`LOV Earrings` }, + Mysticality: { back: $item`LOV Epaulettes` }, + }), + }, + }, + { + name: "Slay Camel", + completed: () => get("_entauntaunedToday"), + ready: () => have($item`blue plate`), + outfit: () => ({ + familiar: $familiar`Melodramedary`, + weapon: $item`Fourth of May Cosplay Saber`, + }), + do: () => { + visitUrl("main.php?action=camel", false); + runChoice(1); + }, + }, innerElf(), { name: "That's Just Cloud Talk, Man", @@ -249,6 +313,13 @@ const Level: CSQuest = { ), ...restoreBuffTasks($effects`Empathy`), skillTask({ skill: $skill`Empathy of the Newt`, effect: $effect`Thoughtful Empathy` }, true), + potionTask($item`green candy heart`), + { + name: "Witchess", + completed: () => get("_witchessBuff"), + do: () => cliExecute("witchess"), + }, + beachTask($effect`Do I Know You From Somewhere?`), { name: "Get Range", completed: () => get("hasRange"), @@ -307,7 +378,7 @@ const Level: CSQuest = { completed: () => have($effect`Giant Growth`), ready: () => have($item`green mana`) && get("_snojoFreeFights") < 10, do: $location`The X-32-F Combat Training Snowman`, - outfit: uniform, + outfit: () => uniform(), combat: new CSStrategy(() => Macro.externalIf( !have($effect`Cosmic Ball in the Air`), @@ -325,7 +396,6 @@ const Level: CSQuest = { name: "Witch", completed: () => have($item`battle broom`), outfit: (): OutfitSpec => { - foldshirt(); return uniform({ changes: { weapon: byStat({ @@ -335,7 +405,7 @@ const Level: CSQuest = { shirt: $item`makeshift garbage shirt`, offhand: $item`familiar scrapbook`, familiar: $familiar`Shorter-Order Cook`, - famequip: $item`tiny stillsuit`, + famequip: $item`toy Cupid bow`, }, }); }, @@ -352,7 +422,6 @@ const Level: CSQuest = { do: () => Witchess.fightPiece($monster`Witchess King`), ready: () => Witchess.fightsDone() < 5, outfit: (): OutfitSpec => { - foldshirt(); return uniform({ changes: { weapon: byStat({ @@ -362,7 +431,7 @@ const Level: CSQuest = { shirt: $item`makeshift garbage shirt`, offhand: $item`familiar scrapbook`, familiar: $familiar`Shorter-Order Cook`, - famequip: $item`tiny stillsuit`, + famequip: $item`toy Cupid bow`, }, }); }, @@ -395,7 +464,6 @@ const Level: CSQuest = { do: () => Witchess.fightPiece($monster`Witchess Queen`), ready: () => Witchess.fightsDone() < 5, outfit: (): OutfitSpec => { - foldshirt(); return uniform({ changes: { weapon: byStat({ @@ -405,7 +473,7 @@ const Level: CSQuest = { shirt: $item`makeshift garbage shirt`, offhand: $item`familiar scrapbook`, familiar: $familiar`Shorter-Order Cook`, - famequip: $item`tiny stillsuit`, + famequip: $item`toy Cupid bow`, }, }); }, @@ -487,7 +555,6 @@ const Level: CSQuest = { name: "LOV", completed: () => get("_loveTunnelUsed"), outfit: (): OutfitSpec => { - foldshirt(); return uniform({ changes: { weapon: byStat({ @@ -532,14 +599,6 @@ const Level: CSQuest = { Moxie: $item`LOV Elixir #9`, }) ), - { - name: "Snojo", - completed: () => get("_snojoFreeFights") >= 10, - ready: () => !!get("snojoSetting"), - outfit: uniform, - do: $location`The X-32-F Combat Training Snowman`, - combat: new CSStrategy(() => Macro.delevel().easyFight().attack().repeat()), - }, { name: "Post-Snojo Hottub", completed: () => @@ -564,7 +623,7 @@ const Level: CSQuest = { } } }), - outfit: uniform, + outfit: () => uniform(), combat: new CSStrategy(() => Macro.delevel().candyblast().defaultKill()), }, { @@ -595,7 +654,6 @@ const Level: CSQuest = { completed: () => get("_machineTunnelsAdv") >= 5, do: $location`The Deep Machine Tunnels`, outfit: (): OutfitSpec => { - foldshirt(); return uniform({ changes: { shirt: $item`makeshift garbage shirt`, @@ -614,45 +672,11 @@ const Level: CSQuest = { runChoice(choice); }, }, - { - name: "NEP Spit", - completed: () => have($effect`Spit Upon`), - ready: () => - get("camelSpit") >= 100 && - have($familiar`Comma Chameleon`) && - get("_neverendingPartyFreeTurns") < 10, - do: $location`The Neverending Party`, - outfit: (): OutfitSpec => { - foldshirt(); - return uniform({ - changes: { - shirt: $items`makeshift garbage shirt`, - ...(get("_sausageFights") > 4 ? {} : { offhand: $item`Kramco Sausage-o-Matic™` }), - familiar: $familiar`Melodramedary`, - }, - }); - }, - combat: new CSStrategy(() => - Macro.trySkill($skill`%fn, spit on me!`) - .if_( - $effect`Inner Elf`, - Macro.if_( - `!hascombatitem ${$item`cosmic bowling ball`}`, - Macro.trySkill($skill`Feel Pride`) - ) - ) - .trySkill($skill`Bowl Sideways`) - .delevel() - .defaultKill() - ), - choices: { [1324]: 5 }, - }, { name: "Purple Candle Kramco", completed: () => getKramcoWandererChance() < 1, do: guildQuestZone, outfit: (): OutfitSpec => { - foldshirt(); return uniform({ changes: { shirt: $item`makeshift garbage shirt`, @@ -670,12 +694,33 @@ const Level: CSQuest = { .repeat() ), }, + /*{ + name: "Peridot NEP", + completed: () => !PeridotOfPeril.canImperil($location`The Neverending Party`), + do: $location`The Neverending Party`, + choices: peridotChoice($monster`jock`), + outfit: () => { + + return uniform({ + changes: { + acc3: $item`Peridot of Peril`, + }, + }); + }, + combat: new CSStrategy(() => + Macro.trySkill($skill`Feel Pride`) + .trySkill($skill`Feel Envy`) + .trySkill($skill`Bowl Sideways`) + .delevel() + .defaultKill() + ), + }, { name: "Regular NEP", completed: () => get("_neverendingPartyFreeTurns") >= 10, do: $location`The Neverending Party`, outfit: (): OutfitSpec => { - foldshirt(); + return uniform({ changes: { shirt: $items`makeshift garbage shirt`, @@ -696,42 +741,7 @@ const Level: CSQuest = { .defaultKill() ), choices: { [1324]: 5 }, - }, - { - name: "Freekill NEP", - completed: () => - get("_shatteringPunchUsed") >= 3 && - get("_gingerbreadMobHitUsed") && - have($effect`Everything Looks Yellow`) && - get("_chestXRayUsed") >= 3, - do: $location`The Neverending Party`, - outfit: (): OutfitSpec => { - foldshirt(); - const killSource = !have($effect`Everything Looks Yellow`) - ? { shirt: $item`Jurassic Parka`, modes: { parka: "dilophosaur" as const } } - : get("_chestXRayUsed") < 3 - ? { acc3: $item`Lil' Doctor™ bag` } - : {}; - const enoughSausages = get("_sausageFights") > 4; - const changes = { - shirt: $items`makeshift garbage shirt`, - ...killSource, - ...(enoughSausages ? {} : { offhand: $item`Kramco Sausage-o-Matic™` }), - }; - return uniform({ changes }); - }, - combat: new CSStrategy(() => - Macro.if_($monster`sausage goblin`, Macro.defaultKill()) - .trySkill($skill`Feel Pride`) - .trySkill($skill`Bowl Sideways`) - .trySkill($skill`Spit jurassic acid`) - .trySkill($skill`Chest X-Ray`) - .trySkill($skill`Shattering Punch`) - .trySkill($skill`Gingerbread Mob Hit`) - .abort() - ), - choices: { [1324]: 5 }, - }, + },*/ ], }; diff --git a/src/lib.ts b/src/lib.ts index 58be626..106f199 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -45,7 +45,7 @@ import { } from "libram"; import { NumericModifier } from "libram/dist/modifierTypes"; -export type CSTask = StrictCombatTask & { +export type CSTask = StrictCombatTask & { core?: Delayed<"hard" | "soft">; class?: Delayed; }; @@ -284,3 +284,5 @@ export const LEPRECONDO_CONFIG: Tuple = byStat({ }); export const peridotChoice = (monster: Monster) => ({ 1557: `1&bandersnatch=${monster.id}` }); + +export const availableEmbers = () => Math.floor(get("availableSeptEmbers") / 2); diff --git a/src/outfit.ts b/src/outfit.ts index 9190586..62b7698 100644 --- a/src/outfit.ts +++ b/src/outfit.ts @@ -1,5 +1,12 @@ import { OutfitSpec } from "grimoire-kolmafia"; -import { Familiar, Item, totalTurnsPlayed } from "kolmafia"; +import { + equip, + Familiar, + familiarEquippedEquipment, + inHardcore, + Item, + totalTurnsPlayed, +} from "kolmafia"; import { $effect, $familiar, @@ -80,7 +87,7 @@ const FAMILIAR_PICKS = [ { familiar: $familiar`Melodramedary`, famequip: () => $items`dromedary drinking helmet`.find((i) => have(i)), - condition: () => get("camelSpit") < 100 && !have($effect`Spit Upon`), + condition: () => get("camelSpit") < 100 && !have($effect`Spit Upon`) && inHardcore(), }, { familiar: $familiar`Shorter-Order Cook`, @@ -115,13 +122,24 @@ function chooseFamiliar(canAttack: boolean): Pick + have($item`blue plate`) && + familiarEquippedEquipment($familiar`Shorter-Order Cook`) !== $item`blue plate` && + equip($familiar`Shorter-Order Cook`, $item`blue plate`), + ]; + + return spec; } diff --git a/src/prologue.ts b/src/prologue.ts index 4172a99..29572c1 100644 --- a/src/prologue.ts +++ b/src/prologue.ts @@ -48,7 +48,7 @@ import { const PULLS = [ $items`repaid diaper, Great Wolf's beastly trousers`, - byStat({ Mysticality: $items`meteorite necklace`, default: $items`norwhal helmet` }), + $items`norwhal helmet`, $items`Stick-Knife of Loathing`, $items`Buddy Bjorn`, ]; @@ -266,6 +266,7 @@ const Prologue: CSQuest = { useFamiliar($familiar`Melodramedary`); cliExecute(`mummery ${myPrimestat().toString().toLowerCase()}`); }, + core: "hard", }, { name: "Shortsuit", diff --git a/src/spell.ts b/src/spell.ts index f739529..7198902 100644 --- a/src/spell.ts +++ b/src/spell.ts @@ -15,6 +15,7 @@ import { canadiaAvailable, canEquip, cliExecute, + Effect, myLevel, pullsRemaining, retrieveItem, @@ -36,6 +37,7 @@ import { getSaleValue, have, Horsery, + PrismaticBeret, } from "libram"; const buffs = $effects`Carol of the Hells, Arched Eyebrow of the Archmage, Song of Sauce`; @@ -58,6 +60,15 @@ const Spell: CSQuest = { : { familiar: $familiar`Left-Hand Man`, famequip: $item`astral statuette` }), back: $items`Buddy Bjorn, protonic accelerator pack`, riders: { "buddy-bjorn": $familiar`Mechanical Songbird` }, + afterDress: [ + () => { + while (get("_beretBuskingUses") < 5) + PrismaticBeret.buskFor( + { "Spell Damage": 1, "Spell Damage Percent": 1 }, + { buyItems: true, uselessEffects: Effect.all().filter((e) => have(e)) } + ); + }, + ], }), maxTurns: 30, tasks: [ diff --git a/src/weapon.ts b/src/weapon.ts index e5d9b65..8270e6f 100644 --- a/src/weapon.ts +++ b/src/weapon.ts @@ -122,7 +122,8 @@ const Weapon: CSQuest = { const changes: OutfitSpec = { weapon: $item`Fourth of May Cosplay Saber`, }; - if (get("camelSpit") >= 100) changes.familiar = $familiar`Melodramedary`; + if (get("camelSpit") >= 100 && !have($effect`Spit Upon`)) + changes.familiar = $familiar`Melodramedary`; return uniform({ changes, canAttack: false }); }, post: (): void => { diff --git a/yarn.lock b/yarn.lock index 4df1bf2..4a19bad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2472,13 +2472,13 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-libram@npm:^0.4.27": - version: 0.4.27 - resolution: "eslint-plugin-libram@npm:0.4.27" +"eslint-plugin-libram@npm:^0.4.28": + version: 0.4.28 + resolution: "eslint-plugin-libram@npm:0.4.28" dependencies: html-entities: "npm:^2.5.2" requireindex: "npm:~1.2.0" - checksum: 10c0/9e571eddc0ba1498c84a6945547f7289098cd93e96769821e6e2fd7261baa81b911567a9d2597f4cc690d4425ab29ac86036417e172128c2ac2385d65b73ff40 + checksum: 10c0/5eb52d9043b71e78b1ea6be2a23eb503e8946be810c986a5f2c9260e643eed26dee00c71bbcb298e66c2be762374af0a0e140dfa5f378cb6ef87a7279d4c642d languageName: node linkType: hard @@ -2833,15 +2833,15 @@ __metadata: languageName: node linkType: hard -"grimoire-kolmafia@npm:^0.3.29": - version: 0.3.29 - resolution: "grimoire-kolmafia@npm:0.3.29" +"grimoire-kolmafia@npm:^0.3.33": + version: 0.3.33 + resolution: "grimoire-kolmafia@npm:0.3.33" dependencies: core-js: "npm:^3.16.4" peerDependencies: kolmafia: ^5.28100.0 libram: ^0.10.0 - checksum: 10c0/9b34e4bfd44492e79c1c0105b42d159168115c98b01688ac949f066f7da7dba441e5a0159489b8cc56b871ba80918a797847ff7931f4da381811dba535896a46 + checksum: 10c0/a29c53875e6aaa397567857818366237fd80f28e08f0cfc86cd5358de3b7c1e1cdd55d860ec522ce794a39d211eea960e78be781690d190846f0bbf9424490c1 languageName: node linkType: hard @@ -3081,14 +3081,14 @@ __metadata: languageName: node linkType: hard -"libram@npm:^0.11.0": - version: 0.11.0 - resolution: "libram@npm:0.11.0" +"libram@npm:^0.11.6": + version: 0.11.6 + resolution: "libram@npm:0.11.6" dependencies: html-entities: "npm:^2.5.2" peerDependencies: kolmafia: ^5.28100.0 - checksum: 10c0/3af156ad5519e95862fdcc4abd061c920e513f1ac06af0f986c639af10d7ecd583efb6d9a8b40da56467e993fab57a77550e7e141212d0cfc7247469ddcba3f3 + checksum: 10c0/6e77a0771f45e3f74148db97ab3a616818970f756bf01a596a85a979d7a4f3e081ab0f7363eb6d3b1d8ee59f7ead96d8b57ed70c06a2f7b348826c42fb0f098f languageName: node linkType: hard @@ -3323,11 +3323,11 @@ __metadata: esbuild-plugin-babel: "npm:^0.2.3" eslint: "npm:8.56.0" eslint-config-prettier: "npm:^8.5.0" - eslint-plugin-libram: "npm:^0.4.27" + eslint-plugin-libram: "npm:^0.4.28" eslint-plugin-prettier: "npm:^4.2.1" - grimoire-kolmafia: "npm:^0.3.29" + grimoire-kolmafia: "npm:^0.3.33" kolmafia: "npm:^5.28481.0" - libram: "npm:^0.11.0" + libram: "npm:^0.11.6" prettier: "npm:^2.7.1" typescript: "npm:^4.7.4" languageName: unknown