libram 0.8.28 → 0.8.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Clan.d.ts +128 -0
- package/dist/Clan.js +300 -0
- package/dist/Copier.d.ts +9 -0
- package/dist/Copier.js +15 -0
- package/dist/Dungeon.d.ts +45 -0
- package/dist/Dungeon.js +115 -0
- package/dist/Kmail.d.ts +133 -0
- package/dist/Kmail.js +259 -0
- package/dist/actions/ActionSource.d.ts +131 -0
- package/dist/actions/ActionSource.js +178 -0
- package/dist/actions/Banish.d.ts +16 -0
- package/dist/actions/Banish.js +121 -0
- package/dist/actions/FreeKill.d.ts +16 -0
- package/dist/actions/FreeKill.js +94 -0
- package/dist/actions/FreeRun.d.ts +16 -0
- package/dist/actions/FreeRun.js +81 -0
- package/dist/actions/index.d.ts +4 -0
- package/dist/actions/index.js +4 -0
- package/dist/ascend.d.ts +83 -0
- package/dist/ascend.js +268 -0
- package/dist/challengePaths/2014/HeavyRains.d.ts +22 -0
- package/dist/challengePaths/2014/HeavyRains.js +75 -0
- package/dist/challengePaths/2015/CommunityService.d.ts +125 -0
- package/dist/challengePaths/2015/CommunityService.js +334 -0
- package/dist/challengePaths/2016/NuclearAutumn.d.ts +13 -0
- package/dist/challengePaths/2016/NuclearAutumn.js +21 -0
- package/dist/challengePaths/index.d.ts +4 -0
- package/dist/challengePaths/index.js +4 -0
- package/dist/combat.d.ts +414 -0
- package/dist/combat.js +711 -0
- package/dist/console.d.ts +12 -0
- package/dist/console.js +14 -0
- package/dist/counter.d.ts +22 -0
- package/dist/counter.js +37 -0
- package/dist/diet/index.d.ts +80 -0
- package/dist/diet/index.js +680 -0
- package/dist/diet/knapsack.d.ts +8 -0
- package/dist/diet/knapsack.js +128 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +26 -0
- package/dist/lib.d.ts +507 -0
- package/dist/lib.js +970 -0
- package/dist/logger.d.ts +35 -0
- package/dist/logger.js +62 -0
- package/dist/maximize.d.ts +122 -0
- package/dist/maximize.js +531 -0
- package/dist/modifier.d.ts +41 -0
- package/dist/modifier.js +160 -0
- package/dist/modifierTypes.d.ts +16 -0
- package/dist/modifierTypes.js +9 -0
- package/dist/mood.d.ts +105 -0
- package/dist/mood.js +349 -0
- package/dist/moonSign.d.ts +13 -0
- package/dist/moonSign.js +25 -0
- package/dist/overlappingNames.d.ts +3 -0
- package/dist/overlappingNames.js +42 -0
- package/dist/property.d.ts +222 -0
- package/dist/property.js +385 -0
- package/dist/propertyTypes.d.ts +19 -0
- package/dist/propertyTypes.js +10 -0
- package/dist/propertyTyping.d.ts +65 -0
- package/dist/propertyTyping.js +91 -0
- package/dist/resources/2007/CandyHearts.d.ts +9 -0
- package/dist/resources/2007/CandyHearts.js +24 -0
- package/dist/resources/2008/DivineFavors.d.ts +9 -0
- package/dist/resources/2008/DivineFavors.js +27 -0
- package/dist/resources/2008/Stickers.d.ts +49 -0
- package/dist/resources/2008/Stickers.js +84 -0
- package/dist/resources/2009/Bandersnatch.d.ts +56 -0
- package/dist/resources/2009/Bandersnatch.js +93 -0
- package/dist/resources/2009/LoveSongs.d.ts +9 -0
- package/dist/resources/2009/LoveSongs.js +24 -0
- package/dist/resources/2009/SpookyPutty.d.ts +31 -0
- package/dist/resources/2009/SpookyPutty.js +49 -0
- package/dist/resources/2010/Brickos.d.ts +9 -0
- package/dist/resources/2010/Brickos.js +21 -0
- package/dist/resources/2010/CrownOfThrones.d.ts +68 -0
- package/dist/resources/2010/CrownOfThrones.js +418 -0
- package/dist/resources/2010/LookingGlass.d.ts +29 -0
- package/dist/resources/2010/LookingGlass.js +89 -0
- package/dist/resources/2011/Gygaxian.d.ts +9 -0
- package/dist/resources/2011/Gygaxian.js +24 -0
- package/dist/resources/2011/ObtuseAngel.d.ts +33 -0
- package/dist/resources/2011/ObtuseAngel.js +51 -0
- package/dist/resources/2011/StompingBoots.d.ts +37 -0
- package/dist/resources/2011/StompingBoots.js +57 -0
- package/dist/resources/2012/RainDoh.d.ts +25 -0
- package/dist/resources/2012/RainDoh.js +37 -0
- package/dist/resources/2012/ReagnimatedGnome.d.ts +31 -0
- package/dist/resources/2012/ReagnimatedGnome.js +46 -0
- package/dist/resources/2012/Resolutions.d.ts +9 -0
- package/dist/resources/2012/Resolutions.js +28 -0
- package/dist/resources/2013/Florist.d.ts +81 -0
- package/dist/resources/2013/Florist.js +245 -0
- package/dist/resources/2013/JungMan.d.ts +33 -0
- package/dist/resources/2013/JungMan.js +69 -0
- package/dist/resources/2013/PulledTaffy.d.ts +9 -0
- package/dist/resources/2013/PulledTaffy.js +33 -0
- package/dist/resources/2014/CrimboShrub.d.ts +42 -0
- package/dist/resources/2014/CrimboShrub.js +89 -0
- package/dist/resources/2014/DNALab.d.ts +56 -0
- package/dist/resources/2014/DNALab.js +162 -0
- package/dist/resources/2014/WinterGarden.d.ts +23 -0
- package/dist/resources/2014/WinterGarden.js +35 -0
- package/dist/resources/2015/BarrelShrine.d.ts +8 -0
- package/dist/resources/2015/BarrelShrine.js +25 -0
- package/dist/resources/2015/ChateauMantegna.d.ts +52 -0
- package/dist/resources/2015/ChateauMantegna.js +99 -0
- package/dist/resources/2015/DeckOfEveryCard.d.ts +29 -0
- package/dist/resources/2015/DeckOfEveryCard.js +122 -0
- package/dist/resources/2015/Dinseylandfill.d.ts +89 -0
- package/dist/resources/2015/Dinseylandfill.js +205 -0
- package/dist/resources/2015/MayoClinic.d.ts +23 -0
- package/dist/resources/2015/MayoClinic.js +49 -0
- package/dist/resources/2016/GingerBread.d.ts +32 -0
- package/dist/resources/2016/GingerBread.js +73 -0
- package/dist/resources/2016/SourceTerminal.d.ts +181 -0
- package/dist/resources/2016/SourceTerminal.js +275 -0
- package/dist/resources/2016/Witchess.d.ts +17 -0
- package/dist/resources/2016/Witchess.js +47 -0
- package/dist/resources/2017/AsdonMartin.d.ts +59 -0
- package/dist/resources/2017/AsdonMartin.js +238 -0
- package/dist/resources/2017/Horsery.d.ts +19 -0
- package/dist/resources/2017/Horsery.js +42 -0
- package/dist/resources/2017/MummingTrunk.d.ts +8 -0
- package/dist/resources/2017/MummingTrunk.js +33 -0
- package/dist/resources/2017/Pantogram.d.ts +92 -0
- package/dist/resources/2017/Pantogram.js +174 -0
- package/dist/resources/2017/Robortender.d.ts +30 -0
- package/dist/resources/2017/Robortender.js +90 -0
- package/dist/resources/2017/Spacegate.d.ts +86 -0
- package/dist/resources/2017/Spacegate.js +178 -0
- package/dist/resources/2017/TunnelOfLove.d.ts +39 -0
- package/dist/resources/2017/TunnelOfLove.js +120 -0
- package/dist/resources/2018/LatteLoversMembersMug.d.ts +392 -0
- package/dist/resources/2018/LatteLoversMembersMug.js +303 -0
- package/dist/resources/2018/SongBoom.d.ts +33 -0
- package/dist/resources/2018/SongBoom.js +55 -0
- package/dist/resources/2019/BeachComb.d.ts +72 -0
- package/dist/resources/2019/BeachComb.js +118 -0
- package/dist/resources/2019/CampAway.d.ts +39 -0
- package/dist/resources/2019/CampAway.js +72 -0
- package/dist/resources/2019/Snapper.d.ts +33 -0
- package/dist/resources/2019/Snapper.js +73 -0
- package/dist/resources/2020/Cartography.d.ts +16 -0
- package/dist/resources/2020/Cartography.js +48 -0
- package/dist/resources/2020/Guzzlr.d.ts +160 -0
- package/dist/resources/2020/Guzzlr.js +275 -0
- package/dist/resources/2020/RetroCape.d.ts +51 -0
- package/dist/resources/2020/RetroCape.js +115 -0
- package/dist/resources/2021/CrystalBall.d.ts +14 -0
- package/dist/resources/2021/CrystalBall.js +41 -0
- package/dist/resources/2021/DaylightShavings.d.ts +40 -0
- package/dist/resources/2021/DaylightShavings.js +74 -0
- package/dist/resources/2022/AutumnAton.d.ts +78 -0
- package/dist/resources/2022/AutumnAton.js +182 -0
- package/dist/resources/2022/CombatLoversLocket.d.ts +44 -0
- package/dist/resources/2022/CombatLoversLocket.js +82 -0
- package/dist/resources/2022/GreyGoose.d.ts +59 -0
- package/dist/resources/2022/GreyGoose.js +90 -0
- package/dist/resources/2022/JuneCleaver.d.ts +47 -0
- package/dist/resources/2022/JuneCleaver.js +69 -0
- package/dist/resources/2022/TrainSet.d.ts +146 -0
- package/dist/resources/2022/TrainSet.js +228 -0
- package/dist/resources/2023/AugustScepter.d.ts +25 -0
- package/dist/resources/2023/AugustScepter.js +40 -0
- package/dist/resources/2023/BurningLeaves.d.ts +25 -0
- package/dist/resources/2023/BurningLeaves.js +74 -0
- package/dist/resources/2023/CinchoDeMayo.d.ts +25 -0
- package/dist/resources/2023/CinchoDeMayo.js +45 -0
- package/dist/resources/2023/ClosedCircuitPayphone.d.ts +80 -0
- package/dist/resources/2023/ClosedCircuitPayphone.js +129 -0
- package/dist/resources/2023/CursedMonkeyPaw.d.ts +46 -0
- package/dist/resources/2023/CursedMonkeyPaw.js +113 -0
- package/dist/resources/2024/AprilingBandHelmet.d.ts +57 -0
- package/dist/resources/2024/AprilingBandHelmet.js +118 -0
- package/dist/resources/2024/ChestMimic.d.ts +42 -0
- package/dist/resources/2024/ChestMimic.js +125 -0
- package/dist/resources/LibramSummon.d.ts +18 -0
- package/dist/resources/LibramSummon.js +74 -0
- package/dist/resources/index.d.ts +54 -0
- package/dist/resources/index.js +54 -0
- package/dist/resources/putty-likes.d.ts +21 -0
- package/dist/resources/putty-likes.js +33 -0
- package/dist/session.d.ts +169 -0
- package/dist/session.js +284 -0
- package/dist/since.d.ts +51 -0
- package/dist/since.js +108 -0
- package/dist/template-string.d.ts +324 -0
- package/dist/template-string.js +265 -0
- package/dist/url.d.ts +35 -0
- package/dist/url.js +67 -0
- package/dist/utils.d.ts +178 -0
- package/dist/utils.js +255 -0
- package/package.json +2 -2
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Monster, Item, Location } from "kolmafia";
|
|
2
|
+
/**
|
|
3
|
+
* @returns Whether we currently have the closed-circuit pay phone
|
|
4
|
+
*/
|
|
5
|
+
export declare function have(): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* @returns Rufus's currently expected quest target, if he has one
|
|
8
|
+
*/
|
|
9
|
+
export declare function rufusTarget(): Monster | Item | string | null;
|
|
10
|
+
declare const INGRESS_RIFTS: {
|
|
11
|
+
readonly desertbeach: Location;
|
|
12
|
+
readonly forestvillage: Location;
|
|
13
|
+
readonly mclargehuge: Location;
|
|
14
|
+
readonly beanstalk: Location;
|
|
15
|
+
readonly manor3: Location;
|
|
16
|
+
readonly "8bit": Location;
|
|
17
|
+
readonly pyramid: Location;
|
|
18
|
+
readonly giantcastle: Location;
|
|
19
|
+
readonly woods: Location;
|
|
20
|
+
readonly hiddencity: Location;
|
|
21
|
+
readonly cemetery: Location;
|
|
22
|
+
readonly plains: Location;
|
|
23
|
+
readonly town_right: Location;
|
|
24
|
+
};
|
|
25
|
+
export declare type Ingress = "" | keyof typeof INGRESS_RIFTS;
|
|
26
|
+
/**
|
|
27
|
+
* @returns Your current `shadowRiftIngress`; `null` if none is set this ascension
|
|
28
|
+
*/
|
|
29
|
+
export declare function currentIngress(): Ingress;
|
|
30
|
+
/**
|
|
31
|
+
* @returns The current shadow rift that Mafia thinks KoL thinks you're in.
|
|
32
|
+
*/
|
|
33
|
+
export declare function currentRift(): Location | null;
|
|
34
|
+
/**
|
|
35
|
+
* Choose a shadow rift to suit your needs
|
|
36
|
+
*
|
|
37
|
+
* @param options An object of various requirements you might have for the rift you want
|
|
38
|
+
* @param options.canAdventure Set to `true` if you want to only select a rift that you can currently access
|
|
39
|
+
* @param options.monsters Set to an array of Shadow Monsters you want to be available in the rift
|
|
40
|
+
* @param options.drops Set to an array of item drops you want to come from monsters in the rift
|
|
41
|
+
* @param options.otherFilter Set an optional additional filtering function not covered by the above logic
|
|
42
|
+
* @param options.sortBy Set a function used to compare valid rifts between eachother; bigger numbers are better
|
|
43
|
+
* @returns A rift that meets the criteria you specify, if one exists
|
|
44
|
+
*/
|
|
45
|
+
export declare function chooseRift(options: {
|
|
46
|
+
canAdventure?: boolean;
|
|
47
|
+
monsters?: Monster[];
|
|
48
|
+
drops?: Item[];
|
|
49
|
+
otherFilter?: (l: Location) => boolean;
|
|
50
|
+
sortBy?: (l: Location) => number;
|
|
51
|
+
}): Location | null;
|
|
52
|
+
/**
|
|
53
|
+
* Choose a quest based on the options available to us
|
|
54
|
+
*
|
|
55
|
+
* @param chooser A function that maps quest-options to a choice
|
|
56
|
+
* @returns Whether we successfully accepted a quest
|
|
57
|
+
*/
|
|
58
|
+
export declare function chooseQuest(chooser: ({ entity, artifact, items, }: {
|
|
59
|
+
entity: Monster;
|
|
60
|
+
artifact: Item;
|
|
61
|
+
items: Item;
|
|
62
|
+
}) => 1 | 2 | 3 | 4): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* @returns Array containing all shadow rift locations
|
|
65
|
+
*/
|
|
66
|
+
export declare function rifts(): Location[];
|
|
67
|
+
/**
|
|
68
|
+
* Picks an option based on your current shadow rift ingress
|
|
69
|
+
*
|
|
70
|
+
* @param options An object keyed by shadow rift ingress; it must either contain all possible ingresses, or have a `default` parameter.
|
|
71
|
+
* @returns The option corresponding to your current shadow rift ingress.
|
|
72
|
+
*/
|
|
73
|
+
export declare const byIngress: <S>(options: import("../../utils").Switch<Ingress, S>) => S;
|
|
74
|
+
/**
|
|
75
|
+
* Submit your Rufus quest
|
|
76
|
+
*
|
|
77
|
+
* @returns Whether we successfully submitted your Rufus quest
|
|
78
|
+
*/
|
|
79
|
+
export declare function submitQuest(): boolean;
|
|
80
|
+
export {};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Monster, Item, getMonsters, itemDrops, canAdventure, runChoice, toItem, use, } from "kolmafia";
|
|
2
|
+
import { directlyUse, have as have_, questStep } from "../../lib";
|
|
3
|
+
import { get, withChoice } from "../../property";
|
|
4
|
+
import { $item, $location, $monster } from "../../template-string";
|
|
5
|
+
import { makeByXFunction, maxBy } from "../../utils";
|
|
6
|
+
const item = $item `closed-circuit pay phone`;
|
|
7
|
+
/**
|
|
8
|
+
* @returns Whether we currently have the closed-circuit pay phone
|
|
9
|
+
*/
|
|
10
|
+
export function have() {
|
|
11
|
+
return have_(item);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* @returns Rufus's currently expected quest target, if he has one
|
|
15
|
+
*/
|
|
16
|
+
export function rufusTarget() {
|
|
17
|
+
const target = get("rufusQuestTarget");
|
|
18
|
+
switch (get("rufusQuestType")) {
|
|
19
|
+
case "entity":
|
|
20
|
+
return Monster.get(target);
|
|
21
|
+
case "artifact":
|
|
22
|
+
case "items":
|
|
23
|
+
return Item.get(target);
|
|
24
|
+
default:
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const INGRESS_RIFTS = {
|
|
29
|
+
desertbeach: $location `Shadow Rift (Desert Beach)`,
|
|
30
|
+
forestvillage: $location `Shadow Rift (Forest Village)`,
|
|
31
|
+
mclargehuge: $location `Shadow Rift (Mt. McLargeHuge)`,
|
|
32
|
+
beanstalk: $location `Shadow Rift (Somewhere Over the Beanstalk)`,
|
|
33
|
+
manor3: $location `Shadow Rift (Spookyraven Manor Third Floor)`,
|
|
34
|
+
"8bit": $location `Shadow Rift (The 8-Bit Realm)`,
|
|
35
|
+
pyramid: $location `Shadow Rift (The Ancient Buried Pyramid)`,
|
|
36
|
+
giantcastle: $location `Shadow Rift (The Castle in the Clouds in the Sky)`,
|
|
37
|
+
woods: $location `Shadow Rift (The Distant Woods)`,
|
|
38
|
+
hiddencity: $location `Shadow Rift (The Hidden City)`,
|
|
39
|
+
cemetery: $location `Shadow Rift (The Misspelled Cemetary)`,
|
|
40
|
+
plains: $location `Shadow Rift (The Nearby Plains)`,
|
|
41
|
+
town_right: $location `Shadow Rift (The Right Side of the Tracks)`,
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* @returns Your current `shadowRiftIngress`; `null` if none is set this ascension
|
|
45
|
+
*/
|
|
46
|
+
export function currentIngress() {
|
|
47
|
+
return get("shadowRiftIngress");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* @returns The current shadow rift that Mafia thinks KoL thinks you're in.
|
|
51
|
+
*/
|
|
52
|
+
export function currentRift() {
|
|
53
|
+
const ingress = currentIngress();
|
|
54
|
+
return ingress ? INGRESS_RIFTS[ingress] : null;
|
|
55
|
+
}
|
|
56
|
+
const RIFTS = Array.from(Object.values(INGRESS_RIFTS));
|
|
57
|
+
/**
|
|
58
|
+
* Choose a shadow rift to suit your needs
|
|
59
|
+
*
|
|
60
|
+
* @param options An object of various requirements you might have for the rift you want
|
|
61
|
+
* @param options.canAdventure Set to `true` if you want to only select a rift that you can currently access
|
|
62
|
+
* @param options.monsters Set to an array of Shadow Monsters you want to be available in the rift
|
|
63
|
+
* @param options.drops Set to an array of item drops you want to come from monsters in the rift
|
|
64
|
+
* @param options.otherFilter Set an optional additional filtering function not covered by the above logic
|
|
65
|
+
* @param options.sortBy Set a function used to compare valid rifts between eachother; bigger numbers are better
|
|
66
|
+
* @returns A rift that meets the criteria you specify, if one exists
|
|
67
|
+
*/
|
|
68
|
+
export function chooseRift(options) {
|
|
69
|
+
const filterFunction = (l) => {
|
|
70
|
+
const monsters = getMonsters(l);
|
|
71
|
+
if (options.canAdventure && !canAdventure(l))
|
|
72
|
+
return false;
|
|
73
|
+
if (options.monsters?.some((m) => !monsters.includes(m)))
|
|
74
|
+
return false;
|
|
75
|
+
if (options.drops?.every((i) => !monsters.some((m) => i.name in itemDrops(m))))
|
|
76
|
+
return false;
|
|
77
|
+
return options.otherFilter?.(l) ?? true;
|
|
78
|
+
};
|
|
79
|
+
const validRifts = [...RIFTS].filter(filterFunction);
|
|
80
|
+
if (!validRifts.length)
|
|
81
|
+
return null;
|
|
82
|
+
return options.sortBy ? maxBy(validRifts, options.sortBy) : validRifts[0];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Choose a quest based on the options available to us
|
|
86
|
+
*
|
|
87
|
+
* @param chooser A function that maps quest-options to a choice
|
|
88
|
+
* @returns Whether we successfully accepted a quest
|
|
89
|
+
*/
|
|
90
|
+
export function chooseQuest(chooser) {
|
|
91
|
+
if (get("questRufus") !== "unstarted")
|
|
92
|
+
return false;
|
|
93
|
+
if (!have())
|
|
94
|
+
return false;
|
|
95
|
+
withChoice(1497, "", () => {
|
|
96
|
+
directlyUse(item);
|
|
97
|
+
runChoice(chooser({
|
|
98
|
+
artifact: toItem(get("rufusDesiredArtifact")),
|
|
99
|
+
entity: get("rufusDesiredEntity") ?? $monster.none,
|
|
100
|
+
items: toItem(get("rufusDesiredItems")),
|
|
101
|
+
}));
|
|
102
|
+
});
|
|
103
|
+
return get("questRufus") !== "unstarted";
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* @returns Array containing all shadow rift locations
|
|
107
|
+
*/
|
|
108
|
+
export function rifts() {
|
|
109
|
+
return [...RIFTS];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Picks an option based on your current shadow rift ingress
|
|
113
|
+
*
|
|
114
|
+
* @param options An object keyed by shadow rift ingress; it must either contain all possible ingresses, or have a `default` parameter.
|
|
115
|
+
* @returns The option corresponding to your current shadow rift ingress.
|
|
116
|
+
*/
|
|
117
|
+
export const byIngress = makeByXFunction(currentIngress);
|
|
118
|
+
/**
|
|
119
|
+
* Submit your Rufus quest
|
|
120
|
+
*
|
|
121
|
+
* @returns Whether we successfully submitted your Rufus quest
|
|
122
|
+
*/
|
|
123
|
+
export function submitQuest() {
|
|
124
|
+
if (questStep("questRufus") === 1) {
|
|
125
|
+
withChoice(1498, 1, () => use(item));
|
|
126
|
+
return questStep("questRufus") === -1;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Item, Location, Effect, Monster } from "kolmafia";
|
|
2
|
+
/**
|
|
3
|
+
* @returns Whether or not we currently `have` the cursed monkey's paw
|
|
4
|
+
*/
|
|
5
|
+
export declare function have(): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* @returns The number of monkey paw wishes we have remaining
|
|
8
|
+
*/
|
|
9
|
+
export declare function wishes(): number;
|
|
10
|
+
export declare type WishableItemsFilters = Partial<{
|
|
11
|
+
location: (location: Location) => boolean;
|
|
12
|
+
monster: (monster: Monster) => boolean;
|
|
13
|
+
drop: (itemDrop: {
|
|
14
|
+
drop: Item;
|
|
15
|
+
rate: number;
|
|
16
|
+
type: string;
|
|
17
|
+
}) => boolean;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* @param filters An optional object optionally consisting of filtering functions to shrink down the pool of wishable items
|
|
21
|
+
* @param filters.location A filtering function to remove locations from the pool of wishable targets.
|
|
22
|
+
* @param filters.monster A filtering function to remove monsters from the pool of wishable targets.
|
|
23
|
+
* @param filters.drop A filtering function to remove item drops from the pool of wishable targets.
|
|
24
|
+
* @returns A set of all items we expect to be able to wish; this doesn't actually constitute all items
|
|
25
|
+
*/
|
|
26
|
+
export declare function wishableItems(filters?: WishableItemsFilters): Set<Item>;
|
|
27
|
+
/**
|
|
28
|
+
* @returns An Array consisting of all genie-wishable Effects that are not Monkey-wishable
|
|
29
|
+
*/
|
|
30
|
+
export declare function getUnwishableEffects(): Effect[];
|
|
31
|
+
/**
|
|
32
|
+
* Decides if we expect that a given Item or Effect can be wished for.
|
|
33
|
+
* May be slow for Effects;
|
|
34
|
+
*
|
|
35
|
+
* @param wish The Item or Effect in question
|
|
36
|
+
* @returns Whether we expect it can be wished for
|
|
37
|
+
*/
|
|
38
|
+
export declare function isWishable(wish: Effect | Item): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Wish for a given Item or Effect.
|
|
41
|
+
* If it's an item, will `prepareForAdventure`; if an item is available in multiple locations this will pick the first one.
|
|
42
|
+
*
|
|
43
|
+
* @param wish The Item or Effect to wish for
|
|
44
|
+
* @returns Whether we succeeded in this endeavor
|
|
45
|
+
*/
|
|
46
|
+
export declare function wishFor(wish: Effect | Item): boolean;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Item, Location, canAdventure, getMonsters, itemDropsArray, Effect, toEffect, monkeyPaw, prepareForAdventure, cliExecute, } from "kolmafia";
|
|
2
|
+
import { have as have_ } from "../../lib";
|
|
3
|
+
import logger from "../../logger";
|
|
4
|
+
import { get } from "../../property";
|
|
5
|
+
import { $item } from "../../template-string";
|
|
6
|
+
import { clamp, flat } from "../../utils";
|
|
7
|
+
const item = $item `cursed monkey's paw`;
|
|
8
|
+
/**
|
|
9
|
+
* @returns Whether or not we currently `have` the cursed monkey's paw
|
|
10
|
+
*/
|
|
11
|
+
export function have() {
|
|
12
|
+
return have_(item);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @returns The number of monkey paw wishes we have remaining
|
|
16
|
+
*/
|
|
17
|
+
export function wishes() {
|
|
18
|
+
return clamp(5 - get("_monkeyPawWishesUsed"), 0, 5);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @param filters An optional object optionally consisting of filtering functions to shrink down the pool of wishable items
|
|
22
|
+
* @param filters.location A filtering function to remove locations from the pool of wishable targets.
|
|
23
|
+
* @param filters.monster A filtering function to remove monsters from the pool of wishable targets.
|
|
24
|
+
* @param filters.drop A filtering function to remove item drops from the pool of wishable targets.
|
|
25
|
+
* @returns A set of all items we expect to be able to wish; this doesn't actually constitute all items
|
|
26
|
+
*/
|
|
27
|
+
export function wishableItems(filters = {}) {
|
|
28
|
+
return new Set(flat(Location.all()
|
|
29
|
+
.filter((l) => canAdventure(l) && (filters.location?.(l) ?? true))
|
|
30
|
+
.map((l) => getMonsters(l)
|
|
31
|
+
.filter((m) => m.copyable && (filters.monster?.(m) ?? true))
|
|
32
|
+
.map((m) => itemDropsArray(m)
|
|
33
|
+
.filter(({ type, rate, drop }) => !drop.quest &&
|
|
34
|
+
(type !== "c" || rate >= 1) && // Remove random roll drops
|
|
35
|
+
(filters.drop?.({ type, rate, drop }) ?? true))
|
|
36
|
+
.map(({ drop }) => drop)))));
|
|
37
|
+
}
|
|
38
|
+
const INVALID_CHARACTERS = /[^a-z\d -]/g;
|
|
39
|
+
let _unwishableEffects;
|
|
40
|
+
function unwishableEffects() {
|
|
41
|
+
// This is the set of all names of genie-wishable effects, split into the maximal substrings we can actually submit
|
|
42
|
+
const names = Effect.all()
|
|
43
|
+
.filter((e) => !e.attributes.includes("nohookah"))
|
|
44
|
+
.map((e) => {
|
|
45
|
+
const name = e.name.toLowerCase();
|
|
46
|
+
return { name, splitName: name.split(INVALID_CHARACTERS) };
|
|
47
|
+
});
|
|
48
|
+
return names
|
|
49
|
+
.filter(({ name, splitName }) =>
|
|
50
|
+
// Any effect that doesn't contain an INVALID_CHARACTER is fine
|
|
51
|
+
splitName.length > 1 &&
|
|
52
|
+
// To be unwishable, there can't be any substrings that uniquely match a genie-wishable effect
|
|
53
|
+
splitName.every((s) =>
|
|
54
|
+
// So we check every maximal substring against every one of our genie-wishable effects, excluding the effect we're currently looking at
|
|
55
|
+
// if one of the substrings matches a substring associated with another effect, we're screwed.
|
|
56
|
+
names.some(({ name: n }) => n !== name && n.includes(s))))
|
|
57
|
+
.map(({ name }) => toEffect(name));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @returns An Array consisting of all genie-wishable Effects that are not Monkey-wishable
|
|
61
|
+
*/
|
|
62
|
+
export function getUnwishableEffects() {
|
|
63
|
+
return (_unwishableEffects ??= unwishableEffects());
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Decides if we expect that a given Item or Effect can be wished for.
|
|
67
|
+
* May be slow for Effects;
|
|
68
|
+
*
|
|
69
|
+
* @param wish The Item or Effect in question
|
|
70
|
+
* @returns Whether we expect it can be wished for
|
|
71
|
+
*/
|
|
72
|
+
export function isWishable(wish) {
|
|
73
|
+
if (wish instanceof Item) {
|
|
74
|
+
return wishableItems().has(wish);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
if (wish.attributes.includes("nohookah"))
|
|
78
|
+
return false;
|
|
79
|
+
if (!wish.name.match(/[.,']/))
|
|
80
|
+
return true;
|
|
81
|
+
return !getUnwishableEffects().includes(wish);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Wish for a given Item or Effect.
|
|
86
|
+
* If it's an item, will `prepareForAdventure`; if an item is available in multiple locations this will pick the first one.
|
|
87
|
+
*
|
|
88
|
+
* @param wish The Item or Effect to wish for
|
|
89
|
+
* @returns Whether we succeeded in this endeavor
|
|
90
|
+
*/
|
|
91
|
+
export function wishFor(wish) {
|
|
92
|
+
if (wishes() <= 0)
|
|
93
|
+
return false;
|
|
94
|
+
if (wish instanceof Effect)
|
|
95
|
+
return monkeyPaw(wish);
|
|
96
|
+
const locations = Location.all().filter((l) => canAdventure(l) &&
|
|
97
|
+
getMonsters(l).some((m) => m.copyable && itemDropsArray(m).some(({ drop }) => drop === wish)));
|
|
98
|
+
try {
|
|
99
|
+
if (locations.length) {
|
|
100
|
+
cliExecute("checkpoint");
|
|
101
|
+
prepareForAdventure(locations[0]);
|
|
102
|
+
}
|
|
103
|
+
const result = monkeyPaw(wish);
|
|
104
|
+
if (!result) {
|
|
105
|
+
logger.debug(`Failed to monkeyPaw wish for ${wish}; assumed it was available in locations ${locations.join(", ")}`);
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
if (locations.length)
|
|
111
|
+
cliExecute("outfit checkpoint");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Effect, Item } from "kolmafia";
|
|
2
|
+
/**
|
|
3
|
+
* @returns whether you `have` the Apriling band helmet
|
|
4
|
+
*/
|
|
5
|
+
export declare function have(): boolean;
|
|
6
|
+
export declare const MARCHING_SONGS: readonly ["Apriling Band Patrol Beat", "Apriling Band Battle Cadence", "Apriling Band Celebration Bop"];
|
|
7
|
+
export declare type MarchingSong = typeof MARCHING_SONGS[number];
|
|
8
|
+
export declare const MARCHING_SONG_EFFECTS: readonly Effect[];
|
|
9
|
+
export declare const INSTRUMENTS: readonly ["Apriling band saxophone", "Apriling band quad tom", "Apriling band tuba", "Apriling band staff", "Apriling band piccolo"];
|
|
10
|
+
export declare type Instrument = typeof INSTRUMENTS[number];
|
|
11
|
+
export declare const INSTRUMENT_ITEMS: readonly Item[];
|
|
12
|
+
/**
|
|
13
|
+
* @returns Whether we can currently join a new section of our Apriling band
|
|
14
|
+
*/
|
|
15
|
+
export declare function canJoinSection(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Joins the given section of your Apriling band, returning whether you successfully obtained its instrument
|
|
18
|
+
*
|
|
19
|
+
* @param section The section of your band to join--either the instrument's name as a string, or the item itself.
|
|
20
|
+
*
|
|
21
|
+
* @returns Whether we have the item, at the end of all things
|
|
22
|
+
*/
|
|
23
|
+
export declare const joinSection: (input: Item | "Apriling band saxophone" | "Apriling band quad tom" | "Apriling band tuba" | "Apriling band staff" | "Apriling band piccolo") => boolean;
|
|
24
|
+
/**
|
|
25
|
+
* @returns Whether we can currently change the marching song of our Apriling Band
|
|
26
|
+
*/
|
|
27
|
+
export declare function canChangeSong(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Instructs your Apriling band to play the given song, returning whether it's successfully playing
|
|
30
|
+
*
|
|
31
|
+
* @param song The song for your band to play--either the effect's name or the effect itself.
|
|
32
|
+
*
|
|
33
|
+
* @returns Whether we have the effect, at the end of all things
|
|
34
|
+
*/
|
|
35
|
+
export declare const changeSong: (input: Effect | "Apriling Band Patrol Beat" | "Apriling Band Battle Cadence" | "Apriling Band Celebration Bop") => boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Conduct your Apriling band helmet
|
|
38
|
+
*
|
|
39
|
+
* @param result The instrument (as an item or string) or song (as an effect or string) you want out of this thing
|
|
40
|
+
* @returns Whether we successfully completed the task
|
|
41
|
+
*/
|
|
42
|
+
export declare function conduct(result: Item | Instrument | Effect | MarchingSong): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Plays a given Apriling band instrument
|
|
45
|
+
*
|
|
46
|
+
* @param instrument The instrument to play
|
|
47
|
+
* @param acquire Whether or not we should obtain the instrument if we don't currently have it
|
|
48
|
+
* @returns Whether we successfully played our instrument
|
|
49
|
+
*/
|
|
50
|
+
export declare function play(instrument: Instrument | Item, acquire?: boolean): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Determine whether you can play an instrument
|
|
53
|
+
* @param instrument The instrument you want to play
|
|
54
|
+
* @param acquire Whether you're willing to obtain an instrument you don't already have
|
|
55
|
+
* @returns Whether you can play that instrument
|
|
56
|
+
*/
|
|
57
|
+
export declare function canPlay(instrument: Instrument | Item, acquire?: boolean): boolean;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Effect, Item, myHash, runChoice, toEffect, toItem, totalTurnsPlayed, visitUrl, } from "kolmafia";
|
|
2
|
+
import { have as have_ } from "../../lib";
|
|
3
|
+
import { get } from "../../property";
|
|
4
|
+
import { $item } from "../../template-string";
|
|
5
|
+
import { arrayContains } from "../../utils";
|
|
6
|
+
const helmet = $item `Apriling band helmet`;
|
|
7
|
+
/**
|
|
8
|
+
* @returns whether you `have` the Apriling band helmet
|
|
9
|
+
*/
|
|
10
|
+
export function have() {
|
|
11
|
+
return have_(helmet);
|
|
12
|
+
}
|
|
13
|
+
export const MARCHING_SONGS = Object.freeze([
|
|
14
|
+
"Apriling Band Patrol Beat",
|
|
15
|
+
"Apriling Band Battle Cadence",
|
|
16
|
+
"Apriling Band Celebration Bop",
|
|
17
|
+
]);
|
|
18
|
+
export const MARCHING_SONG_EFFECTS = Object.freeze(MARCHING_SONGS.map((song) => toEffect(song)));
|
|
19
|
+
export const INSTRUMENTS = Object.freeze([
|
|
20
|
+
"Apriling band saxophone",
|
|
21
|
+
"Apriling band quad tom",
|
|
22
|
+
"Apriling band tuba",
|
|
23
|
+
"Apriling band staff",
|
|
24
|
+
"Apriling band piccolo",
|
|
25
|
+
]);
|
|
26
|
+
export const INSTRUMENT_ITEMS = Object.freeze(INSTRUMENTS.map((instrument) => toItem(instrument)));
|
|
27
|
+
const visitConduct = () => visitUrl("inventory.php?pwd&action=apriling");
|
|
28
|
+
/**
|
|
29
|
+
* @returns Whether we can currently join a new section of our Apriling band
|
|
30
|
+
*/
|
|
31
|
+
export function canJoinSection() {
|
|
32
|
+
return have() && get("_aprilBandInstruments") < 2;
|
|
33
|
+
}
|
|
34
|
+
function makeConductFunction(mafiaClass, canDo, set, offset) {
|
|
35
|
+
return (input) => {
|
|
36
|
+
if (!canDo())
|
|
37
|
+
return false;
|
|
38
|
+
const [name, instance] = typeof input === "string"
|
|
39
|
+
? [input, mafiaClass.get(input)]
|
|
40
|
+
: [input.name, input];
|
|
41
|
+
if (have_(instance))
|
|
42
|
+
return true;
|
|
43
|
+
const key = set.indexOf(name);
|
|
44
|
+
if (key === -1)
|
|
45
|
+
return false;
|
|
46
|
+
visitConduct();
|
|
47
|
+
runChoice(key + offset);
|
|
48
|
+
runChoice(9);
|
|
49
|
+
return have_(instance);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Joins the given section of your Apriling band, returning whether you successfully obtained its instrument
|
|
54
|
+
*
|
|
55
|
+
* @param section The section of your band to join--either the instrument's name as a string, or the item itself.
|
|
56
|
+
*
|
|
57
|
+
* @returns Whether we have the item, at the end of all things
|
|
58
|
+
*/
|
|
59
|
+
export const joinSection = makeConductFunction(Item, canJoinSection, INSTRUMENTS, 4);
|
|
60
|
+
/**
|
|
61
|
+
* @returns Whether we can currently change the marching song of our Apriling Band
|
|
62
|
+
*/
|
|
63
|
+
export function canChangeSong() {
|
|
64
|
+
return have() && get("nextAprilBandTurn") <= totalTurnsPlayed();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Instructs your Apriling band to play the given song, returning whether it's successfully playing
|
|
68
|
+
*
|
|
69
|
+
* @param song The song for your band to play--either the effect's name or the effect itself.
|
|
70
|
+
*
|
|
71
|
+
* @returns Whether we have the effect, at the end of all things
|
|
72
|
+
*/
|
|
73
|
+
export const changeSong = makeConductFunction(Effect, canChangeSong, MARCHING_SONGS, 1);
|
|
74
|
+
/**
|
|
75
|
+
* Conduct your Apriling band helmet
|
|
76
|
+
*
|
|
77
|
+
* @param result The instrument (as an item or string) or song (as an effect or string) you want out of this thing
|
|
78
|
+
* @returns Whether we successfully completed the task
|
|
79
|
+
*/
|
|
80
|
+
export function conduct(result) {
|
|
81
|
+
if (result instanceof Item || arrayContains(result, INSTRUMENTS)) {
|
|
82
|
+
return joinSection(result);
|
|
83
|
+
}
|
|
84
|
+
return changeSong(result);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Plays a given Apriling band instrument
|
|
88
|
+
*
|
|
89
|
+
* @param instrument The instrument to play
|
|
90
|
+
* @param acquire Whether or not we should obtain the instrument if we don't currently have it
|
|
91
|
+
* @returns Whether we successfully played our instrument
|
|
92
|
+
*/
|
|
93
|
+
export function play(instrument, acquire = false) {
|
|
94
|
+
const item = instrument instanceof Item ? instrument : Item.get(instrument);
|
|
95
|
+
if (!canPlay(instrument, acquire))
|
|
96
|
+
return false;
|
|
97
|
+
if (acquire && !have_(item))
|
|
98
|
+
joinSection(item);
|
|
99
|
+
const currentUsesRemaining = item.dailyusesleft;
|
|
100
|
+
visitUrl(`inventory.php?pwd=${myHash()}&iid=${item.id}&action=aprilplay`, false);
|
|
101
|
+
return item.dailyusesleft !== currentUsesRemaining;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Determine whether you can play an instrument
|
|
105
|
+
* @param instrument The instrument you want to play
|
|
106
|
+
* @param acquire Whether you're willing to obtain an instrument you don't already have
|
|
107
|
+
* @returns Whether you can play that instrument
|
|
108
|
+
*/
|
|
109
|
+
export function canPlay(instrument, acquire = false) {
|
|
110
|
+
if (!have())
|
|
111
|
+
return false;
|
|
112
|
+
const item = instrument instanceof Item ? instrument : Item.get(instrument);
|
|
113
|
+
if (!have_(item) && (!acquire || !canJoinSection()))
|
|
114
|
+
return false;
|
|
115
|
+
if (item.dailyusesleft <= 0)
|
|
116
|
+
return false;
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Monster, runCombat } from "kolmafia";
|
|
2
|
+
/**
|
|
3
|
+
* @returns Whether you `have` the Chest Mimic familiar.
|
|
4
|
+
*/
|
|
5
|
+
export declare function have(): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* @returns List of monsters available for donation at this time
|
|
8
|
+
*/
|
|
9
|
+
export declare function getDonableMonsters(): Monster[];
|
|
10
|
+
/**
|
|
11
|
+
* @returns List of monsters available to receive as an egg at this time
|
|
12
|
+
*/
|
|
13
|
+
export declare function getReceivableMonsters(): Monster[];
|
|
14
|
+
/**
|
|
15
|
+
* Donate an egg to the DNA bank
|
|
16
|
+
*
|
|
17
|
+
* @param monster The monster whose egg you want to donate
|
|
18
|
+
* @returns Whether we succeeded in our endeavor
|
|
19
|
+
*/
|
|
20
|
+
export declare function donate(monster: Monster): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Receive an egg from the DNA bank
|
|
23
|
+
*
|
|
24
|
+
* @param monster The monster whose egg you want to receive
|
|
25
|
+
* @returns Whether we succeeded in our endeavor
|
|
26
|
+
*/
|
|
27
|
+
export declare function receive(monster: Monster): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Differentiate a Mimic egg into a monster, and fight it!
|
|
30
|
+
*
|
|
31
|
+
* @param monster The monster to differentiate your egg into
|
|
32
|
+
* @param combat Any parameters you'd like to pass to `runCombat`
|
|
33
|
+
* @returns Whether we successfully differentiated our egg
|
|
34
|
+
*/
|
|
35
|
+
export declare function differentiate(monster: Monster, ...combat: Parameters<typeof runCombat>): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check how many of a monster is available to differentiate into
|
|
38
|
+
*
|
|
39
|
+
* @param monster The monster to differentiate your egg into; may behave weirdly with name collisions
|
|
40
|
+
* @returns How many of a Monster we can differentiate
|
|
41
|
+
*/
|
|
42
|
+
export declare function differentiableQuantity(monster: Monster): number;
|