libram 0.4.2 → 0.4.6
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.js +7 -4
- package/dist/Copier.js +5 -1
- package/dist/Kmail.js +18 -12
- package/dist/Path.js +9 -0
- package/dist/combat.d.ts +22 -11
- package/dist/combat.js +74 -19
- package/dist/diet/index.d.ts +9 -0
- package/dist/diet/index.js +191 -88
- package/dist/diet/knapsack.js +16 -2
- package/dist/freerun.js +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/lib.d.ts +2 -0
- package/dist/lib.js +22 -2
- package/dist/logger.js +1 -3
- package/dist/maximize.js +12 -12
- package/dist/mood.d.ts +5 -0
- package/dist/mood.js +43 -15
- package/dist/property.js +5 -1
- package/dist/propertyTypes.d.ts +5 -4
- package/dist/propertyTyping.d.ts +4 -3
- package/dist/propertyTyping.js +4 -0
- package/dist/resources/2010/CrownOfThrones.d.ts +3 -3
- package/dist/resources/2010/CrownOfThrones.js +7 -7
- package/dist/resources/2013/Florist.js +5 -0
- package/dist/resources/2014/DNALab.d.ts +47 -0
- package/dist/resources/2014/DNALab.js +154 -0
- package/dist/resources/2015/MayoClinic.d.ts +2 -0
- package/dist/resources/2015/MayoClinic.js +8 -2
- package/dist/resources/2017/AsdonMartin.d.ts +27 -0
- package/dist/resources/2017/AsdonMartin.js +80 -0
- package/dist/resources/2019/Snapper.js +2 -3
- package/dist/resources/2020/Guzzlr.d.ts +3 -0
- package/dist/resources/2020/Guzzlr.js +14 -1
- package/dist/resources/LibramSummon.js +2 -2
- package/dist/resources/index.d.ts +3 -1
- package/dist/resources/index.js +3 -1
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +12 -1
- package/package.json +14 -8
|
@@ -513,18 +513,18 @@ export const ridingFamiliars = [
|
|
|
513
513
|
modifier: { ["Hot Damage"]: 20 },
|
|
514
514
|
},
|
|
515
515
|
];
|
|
516
|
-
export function valueRider(rider, modifierValueFunction,
|
|
517
|
-
const dropValue = !rider.dropPredicate || (rider.dropPredicate() && !
|
|
516
|
+
export function valueRider(rider, modifierValueFunction, ignoreLimitedDrops = false) {
|
|
517
|
+
const dropValue = !rider.dropPredicate || (rider.dropPredicate() && !ignoreLimitedDrops)
|
|
518
518
|
? rider.probability * rider.meatVal()
|
|
519
519
|
: 0;
|
|
520
520
|
const modifierValue = modifierValueFunction(rider.modifier);
|
|
521
521
|
return dropValue + modifierValue;
|
|
522
522
|
}
|
|
523
523
|
const riderModes = new Map();
|
|
524
|
-
export function createRiderMode(name, modifierValueFunction,
|
|
524
|
+
export function createRiderMode(name, modifierValueFunction, ignoreLimitedDrops = false, excludeCurrentFamiliar = true) {
|
|
525
525
|
return riderModes.set(name, {
|
|
526
526
|
modifierValueFunction: modifierValueFunction,
|
|
527
|
-
|
|
527
|
+
ignoreLimitedDrops: ignoreLimitedDrops,
|
|
528
528
|
excludeCurrentFamiliar: excludeCurrentFamiliar,
|
|
529
529
|
});
|
|
530
530
|
}
|
|
@@ -533,12 +533,12 @@ export function pickRider(mode) {
|
|
|
533
533
|
const modeData = riderModes.get(mode);
|
|
534
534
|
if (!modeData)
|
|
535
535
|
return null;
|
|
536
|
-
const { modifierValueFunction,
|
|
536
|
+
const { modifierValueFunction, ignoreLimitedDrops, excludeCurrentFamiliar, } = modeData;
|
|
537
537
|
if (!riderLists.has(mode)) {
|
|
538
538
|
riderLists.set(mode, ridingFamiliars
|
|
539
539
|
.filter((rider) => have(rider.familiar))
|
|
540
|
-
.sort((a, b) => valueRider(b, modifierValueFunction,
|
|
541
|
-
valueRider(a, modifierValueFunction,
|
|
540
|
+
.sort((a, b) => valueRider(b, modifierValueFunction, ignoreLimitedDrops) -
|
|
541
|
+
valueRider(a, modifierValueFunction, ignoreLimitedDrops)));
|
|
542
542
|
}
|
|
543
543
|
const list = riderLists.get(mode);
|
|
544
544
|
if (list) {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { floristAvailable, getFloristPlants, myLocation, visitUrl, } from "kolmafia";
|
|
2
2
|
import { get } from "../../property";
|
|
3
3
|
class Flower {
|
|
4
|
+
name;
|
|
5
|
+
id;
|
|
6
|
+
environment;
|
|
7
|
+
modifier;
|
|
8
|
+
territorial;
|
|
4
9
|
constructor(name, id, environment, modifier, territorial = false) {
|
|
5
10
|
this.name = name;
|
|
6
11
|
this.id = id;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if you have DNA lab in inventory or installed
|
|
3
|
+
*/
|
|
4
|
+
export declare function have(): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Checks if you have DNA lab installed
|
|
7
|
+
*/
|
|
8
|
+
export declare function installed(): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Tells you whether you are currently hybridized. When passed with an input of any sort, tells you whether you are currently hybridized with that effect.
|
|
11
|
+
* @param tonic Optional input. When passed, the function returns whether that specific effect is hybridized.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isHybridized(tonic?: Effect | Phylum | Item): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Returns the tonic item associated with a particular phylum.
|
|
16
|
+
* @param phylum The phylum in question.
|
|
17
|
+
* @returns The tonic item associated with that phylum; returns $item`none` for $phylum`none`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getTonic(phylum: Phylum): Item;
|
|
20
|
+
/**
|
|
21
|
+
* Returns the tonic effect associated with a particular phylum.
|
|
22
|
+
* @param phylum The phylum in question.
|
|
23
|
+
* @returns The tonic effect associated with that phylum; returns $effect`none` for $phylum`none`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getEffect(phylum: Phylum): Effect;
|
|
26
|
+
/**
|
|
27
|
+
* Tells you which phylum to hunt down for a given effect or item.
|
|
28
|
+
* @param dnatype The tonic effect or item in question
|
|
29
|
+
* @returns The Phylum associated with that effect or item; null if an invalid choice
|
|
30
|
+
*/
|
|
31
|
+
export declare function phylumFor(dnatype: Effect | Item): Phylum | null;
|
|
32
|
+
/**
|
|
33
|
+
* Hybridize yourself with the current contents of your syringe, if possible.
|
|
34
|
+
* @returns Whether or not we succeeded
|
|
35
|
+
*/
|
|
36
|
+
export declare function hybridize(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Makes tonics with whatever phylum is currently in your syringe
|
|
39
|
+
* @param {number} [amount=1] the number of tonics to make
|
|
40
|
+
* @returns Whether we successfully made tonics; returns true if we made as many as we could, regardless of whether that was the number requested
|
|
41
|
+
*/
|
|
42
|
+
export declare function makeTonic(amount?: 1 | 2 | 3): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Tells you how many tonics you can make the rest of the day.
|
|
45
|
+
* @returns The remaining tonics you can make
|
|
46
|
+
*/
|
|
47
|
+
export declare function tonicsLeft(): number;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { cliExecute, getWorkshed, haveEffect, itemAmount } from "kolmafia";
|
|
2
|
+
import { $effect, $item, $phylum } from "../../template-string";
|
|
3
|
+
import { have as haveItem } from "../../lib";
|
|
4
|
+
import { get } from "../../property";
|
|
5
|
+
import { get as getModifier } from "../../modifier";
|
|
6
|
+
import { clamp } from "../../utils";
|
|
7
|
+
const lab = $item `Little Geneticist DNA-Splicing Lab`;
|
|
8
|
+
/**
|
|
9
|
+
* Checks if you have DNA lab in inventory or installed
|
|
10
|
+
*/
|
|
11
|
+
export function have() {
|
|
12
|
+
return haveItem(lab) || getWorkshed() === lab;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Checks if you have DNA lab installed
|
|
16
|
+
*/
|
|
17
|
+
export function installed() {
|
|
18
|
+
return getWorkshed() === lab;
|
|
19
|
+
}
|
|
20
|
+
const phylaEffects = new Map([
|
|
21
|
+
[$phylum `beast`, $effect `Human-Beast Hybrid`],
|
|
22
|
+
[$phylum `bug`, $effect `Human-Insect Hybrid`],
|
|
23
|
+
[$phylum `constellation`, $effect `Human-Constellation Hybrid`],
|
|
24
|
+
[$phylum `construct`, $effect `Human-Machine Hybrid`],
|
|
25
|
+
[$phylum `demon`, $effect `Human-Demon Hybrid`],
|
|
26
|
+
[$phylum `dude`, $effect `Human-Human Hybrid`],
|
|
27
|
+
[$phylum `elemental`, $effect `Human-Elemental Hybrid`],
|
|
28
|
+
[$phylum `elf`, $effect `Human-Elf Hybrid`],
|
|
29
|
+
[$phylum `fish`, $effect `Human-Fish Hybrid`],
|
|
30
|
+
[$phylum `goblin`, $effect `Human-Goblin Hybrid`],
|
|
31
|
+
[$phylum `hippy`, $effect `Human-Hobo Hybrid`],
|
|
32
|
+
[$phylum `horror`, $effect `Human-Horror Hybrid`],
|
|
33
|
+
[$phylum `humanoid`, $effect `Human-Humanoid Hybrid`],
|
|
34
|
+
[$phylum `mer-kin`, $effect `Human-Mer-kin Hybrid`],
|
|
35
|
+
[$phylum `orc`, $effect `Human-Orc Hybrid`],
|
|
36
|
+
[$phylum `penguin`, $effect `Human-Penguin Hybrid`],
|
|
37
|
+
[$phylum `pirate`, $effect `Human-Pirate Hybrid`],
|
|
38
|
+
[$phylum `plant`, $effect `Human-Plant Hybrid`],
|
|
39
|
+
[$phylum `slime`, $effect `Human-Slime Hybrid`],
|
|
40
|
+
[$phylum `undead`, $effect `Human-Undead Hybrid`],
|
|
41
|
+
[$phylum `weird`, $effect `Human-Weird Thing Hybrid`],
|
|
42
|
+
]);
|
|
43
|
+
const phylaTonics = new Map([
|
|
44
|
+
[$phylum `beast`, $item `Gene Tonic: Beast`],
|
|
45
|
+
[$phylum `bug`, $item `Gene Tonic: Insect`],
|
|
46
|
+
[$phylum `constellation`, $item `Gene Tonic: Constellation`],
|
|
47
|
+
[$phylum `construct`, $item `Gene Tonic: Construct`],
|
|
48
|
+
[$phylum `demon`, $item `Gene Tonic: Demon`],
|
|
49
|
+
[$phylum `dude`, $item `Gene Tonic: Humanoid`],
|
|
50
|
+
[$phylum `elemental`, $item `Gene Tonic: Elemental`],
|
|
51
|
+
[$phylum `elf`, $item `Gene Tonic: Elf`],
|
|
52
|
+
[$phylum `fish`, $item `Gene Tonic: Fish`],
|
|
53
|
+
[$phylum `goblin`, $item `Gene Tonic: Goblin`],
|
|
54
|
+
[$phylum `hippy`, $item `Gene Tonic: Hobo`],
|
|
55
|
+
[$phylum `horror`, $item `Gene Tonic: Horror`],
|
|
56
|
+
[$phylum `humanoid`, $item `Gene Tonic: Humanoid`],
|
|
57
|
+
[$phylum `mer-kin`, $item `Gene Tonic: Mer-kin`],
|
|
58
|
+
[$phylum `orc`, $item `Gene Tonic: Orc`],
|
|
59
|
+
[$phylum `penguin`, $item `Gene Tonic: Penguin`],
|
|
60
|
+
[$phylum `pirate`, $item `Gene Tonic: Pirate`],
|
|
61
|
+
[$phylum `plant`, $item `Gene Tonic: Plant`],
|
|
62
|
+
[$phylum `slime`, $item `Gene Tonic: Slime`],
|
|
63
|
+
[$phylum `undead`, $item `Gene Tonic: Undead`],
|
|
64
|
+
[$phylum `weird`, $item `Gene Tonic: Weird`],
|
|
65
|
+
]);
|
|
66
|
+
const tonicEffects = Array.from(phylaEffects.values());
|
|
67
|
+
/**
|
|
68
|
+
* Tells you whether you are currently hybridized. When passed with an input of any sort, tells you whether you are currently hybridized with that effect.
|
|
69
|
+
* @param tonic Optional input. When passed, the function returns whether that specific effect is hybridized.
|
|
70
|
+
*/
|
|
71
|
+
export function isHybridized(tonic) {
|
|
72
|
+
if (!tonic)
|
|
73
|
+
return installed() && get("_dnaHybrid");
|
|
74
|
+
const tonicEffect = tonic instanceof Effect
|
|
75
|
+
? tonic
|
|
76
|
+
: tonic instanceof Phylum
|
|
77
|
+
? getEffect(tonic)
|
|
78
|
+
: getModifier("Effect", tonic);
|
|
79
|
+
return (tonicEffects.includes(tonicEffect) && haveEffect(tonicEffect) === 2147483647);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns the tonic item associated with a particular phylum.
|
|
83
|
+
* @param phylum The phylum in question.
|
|
84
|
+
* @returns The tonic item associated with that phylum; returns $item`none` for $phylum`none`.
|
|
85
|
+
*/
|
|
86
|
+
export function getTonic(phylum) {
|
|
87
|
+
return phylaTonics.get(phylum) ?? $item `none`;
|
|
88
|
+
//return $item`none` rather than null because it should never happen.
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns the tonic effect associated with a particular phylum.
|
|
92
|
+
* @param phylum The phylum in question.
|
|
93
|
+
* @returns The tonic effect associated with that phylum; returns $effect`none` for $phylum`none`.
|
|
94
|
+
*/
|
|
95
|
+
export function getEffect(phylum) {
|
|
96
|
+
return phylaEffects.get(phylum) ?? $effect `none`;
|
|
97
|
+
//return $effect`none` rather than null because it should never happen
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Tells you which phylum to hunt down for a given effect or item.
|
|
101
|
+
* @param dnatype The tonic effect or item in question
|
|
102
|
+
* @returns The Phylum associated with that effect or item; null if an invalid choice
|
|
103
|
+
*/
|
|
104
|
+
export function phylumFor(dnatype) {
|
|
105
|
+
if (dnatype instanceof Effect) {
|
|
106
|
+
const phylumPair = Array.from(phylaEffects.entries()).find(([, effect]) => effect === dnatype);
|
|
107
|
+
return phylumPair ? phylumPair[0] : null;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const phylumPair = Array.from(phylaTonics.entries()).find(([, tonic]) => tonic === dnatype);
|
|
111
|
+
return phylumPair ? phylumPair[0] : null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Hybridize yourself with the current contents of your syringe, if possible.
|
|
116
|
+
* @returns Whether or not we succeeded
|
|
117
|
+
*/
|
|
118
|
+
export function hybridize() {
|
|
119
|
+
if (get("_dnaHybrid"))
|
|
120
|
+
return false;
|
|
121
|
+
if (!installed())
|
|
122
|
+
return false;
|
|
123
|
+
const currentSyringe = get("dnaSyringe");
|
|
124
|
+
if (!currentSyringe)
|
|
125
|
+
return false;
|
|
126
|
+
const tonicPotion = getTonic(currentSyringe);
|
|
127
|
+
const expectedEffect = getModifier("Effect", tonicPotion);
|
|
128
|
+
cliExecute("camp dnainject");
|
|
129
|
+
return isHybridized(expectedEffect);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Makes tonics with whatever phylum is currently in your syringe
|
|
133
|
+
* @param {number} [amount=1] the number of tonics to make
|
|
134
|
+
* @returns Whether we successfully made tonics; returns true if we made as many as we could, regardless of whether that was the number requested
|
|
135
|
+
*/
|
|
136
|
+
export function makeTonic(amount = 1) {
|
|
137
|
+
if (!installed())
|
|
138
|
+
return false;
|
|
139
|
+
const currentSyringe = get("dnaSyringe");
|
|
140
|
+
if (!currentSyringe)
|
|
141
|
+
return false;
|
|
142
|
+
const tonicPotion = getTonic(currentSyringe);
|
|
143
|
+
const amountToMake = clamp(amount, 0, tonicsLeft());
|
|
144
|
+
const startingAmount = itemAmount(tonicPotion);
|
|
145
|
+
cliExecute(`camp dnapotion ${amountToMake}`);
|
|
146
|
+
return itemAmount(tonicPotion) - startingAmount === amountToMake;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Tells you how many tonics you can make the rest of the day.
|
|
150
|
+
* @returns The remaining tonics you can make
|
|
151
|
+
*/
|
|
152
|
+
export function tonicsLeft() {
|
|
153
|
+
return clamp(3 - get("_dnaPotionsMade"), 0, 3);
|
|
154
|
+
}
|
|
@@ -5,6 +5,8 @@ export declare const Mayo: {
|
|
|
5
5
|
zapine: Item;
|
|
6
6
|
flex: Item;
|
|
7
7
|
};
|
|
8
|
+
export declare function installed(): boolean;
|
|
9
|
+
export declare function have(): boolean;
|
|
8
10
|
/**
|
|
9
11
|
* Sets mayo minder to a particular mayo, and ensures you have enough of it.
|
|
10
12
|
* @param mayo Mayo to use
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "core-js/modules/es.object.values";
|
|
2
2
|
import { buy, getWorkshed, retrieveItem, toInt, use } from "kolmafia";
|
|
3
|
-
import { have } from "../../lib";
|
|
3
|
+
import { have as haveItem } from "../../lib";
|
|
4
4
|
import logger from "../../logger";
|
|
5
5
|
import { get, withChoice } from "../../property";
|
|
6
6
|
import { $item } from "../../template-string";
|
|
@@ -10,6 +10,12 @@ export const Mayo = {
|
|
|
10
10
|
zapine: $item `Mayozapine`,
|
|
11
11
|
flex: $item `Mayoflex`,
|
|
12
12
|
};
|
|
13
|
+
export function installed() {
|
|
14
|
+
return getWorkshed() === $item `portable Mayo Clinic`;
|
|
15
|
+
}
|
|
16
|
+
export function have() {
|
|
17
|
+
return haveItem($item `portable Mayo Clinic`) || installed();
|
|
18
|
+
}
|
|
13
19
|
/**
|
|
14
20
|
* Sets mayo minder to a particular mayo, and ensures you have enough of it.
|
|
15
21
|
* @param mayo Mayo to use
|
|
@@ -27,7 +33,7 @@ export function setMayoMinder(mayo, quantity = 1) {
|
|
|
27
33
|
return false;
|
|
28
34
|
}
|
|
29
35
|
retrieveItem(quantity, mayo);
|
|
30
|
-
if (!
|
|
36
|
+
if (!haveItem($item `Mayo Minder™`))
|
|
31
37
|
buy($item `Mayo Minder™`);
|
|
32
38
|
if (get("mayoMinderSetting") !== mayo.name) {
|
|
33
39
|
withChoice(1076, toInt(mayo) - 8260, () => use($item `Mayo Minder™`));
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fill your Asdon Martin to the given fuel level in the cheapest way possible
|
|
3
|
+
* @param targetUnits Fuel level to attempt to reach.
|
|
4
|
+
* @returns Whether we succeeded at filling to the target fuel level.
|
|
5
|
+
*/
|
|
6
|
+
export declare function fillTo(targetUnits: number): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Object consisting of the various Asdon driving styles
|
|
9
|
+
*/
|
|
10
|
+
export declare const Driving: {
|
|
11
|
+
Obnoxiously: Effect;
|
|
12
|
+
Stealthily: Effect;
|
|
13
|
+
Wastefully: Effect;
|
|
14
|
+
Safely: Effect;
|
|
15
|
+
Recklessly: Effect;
|
|
16
|
+
Intimidatingly: Effect;
|
|
17
|
+
Quickly: Effect;
|
|
18
|
+
Observantly: Effect;
|
|
19
|
+
Waterproofly: Effect;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Attempt to drive with a particular style for a particular number of turns
|
|
23
|
+
* @param style The driving style to use
|
|
24
|
+
* @param turns The number of turns to attempt to get
|
|
25
|
+
* @returns Whether we have at least as many turns as requested of said driving style.
|
|
26
|
+
*/
|
|
27
|
+
export declare function drive(style: Effect, turns?: number): boolean;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { cliExecute, getFuel, haveEffect, historicalPrice, isNpcItem, mallPrice, retrieveItem, toInt, visitUrl, } from "kolmafia";
|
|
2
|
+
import { getAverageAdventures } from "../../lib";
|
|
3
|
+
import { $effect, $items } from "../../template-string";
|
|
4
|
+
const fuelSkiplist = $items `cup of "tea", thermos of "whiskey", Lucky Lindy, Bee's Knees, Sockdollager, Ish Kabibble, Hot Socks, Phonus Balonus, Flivver, Sloppy Jalopy, glass of "milk"`;
|
|
5
|
+
function price(item) {
|
|
6
|
+
return historicalPrice(item) === 0 ? mallPrice(item) : historicalPrice(item);
|
|
7
|
+
}
|
|
8
|
+
function calculateFuelEfficiency(it, targetUnits) {
|
|
9
|
+
const units = getAverageAdventures(it);
|
|
10
|
+
return price(it) / Math.min(targetUnits, units);
|
|
11
|
+
}
|
|
12
|
+
function isFuelItem(it) {
|
|
13
|
+
return (!isNpcItem(it) &&
|
|
14
|
+
it.fullness + it.inebriety > 0 &&
|
|
15
|
+
getAverageAdventures(it) > 0 &&
|
|
16
|
+
it.tradeable &&
|
|
17
|
+
it.discardable &&
|
|
18
|
+
!fuelSkiplist.includes(it));
|
|
19
|
+
}
|
|
20
|
+
const potentialFuel = $items ``.filter(isFuelItem);
|
|
21
|
+
function getBestFuel(targetUnits) {
|
|
22
|
+
const key1 = (item) => -getAverageAdventures(item);
|
|
23
|
+
const key2 = (item) => calculateFuelEfficiency(item, targetUnits);
|
|
24
|
+
potentialFuel.sort((x, y) => key1(x) - key1(y));
|
|
25
|
+
potentialFuel.sort((x, y) => key2(x) - key2(y));
|
|
26
|
+
return potentialFuel[0];
|
|
27
|
+
}
|
|
28
|
+
function insertFuel(it, quantity = 1) {
|
|
29
|
+
const result = visitUrl(`campground.php?action=fuelconvertor&pwd&qty=${quantity}&iid=${toInt(it)}&go=Convert%21`);
|
|
30
|
+
return result.includes("The display updates with a");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Fill your Asdon Martin to the given fuel level in the cheapest way possible
|
|
34
|
+
* @param targetUnits Fuel level to attempt to reach.
|
|
35
|
+
* @returns Whether we succeeded at filling to the target fuel level.
|
|
36
|
+
*/
|
|
37
|
+
export function fillTo(targetUnits) {
|
|
38
|
+
while (getFuel() < targetUnits) {
|
|
39
|
+
const remaining = targetUnits - getFuel();
|
|
40
|
+
const fuel = getBestFuel(remaining);
|
|
41
|
+
const count = Math.ceil(targetUnits / getAverageAdventures(fuel));
|
|
42
|
+
retrieveItem(count, fuel);
|
|
43
|
+
if (!insertFuel(fuel, count)) {
|
|
44
|
+
throw new Error("Failed to fuel Asdon Martin.");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return getFuel() >= targetUnits;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Object consisting of the various Asdon driving styles
|
|
51
|
+
*/
|
|
52
|
+
export const Driving = {
|
|
53
|
+
Obnoxiously: $effect `Driving Obnoxiously`,
|
|
54
|
+
Stealthily: $effect `Driving Stealthily`,
|
|
55
|
+
Wastefully: $effect `Driving Wastefully`,
|
|
56
|
+
Safely: $effect `Driving Safely`,
|
|
57
|
+
Recklessly: $effect `Driving Recklessly`,
|
|
58
|
+
Intimidatingly: $effect `Driving Intimidatingly`,
|
|
59
|
+
Quickly: $effect `Driving Quickly`,
|
|
60
|
+
Observantly: $effect `Driving Observantly`,
|
|
61
|
+
Waterproofly: $effect `Driving Waterproofly`,
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Attempt to drive with a particular style for a particular number of turns
|
|
65
|
+
* @param style The driving style to use
|
|
66
|
+
* @param turns The number of turns to attempt to get
|
|
67
|
+
* @returns Whether we have at least as many turns as requested of said driving style.
|
|
68
|
+
*/
|
|
69
|
+
export function drive(style, turns = 1) {
|
|
70
|
+
if (!Object.values(Driving).includes(style))
|
|
71
|
+
return false;
|
|
72
|
+
if (haveEffect(style) >= turns)
|
|
73
|
+
return true;
|
|
74
|
+
const fuelNeeded = 37 * Math.ceil((turns - haveEffect(style)) / 30);
|
|
75
|
+
fillTo(fuelNeeded);
|
|
76
|
+
while (getFuel() >= 37 && haveEffect(style) < turns) {
|
|
77
|
+
cliExecute(`asdonmartin drive ${style.name.replace("Driving ", "")}`);
|
|
78
|
+
}
|
|
79
|
+
return haveEffect(style) >= turns;
|
|
80
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cliExecute, haveFamiliar, myFamiliar,
|
|
1
|
+
import { cliExecute, haveFamiliar, myFamiliar, useFamiliar } from "kolmafia";
|
|
2
2
|
import { get } from "../../property";
|
|
3
3
|
const familiar = Familiar.get("Red-Nosed Snapper");
|
|
4
4
|
/**
|
|
@@ -44,8 +44,7 @@ export function have() {
|
|
|
44
44
|
* @returns Tracked phylum, or null if no phylum tracked.
|
|
45
45
|
*/
|
|
46
46
|
export function getTrackedPhylum() {
|
|
47
|
-
|
|
48
|
-
return phylum === Phylum.get("none") ? null : phylum;
|
|
47
|
+
return get("redSnapperPhylum");
|
|
49
48
|
}
|
|
50
49
|
/**
|
|
51
50
|
* Set snapper tracking to a certain phylum.
|
|
@@ -87,3 +87,6 @@ export declare function havePlatinumBooze(): boolean;
|
|
|
87
87
|
* If they have no quest, returns false
|
|
88
88
|
*/
|
|
89
89
|
export declare function haveBooze(): boolean;
|
|
90
|
+
export declare const ingredientToPlatinumCocktail: Map<Item, Item>;
|
|
91
|
+
export declare const platinumCocktailToIngredient: Map<Item, Item>;
|
|
92
|
+
export declare function getCheapestPlatinumCocktail(): Item;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { runChoice, use, visitUrl } from "kolmafia";
|
|
1
|
+
import { mallPrice, runChoice, use, visitUrl } from "kolmafia";
|
|
2
|
+
import { maxBy } from "lodash";
|
|
2
3
|
import { have as haveItem } from "../../lib";
|
|
3
4
|
import { get, withChoice } from "../../property";
|
|
4
5
|
import { $item, $items } from "../../template-string";
|
|
6
|
+
import { invertMap } from "../../utils";
|
|
5
7
|
export const item = $item `Guzzlr tablet`;
|
|
6
8
|
export function have() {
|
|
7
9
|
return haveItem(item);
|
|
@@ -164,3 +166,14 @@ export function haveBooze() {
|
|
|
164
166
|
return haveItem(booze);
|
|
165
167
|
}
|
|
166
168
|
}
|
|
169
|
+
export const ingredientToPlatinumCocktail = new Map([
|
|
170
|
+
[$item `miniature boiler`, $item `Steamboat`],
|
|
171
|
+
[$item `cold wad`, $item `Ghiaccio Colada`],
|
|
172
|
+
[$item `robin's egg`, $item `Nog-on-the-Cob`],
|
|
173
|
+
[$item `mangled finger`, $item `Sourfinger`],
|
|
174
|
+
[$item `Dish of Clarified Butter`, $item `Buttery Boy`],
|
|
175
|
+
]);
|
|
176
|
+
export const platinumCocktailToIngredient = invertMap(ingredientToPlatinumCocktail);
|
|
177
|
+
export function getCheapestPlatinumCocktail() {
|
|
178
|
+
return (maxBy(Array.from(ingredientToPlatinumCocktail), (ingredientAndCocktail) => mallPrice(ingredientAndCocktail[0])) ?? [$item `Dish of Clarified Butter`, $item `Buttery Boy`])[1];
|
|
179
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import maxBy from "lodash/maxBy";
|
|
2
2
|
import { getSaleValue } from "../lib";
|
|
3
|
-
import {
|
|
3
|
+
import { sumNumbers } from "../utils";
|
|
4
4
|
import { expected as candyHeartsExpected, have as candyHeartsHave, summonSkill as candyHeartsSkill, } from "./2007/CandyHearts";
|
|
5
5
|
import { expected as divineFavorsExpected, have as divineFavorsHave, summonSkill as divineFavorsSkill, } from "./2008/DivineFavors";
|
|
6
6
|
import { expected as loveSongsExpected, have as loveSongsHave, summonSkill as loveSongsSkill, } from "./2009/LoveSongs";
|
|
@@ -62,5 +62,5 @@ export function possibleLibramSummons() {
|
|
|
62
62
|
return results;
|
|
63
63
|
}
|
|
64
64
|
export function bestLibramToCast() {
|
|
65
|
-
return (maxBy(Array.from(possibleLibramSummons().entries()), ([, itemMap]) =>
|
|
65
|
+
return (maxBy(Array.from(possibleLibramSummons().entries()), ([, itemMap]) => sumNumbers(Array.from(itemMap.entries()).map(([item, weight]) => weight * getSaleValue(item)))) ?? [null])[0];
|
|
66
66
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import * as AsdonMartin from "./2017/AsdonMartin";
|
|
1
2
|
import * as Bandersnatch from "./2009/Bandersnatch";
|
|
2
3
|
import * as BeachComb from "./2019/BeachComb";
|
|
3
4
|
import * as ChateauMantegna from "./2015/ChateauMantegna";
|
|
4
5
|
import * as CrownOfThrones from "./2010/CrownOfThrones";
|
|
6
|
+
import * as DNALab from "./2014/DNALab";
|
|
5
7
|
import * as FloristFriar from "./2013/Florist";
|
|
6
8
|
import * as Guzzlr from "./2020/Guzzlr";
|
|
7
9
|
import * as MayoClinic from "./2015/MayoClinic";
|
|
@@ -14,6 +16,6 @@ import * as SpookyPutty from "./2009/SpookyPutty";
|
|
|
14
16
|
import * as TunnelOfLove from "./2017/TunnelOfLove";
|
|
15
17
|
import * as WinterGarden from "./2014/WinterGarden";
|
|
16
18
|
import * as Witchess from "./2016/Witchess";
|
|
17
|
-
export { Bandersnatch, BeachComb, ChateauMantegna, CrownOfThrones, FloristFriar, Guzzlr, MayoClinic, ObtuseAngel, RainDoh, SongBoom, SourceTerminal, Snapper, SpookyPutty, TunnelOfLove, WinterGarden, Witchess, };
|
|
19
|
+
export { AsdonMartin, Bandersnatch, BeachComb, ChateauMantegna, CrownOfThrones, DNALab, FloristFriar, Guzzlr, MayoClinic, ObtuseAngel, RainDoh, SongBoom, SourceTerminal, Snapper, SpookyPutty, TunnelOfLove, WinterGarden, Witchess, };
|
|
18
20
|
export * from "./putty-likes";
|
|
19
21
|
export * from "./LibramSummon";
|
package/dist/resources/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import * as AsdonMartin from "./2017/AsdonMartin";
|
|
1
2
|
import * as Bandersnatch from "./2009/Bandersnatch";
|
|
2
3
|
import * as BeachComb from "./2019/BeachComb";
|
|
3
4
|
import * as ChateauMantegna from "./2015/ChateauMantegna";
|
|
4
5
|
import * as CrownOfThrones from "./2010/CrownOfThrones";
|
|
6
|
+
import * as DNALab from "./2014/DNALab";
|
|
5
7
|
import * as FloristFriar from "./2013/Florist";
|
|
6
8
|
import * as Guzzlr from "./2020/Guzzlr";
|
|
7
9
|
import * as MayoClinic from "./2015/MayoClinic";
|
|
@@ -14,6 +16,6 @@ import * as SpookyPutty from "./2009/SpookyPutty";
|
|
|
14
16
|
import * as TunnelOfLove from "./2017/TunnelOfLove";
|
|
15
17
|
import * as WinterGarden from "./2014/WinterGarden";
|
|
16
18
|
import * as Witchess from "./2016/Witchess";
|
|
17
|
-
export { Bandersnatch, BeachComb, ChateauMantegna, CrownOfThrones, FloristFriar, Guzzlr, MayoClinic, ObtuseAngel, RainDoh, SongBoom, SourceTerminal, Snapper, SpookyPutty, TunnelOfLove, WinterGarden, Witchess, };
|
|
19
|
+
export { AsdonMartin, Bandersnatch, BeachComb, ChateauMantegna, CrownOfThrones, DNALab, FloristFriar, Guzzlr, MayoClinic, ObtuseAngel, RainDoh, SongBoom, SourceTerminal, Snapper, SpookyPutty, TunnelOfLove, WinterGarden, Witchess, };
|
|
18
20
|
export * from "./putty-likes";
|
|
19
21
|
export * from "./LibramSummon";
|
package/dist/utils.d.ts
CHANGED
|
@@ -39,3 +39,8 @@ export declare function arrayContains<T, A extends T>(item: T, array: ReadonlyAr
|
|
|
39
39
|
* @returns Whether the two arrays are equal, irrespective of order.
|
|
40
40
|
*/
|
|
41
41
|
export declare function setEqual<T>(a: T[], b: T[]): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Reverses keys and values for a given map
|
|
44
|
+
* @param map Map to invert
|
|
45
|
+
*/
|
|
46
|
+
export declare function invertMap<T1, T2>(map: Map<T1, T2>): Map<T2, T1>;
|
package/dist/utils.js
CHANGED
|
@@ -37,7 +37,7 @@ export function arrayToCountedMap(array) {
|
|
|
37
37
|
return map;
|
|
38
38
|
}
|
|
39
39
|
export function countedMapToArray(map) {
|
|
40
|
-
return [...map].
|
|
40
|
+
return [].concat(...[...map].map(([item, quantity]) => Array(quantity).fill(item)));
|
|
41
41
|
}
|
|
42
42
|
export function countedMapToString(map) {
|
|
43
43
|
return [...map].map(([item, quantity]) => `${quantity} x ${item}`).join(", ");
|
|
@@ -74,3 +74,14 @@ export function setEqual(a, b) {
|
|
|
74
74
|
return (a.length === b.length &&
|
|
75
75
|
sortedA.every((item, index) => item === sortedB[index]));
|
|
76
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Reverses keys and values for a given map
|
|
79
|
+
* @param map Map to invert
|
|
80
|
+
*/
|
|
81
|
+
export function invertMap(map) {
|
|
82
|
+
const returnValue = new Map();
|
|
83
|
+
for (const [key, value] of map) {
|
|
84
|
+
returnValue.set(value, key);
|
|
85
|
+
}
|
|
86
|
+
return returnValue;
|
|
87
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libram",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "JavaScript helper library for KoLmafia",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"clean": "rm -rf dist",
|
|
14
14
|
"docs": "yarn run typedoc",
|
|
15
15
|
"format": "yarn run prettier --write .",
|
|
16
|
-
"lint": "yarn run eslint src --ext .ts && yarn run prettier --check .",
|
|
16
|
+
"lint": "yarn run eslint src tools --ext .ts && yarn run prettier --check .",
|
|
17
17
|
"prepublishOnly": "yarn run build",
|
|
18
18
|
"updateProps": "yarn run ts-node ./tools/parseDefaultProperties.ts"
|
|
19
19
|
},
|
|
@@ -30,30 +30,36 @@
|
|
|
30
30
|
"@babel/plugin-transform-runtime": "^7.15.0",
|
|
31
31
|
"@babel/preset-env": "^7.15.0",
|
|
32
32
|
"@babel/preset-typescript": "^7.15.0",
|
|
33
|
+
"@tsconfig/node16": "^1.0.2",
|
|
34
|
+
"@types/jest": "^27.0.1",
|
|
33
35
|
"@types/lodash-es": "^4.17.4",
|
|
36
|
+
"@types/node": "^16.11.11",
|
|
34
37
|
"@types/node-fetch": "^2.5.7",
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
36
|
-
"@typescript-eslint/parser": "^
|
|
38
|
+
"@typescript-eslint/eslint-plugin": "^5.5.0",
|
|
39
|
+
"@typescript-eslint/parser": "^5.5.0",
|
|
37
40
|
"babel-loader": "^8.2.2",
|
|
38
41
|
"eslint": "^7.16.0",
|
|
39
42
|
"eslint-config-prettier": "^8.3.0",
|
|
40
43
|
"eslint-plugin-import": "^2.24.2",
|
|
44
|
+
"eslint-plugin-jest": "^25.2.3",
|
|
41
45
|
"eslint-plugin-libram": "^0.1.9",
|
|
42
46
|
"husky": "^4.3.6",
|
|
43
47
|
"java-parser": "^1.4.0",
|
|
48
|
+
"jest": "^27.1.0",
|
|
44
49
|
"lint-staged": ">=10",
|
|
45
50
|
"node-fetch": "^2.6.1",
|
|
46
51
|
"prettier": "^2.1.2",
|
|
47
|
-
"ts-
|
|
48
|
-
"
|
|
49
|
-
"
|
|
52
|
+
"ts-jest": "^27.0.5",
|
|
53
|
+
"ts-node": "^10.4.0",
|
|
54
|
+
"typedoc": "^0.22.10",
|
|
55
|
+
"typescript": "^4.5.2",
|
|
50
56
|
"webpack": "^5.10.0",
|
|
51
57
|
"webpack-cli": "^4.2.0"
|
|
52
58
|
},
|
|
53
59
|
"dependencies": {
|
|
54
60
|
"@babel/runtime-corejs3": "^7.14.9",
|
|
55
61
|
"core-js": "3.15.2",
|
|
56
|
-
"kolmafia": "^1.
|
|
62
|
+
"kolmafia": "^1.4.0",
|
|
57
63
|
"lodash": "^4.17.21"
|
|
58
64
|
},
|
|
59
65
|
"husky": {
|