diff --git a/src/lib.ts b/src/lib.ts index 71cbe37..333cd0f 100644 --- a/src/lib.ts +++ b/src/lib.ts @@ -703,6 +703,12 @@ export function saveLeafyBoys(): boolean { return false; } +export function shouldFeelLost(): boolean { + if (have($familiar`Machine Elf`)) return false; + if (!have($skill`Feel Lost`)) return false; + return true; +} + export function checkTurnSave(test: string, ef: Effect): number { switch (test) { case "BoozeDrop": diff --git a/src/resources.ts b/src/resources.ts index 2a3f7c0..45dbee5 100644 --- a/src/resources.ts +++ b/src/resources.ts @@ -35,7 +35,6 @@ const consumptionResources: Resource[] = [ ), new Resource("instant_savePerfectFreeze", "Do not craft and drink a perfect drink"), new Resource("instant_saveBeesKnees", "Do not buy and drink Bee's Knees"), - new Resource("instant_saveSockdollager", "Do not buy and drink a sockdollager"), new Resource("instant_saveSacramentoWine", "Do not drink a Sacramento Wine for the item test"), new Resource("instant_skipSynthExp", "Do not use synth for the Xp% buff"), new Resource( diff --git a/src/tasks/boozedrop.ts b/src/tasks/boozedrop.ts index 48be14d..29851c9 100644 --- a/src/tasks/boozedrop.ts +++ b/src/tasks/boozedrop.ts @@ -14,8 +14,11 @@ import { itemAmount, myClass, myInebriety, + myMaxhp, myMeat, print, + restoreHp, + restoreMp, retrieveItem, runChoice, sweetSynthesis, @@ -27,12 +30,14 @@ import { import { $coinmaster, $effect, + $effects, $familiar, $item, $location, $monster, $skill, $slot, + clamp, CombatLoversLocket, CommunityService, DaylightShavings, @@ -47,12 +52,13 @@ import { checkValue, fuelUp, logTestSetup, + shouldFeelLost, tryAcquiringEffect, wishFor, } from "../lib"; import { chooseFamiliar, sugarItemsAboutToBreak } from "../engine/outfit"; import { CombatStrategy } from "grimoire-kolmafia"; -import Macro from "../combat"; +import Macro, { haveFreeBanish } from "../combat"; import { forbiddenEffects } from "../resources"; import { drive } from "libram/dist/resources/2017/AsdonMartin"; @@ -126,9 +132,42 @@ export const BoozeDropQuest: Quest = { }, limit: { tries: 1 }, }, + { + name: "Item Buff if Feeling Lost", + ready: () => shouldFeelLost(), + prepare: (): void => { + restoreHp(clamp(1000, myMaxhp() / 2, myMaxhp())); + restoreMp(50); + }, + completed: () => + (!have($familiar`Ghost of Crimbo Carols`) && + !have($item`cosmic bowling ball`) && + !have($item`vampyric cloake`)) || + !haveFreeBanish() || + $effects`Cosmic Ball in the Air, Do You Crush What I Crush?, Bat-Adjacent Form`.some((ef) => + have(ef) + ), + do: $location`The Dire Warren`, + combat: new CombatStrategy().macro( + Macro.trySkill($skill`Bowl Straight Up`) + .trySkill($skill`Become a Bat`) + .trySkill($skill`Use the Force`) + .banish() + .abort() + ), + outfit: { + offhand: $item`latte lovers member's mug`, + acc1: $item`Kremlin's Greatest Briefcase`, + acc2: $item`Lil' Doctorâ„¢ bag`, + familiar: $familiar`Ghost of Crimbo Carols`, + famequip: $item.none, + }, + limit: { tries: 5 }, + }, { name: "Fax Ungulith", - completed: () => have($item`corrupted marrow`) || have($effect`Cowrruption`), + completed: () => + have($item`corrupted marrow`) || have($effect`Cowrruption`) || shouldFeelLost(), do: (): void => { const monsterCow = myClass().toString() === "Seal Clubber" && @@ -283,20 +322,8 @@ export const BoozeDropQuest: Quest = { }, { name: "Feeling Lost", - ready: () => CommunityService.SpellDamage.isDone(), - completed: () => have($effect`Feeling Lost`) || !have($skill`Feel Lost`), - do: () => useSkill($skill`Feel Lost`), - limit: { tries: 1 }, - }, - { - name: "Alternative Feeling Lost", - completed: () => - have($effect`Feeling Lost`) || - !have($skill`Feel Lost`) || - get("camelSpit") >= 100 || - have($familiar`Machine Elf`) || - have($skill`Meteor Lore`) || - have($familiar`Ghost of Crimbo Carols`), + ready: () => shouldFeelLost(), + completed: () => have($effect`Feeling Lost`), do: () => useSkill($skill`Feel Lost`), limit: { tries: 1 }, }, diff --git a/src/tasks/spelldamage.ts b/src/tasks/spelldamage.ts index 734fadc..ea50768 100644 --- a/src/tasks/spelldamage.ts +++ b/src/tasks/spelldamage.ts @@ -41,6 +41,7 @@ import { checkTurnSave, checkValue, logTestSetup, + shouldFeelLost, shrugAT, startingClan, tryAcquiringEffect, @@ -50,6 +51,8 @@ import { chooseFamiliar, sugarItemsAboutToBreak } from "../engine/outfit"; import { forbiddenEffects } from "../resources"; let triedDeepDark = false; +// eslint-disable-next-line no-octal +const barrels = [0o0, 0o1, 0o2, 10, 11, 12, 20, 21, 22]; export const SpellDamageQuest: Quest = { name: "Spell Damage", @@ -85,6 +88,7 @@ export const SpellDamageQuest: Quest = { }, { name: "Stand-Alone Carol Ghost Buff", + ready: () => !shouldFeelLost(), prepare: (): void => { restoreHp(clamp(1000, myMaxhp() / 2, myMaxhp())); restoreMp(50); @@ -137,6 +141,7 @@ export const SpellDamageQuest: Quest = { }, { name: "Meteor Shower", + ready: () => !shouldFeelLost(), completed: () => have($effect`Meteor Showered`) || !have($item`Fourth of May Cosplay Saber`) || @@ -164,6 +169,46 @@ export const SpellDamageQuest: Quest = { choices: { 1387: 3 }, limit: { tries: 1 }, }, + { + name: "Meteor Shower Feeling Lost", + ready: () => shouldFeelLost(), + completed: () => + have($effect`Meteor Showered`) || + !have($item`Fourth of May Cosplay Saber`) || + !have($skill`Meteor Lore`) || + get("_saberForceUses") >= 5, + do: (): void => { + if (get("_leafMonstersFought", 0) < 5 && have($item`inflammable leaf`, 11)) { + visitUrl("campground.php?preaction=leaves"); + visitUrl("choice.php?pwd&whichchoice=1510&option=1&leaves=11"); + } else { + for (const barrel of barrels) { + visitUrl("barrel.php"); + visitUrl(`choice.php?whichchoice=1099&pwd&option=1&slot=${barrel}`); + } + } + }, + combat: new CombatStrategy().macro( + Macro.trySkill($skill`Meteor Shower`) + .trySkill($skill`%fn, spit on me!`) + .trySkill($skill`Use the Force`) + .abort() + ), + outfit: () => ({ + weapon: $item`Fourth of May Cosplay Saber`, + familiar: + get("camelSpit") >= 100 + ? $familiar`Melodramedary` + : $effects`Do You Crush What I Crush?, Holiday Yoked, Let It Snow/Boil/Stink/Frighten/Grease, All I Want For Crimbo Is Stuff, Crimbo Wrapping`.some( + (ef) => have(ef) + ) + ? $familiar`Ghost of Crimbo Carols` + : chooseFamiliar(false), + avoid: sugarItemsAboutToBreak(), + }), + choices: { 1387: 3 }, + limit: { tries: 10 }, + }, { name: "Deep Dark Visions", completed: () => diff --git a/src/tasks/weapondamage.ts b/src/tasks/weapondamage.ts index 67bfab7..424826d 100644 --- a/src/tasks/weapondamage.ts +++ b/src/tasks/weapondamage.ts @@ -1,13 +1,17 @@ import { CombatStrategy } from "grimoire-kolmafia"; import { buy, + cliExecute, create, Effect, + faxbot, + myClass, myMaxhp, print, restoreHp, restoreMp, retrieveItem, + use, useSkill, visitUrl, } from "kolmafia"; @@ -17,9 +21,11 @@ import { $familiar, $item, $location, + $monster, $skill, clamp, Clan, + CombatLoversLocket, CommunityService, get, have, @@ -28,9 +34,11 @@ import Macro, { haveFreeBanish, haveMotherSlimeBanish } from "../combat"; import { chooseFamiliar, sugarItemsAboutToBreak } from "../engine/outfit"; import { Quest } from "../engine/task"; import { + checkLocketAvailable, checkTurnSave, checkValue, logTestSetup, + shouldFeelLost, startingClan, tryAcquiringEffect, wishFor, @@ -52,11 +60,13 @@ export const WeaponDamageQuest: Quest = { }, { name: "Stand-Alone Carol Ghost Buff", + ready: () => !shouldFeelLost(), prepare: (): void => { restoreHp(clamp(1000, myMaxhp() / 2, myMaxhp())); restoreMp(50); }, completed: () => + have($effect`Feeling Lost`) || !have($familiar`Ghost of Crimbo Carols`) || (have($skill`Meteor Lore`) && get("camelSpit") < 100) || !haveFreeBanish() || @@ -111,8 +121,55 @@ export const WeaponDamageQuest: Quest = { }, limit: { tries: 1 }, }, + { + name: "Fax Ungulith", + ready: () => shouldFeelLost(), + completed: () => have($item`corrupted marrow`) || have($effect`Cowrruption`), + do: (): void => { + const monsterCow = + myClass().toString() === "Seal Clubber" && + CombatLoversLocket.unlockedLocketMonsters().includes($monster`furious cow`) + ? $monster`furious cow` + : $monster`ungulith`; + if (checkLocketAvailable() >= 2) { + CombatLoversLocket.reminisce(monsterCow); + } else { + cliExecute("chat"); + if (have($item`photocopied monster`) && get("photocopyMonster") !== monsterCow) { + cliExecute("fax send"); + } + if ( + (have($item`photocopied monster`) || faxbot(monsterCow)) && + get("photocopyMonster") === monsterCow + ) { + use($item`photocopied monster`); + } + } + }, + outfit: () => ({ + weapon: $item`Fourth of May Cosplay Saber`, + familiar: + get("camelSpit") >= 100 + ? $familiar`Melodramedary` + : $effects`Do You Crush What I Crush?, Holiday Yoked, Let It Snow/Boil/Stink/Frighten/Grease, All I Want For Crimbo Is Stuff, Crimbo Wrapping`.some( + (ef) => have(ef) + ) + ? $familiar`Ghost of Crimbo Carols` + : chooseFamiliar(false), + avoid: sugarItemsAboutToBreak(), + }), + choices: { 1387: 3 }, + combat: new CombatStrategy().macro( + Macro.trySkill($skill`Meteor Shower`) + .trySkill($skill`%fn, spit on me!`) + .trySkill($skill`Use the Force`) + .default() + ), + limit: { tries: 5 }, + }, { name: "Meteor Shower", + ready: () => !shouldFeelLost(), completed: () => have($effect`Meteor Showered`) || !have($item`Fourth of May Cosplay Saber`) ||