libram 0.4.6 → 0.5.0
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/combat.d.ts +19 -3
- package/dist/combat.js +43 -12
- package/dist/diet/index.d.ts +49 -14
- package/dist/diet/index.js +222 -75
- package/dist/freerun.d.ts +2 -1
- package/dist/freerun.js +6 -3
- package/dist/lib.d.ts +1 -0
- package/dist/lib.js +9 -2
- package/dist/maximize.d.ts +4 -2
- package/dist/maximize.js +41 -7
- package/dist/modifier.d.ts +6 -0
- package/dist/modifier.js +30 -0
- package/dist/mood.js +2 -1
- package/dist/property.d.ts +42 -2
- package/dist/property.js +69 -3
- package/dist/propertyTypes.d.ts +6 -6
- package/dist/resources/2013/Florist.d.ts +7 -4
- package/dist/resources/2013/Florist.js +108 -46
- package/dist/resources/2017/AsdonMartin.d.ts +8 -0
- package/dist/resources/2017/AsdonMartin.js +39 -7
- package/dist/resources/2018/LatteLoversMembersMug.d.ts +3 -0
- package/dist/resources/2018/LatteLoversMembersMug.js +13 -0
- package/dist/resources/2020/Guzzlr.d.ts +3 -1
- package/dist/resources/2020/Guzzlr.js +29 -2
- package/dist/resources/2021/CrystalBall.d.ts +1 -0
- package/dist/resources/2021/CrystalBall.js +15 -0
- package/dist/resources/index.d.ts +3 -1
- package/dist/resources/index.js +3 -1
- package/package.json +1 -1
- package/dist/Dungeon.d.ts +0 -37
- package/dist/Dungeon.js +0 -87
- package/dist/ring-buffer.d.ts +0 -24
- package/dist/ring-buffer.js +0 -135
package/dist/combat.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @category Combat
|
|
5
5
|
* @returns {number} The macro ID.
|
|
6
6
|
*/
|
|
7
|
-
export declare function getMacroId(): number;
|
|
7
|
+
export declare function getMacroId(name?: string): number;
|
|
8
8
|
declare type ItemOrName = Item | string;
|
|
9
9
|
declare type SkillOrName = Skill | string;
|
|
10
10
|
declare type Constructor<T> = {
|
|
@@ -21,13 +21,20 @@ export declare class InvalidMacroError extends Error {
|
|
|
21
21
|
*/
|
|
22
22
|
export declare class Macro {
|
|
23
23
|
static SAVED_MACRO_PROPERTY: string;
|
|
24
|
-
static
|
|
25
|
-
static
|
|
24
|
+
static cachedMacroIds: Map<string, number>;
|
|
25
|
+
static cachedAutoAttacks: Map<string, string>;
|
|
26
26
|
components: string[];
|
|
27
|
+
name: string;
|
|
27
28
|
/**
|
|
28
29
|
* Convert macro to string.
|
|
29
30
|
*/
|
|
30
31
|
toString(): string;
|
|
32
|
+
/**
|
|
33
|
+
* Gives your macro a new name to be used when saving an autoattack.
|
|
34
|
+
* @param name The name to be used when saving as an autoattack.
|
|
35
|
+
* @returns The previous name assigned to this macro.
|
|
36
|
+
*/
|
|
37
|
+
rename(name: string): string;
|
|
31
38
|
/**
|
|
32
39
|
* Save a macro to a Mafia property for use in a consult script.
|
|
33
40
|
*/
|
|
@@ -60,6 +67,15 @@ export declare class Macro {
|
|
|
60
67
|
* Set this macro as a KoL native autoattack.
|
|
61
68
|
*/
|
|
62
69
|
setAutoAttack(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Renames the macro, then sets it as an autoattack.
|
|
72
|
+
* @param name The name to save the macro under as an autoattack.
|
|
73
|
+
*/
|
|
74
|
+
setAutoAttackAs(name: string): void;
|
|
75
|
+
/**
|
|
76
|
+
* Clear all cached autoattacks, and delete all stored macros server-side.
|
|
77
|
+
*/
|
|
78
|
+
static clearAutoAttackMacros(): void;
|
|
63
79
|
/**
|
|
64
80
|
* Add an "abort" step to this macro.
|
|
65
81
|
* @returns {Macro} This object itself.
|
package/dist/combat.js
CHANGED
|
@@ -9,11 +9,11 @@ const MACRO_NAME = "Script Autoattack Macro";
|
|
|
9
9
|
* @category Combat
|
|
10
10
|
* @returns {number} The macro ID.
|
|
11
11
|
*/
|
|
12
|
-
export function getMacroId() {
|
|
13
|
-
const macroMatches = xpath(visitUrl("account_combatmacros.php"), `//select[@name="macroid"]/option[text()="${
|
|
12
|
+
export function getMacroId(name = MACRO_NAME) {
|
|
13
|
+
const macroMatches = xpath(visitUrl("account_combatmacros.php"), `//select[@name="macroid"]/option[text()="${name}"]/@value`);
|
|
14
14
|
if (macroMatches.length === 0) {
|
|
15
15
|
visitUrl("account_combatmacros.php?action=new");
|
|
16
|
-
const newMacroText = visitUrl(`account_combatmacros.php?macroid=0&name=${
|
|
16
|
+
const newMacroText = visitUrl(`account_combatmacros.php?macroid=0&name=${name}¯otext=abort&action=save`);
|
|
17
17
|
return parseInt(xpath(newMacroText, "//input[@name=macroid]/@value")[0], 10);
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
@@ -70,15 +70,26 @@ export class InvalidMacroError extends Error {
|
|
|
70
70
|
*/
|
|
71
71
|
export class Macro {
|
|
72
72
|
static SAVED_MACRO_PROPERTY = "libram_savedMacro";
|
|
73
|
-
static
|
|
74
|
-
static
|
|
73
|
+
static cachedMacroIds = new Map();
|
|
74
|
+
static cachedAutoAttacks = new Map();
|
|
75
75
|
components = [];
|
|
76
|
+
name = MACRO_NAME;
|
|
76
77
|
/**
|
|
77
78
|
* Convert macro to string.
|
|
78
79
|
*/
|
|
79
80
|
toString() {
|
|
80
81
|
return this.components.join(";");
|
|
81
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Gives your macro a new name to be used when saving an autoattack.
|
|
85
|
+
* @param name The name to be used when saving as an autoattack.
|
|
86
|
+
* @returns The previous name assigned to this macro.
|
|
87
|
+
*/
|
|
88
|
+
rename(name) {
|
|
89
|
+
const returnValue = this.name;
|
|
90
|
+
this.name = name;
|
|
91
|
+
return returnValue;
|
|
92
|
+
}
|
|
82
93
|
/**
|
|
83
94
|
* Save a macro to a Mafia property for use in a consult script.
|
|
84
95
|
*/
|
|
@@ -129,16 +140,36 @@ export class Macro {
|
|
|
129
140
|
* Set this macro as a KoL native autoattack.
|
|
130
141
|
*/
|
|
131
142
|
setAutoAttack() {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
143
|
+
let id = Macro.cachedMacroIds.get(this.name);
|
|
144
|
+
if (id === undefined)
|
|
145
|
+
Macro.cachedMacroIds.set(this.name, getMacroId(this.name));
|
|
146
|
+
id = getMacroId(this.name);
|
|
147
|
+
if (getAutoAttack() === 99000000 + id &&
|
|
148
|
+
this.toString() === Macro.cachedAutoAttacks.get(this.name)) {
|
|
136
149
|
// This macro is already set. Don"t make the server request.
|
|
137
150
|
return;
|
|
138
151
|
}
|
|
139
|
-
visitUrl(`account_combatmacros.php?macroid=${
|
|
140
|
-
visitUrl(`account.php?am=1&action=autoattack&value=${99000000 +
|
|
141
|
-
Macro.
|
|
152
|
+
visitUrl(`account_combatmacros.php?macroid=${id}&name=${urlEncode(this.name)}¯otext=${urlEncode(this.toString())}&action=save`, true, true);
|
|
153
|
+
visitUrl(`account.php?am=1&action=autoattack&value=${99000000 + id}&ajax=1`);
|
|
154
|
+
Macro.cachedAutoAttacks.set(this.name, this.toString());
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Renames the macro, then sets it as an autoattack.
|
|
158
|
+
* @param name The name to save the macro under as an autoattack.
|
|
159
|
+
*/
|
|
160
|
+
setAutoAttackAs(name) {
|
|
161
|
+
this.name = name;
|
|
162
|
+
this.setAutoAttack();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Clear all cached autoattacks, and delete all stored macros server-side.
|
|
166
|
+
*/
|
|
167
|
+
static clearAutoAttackMacros() {
|
|
168
|
+
for (const name of Macro.cachedAutoAttacks.keys()) {
|
|
169
|
+
const id = Macro.cachedMacroIds.get(name) ?? getMacroId(name);
|
|
170
|
+
visitUrl(`account_combatmacros.php?macroid=${id}&action=edit&what=Delete&confirm=1`);
|
|
171
|
+
Macro.cachedAutoAttacks.delete(name);
|
|
172
|
+
}
|
|
142
173
|
}
|
|
143
174
|
/**
|
|
144
175
|
* Add an "abort" step to this macro.
|
package/dist/diet/index.d.ts
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
declare type
|
|
1
|
+
declare type RawDietEntry<T> = [MenuItem<T>[], number];
|
|
2
|
+
declare type RawDiet<T> = RawDietEntry<T>[];
|
|
3
|
+
declare type MenuItemOptions<T> = {
|
|
2
4
|
organ?: Organ;
|
|
3
5
|
size?: number;
|
|
4
6
|
maximum?: number | "auto";
|
|
5
7
|
additionalValue?: number;
|
|
6
|
-
|
|
8
|
+
effect?: Effect;
|
|
9
|
+
priceOverride?: number;
|
|
10
|
+
mayo?: Item;
|
|
11
|
+
data?: T;
|
|
7
12
|
};
|
|
8
|
-
export declare class MenuItem {
|
|
13
|
+
export declare class MenuItem<T> {
|
|
9
14
|
item: Item;
|
|
10
15
|
organ?: Organ;
|
|
11
16
|
size: number;
|
|
12
17
|
maximum?: number;
|
|
13
18
|
additionalValue?: number;
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
effect?: Effect;
|
|
20
|
+
priceOverride?: number;
|
|
21
|
+
mayo?: Item;
|
|
22
|
+
data?: T;
|
|
23
|
+
static defaultOptions<T>(): Map<Item, MenuItemOptions<T>>;
|
|
16
24
|
/**
|
|
17
25
|
* Construct a new menu item, possibly with extra properties. Items in MenuItem.defaultOptions have intelligent defaults.
|
|
18
26
|
* @param item Item to add to menu.
|
|
@@ -20,21 +28,48 @@ export declare class MenuItem {
|
|
|
20
28
|
* @param options.size Override item organ size. Necessary for any non-food/booze/spleen item.
|
|
21
29
|
* @param options.maximum Maximum uses remaining today, or "auto" to check dailyusesleft Mafia property.
|
|
22
30
|
* @param options.additionalValue Additional value (positive) or cost (negative) to consider with item, e.g. from buffs.
|
|
23
|
-
* @param options.
|
|
31
|
+
* @param options.effect Effect associated with this menu item (pocket wish effect, sweet synthesis effect, pill keeper potion extension)
|
|
32
|
+
* @param options.mayo Which mayo to use before item (ignored if mayo clinic is not installed or item is not a food)
|
|
33
|
+
* @param options.note Any note to track information about item, to be used later
|
|
24
34
|
*/
|
|
25
|
-
constructor(item: Item, options?: MenuItemOptions);
|
|
26
|
-
equals(other: MenuItem): boolean;
|
|
35
|
+
constructor(item: Item, options?: MenuItemOptions<T>);
|
|
36
|
+
equals(other: MenuItem<T>): boolean;
|
|
27
37
|
toString(): string;
|
|
28
38
|
price(): number;
|
|
29
39
|
}
|
|
30
40
|
declare const organs: readonly ["food", "booze", "spleen item"];
|
|
31
41
|
declare type Organ = typeof organs[number];
|
|
42
|
+
declare class DietEntry<T> {
|
|
43
|
+
readonly menuItems: MenuItem<T>[];
|
|
44
|
+
quantity: number;
|
|
45
|
+
constructor(menuItems: MenuItem<T>[], quantity: number);
|
|
46
|
+
target(): MenuItem<T>;
|
|
47
|
+
helpers(): MenuItem<T>[];
|
|
48
|
+
expectedAdventures(diet: Diet<T>): number;
|
|
49
|
+
expectedValue(mpa: number, diet: Diet<T>, method?: "gross" | "net"): number;
|
|
50
|
+
expectedPrice(): number;
|
|
51
|
+
}
|
|
52
|
+
interface OrganCapacity {
|
|
53
|
+
food?: number | "auto";
|
|
54
|
+
booze?: number | "auto";
|
|
55
|
+
spleen?: number | "auto";
|
|
56
|
+
}
|
|
32
57
|
/**
|
|
33
|
-
*
|
|
34
|
-
* @param mpa Meat per adventure value.
|
|
35
|
-
* @param menu Array of MenuItems to consider for diet purposes.
|
|
36
|
-
* @param organCapacities Optional override of each organ's capacity.
|
|
37
|
-
* @returns Array of [menu item and helpers, count].
|
|
58
|
+
* A representation of a potential diet
|
|
38
59
|
*/
|
|
39
|
-
export declare
|
|
60
|
+
export declare class Diet<T> {
|
|
61
|
+
entries: DietEntry<T>[];
|
|
62
|
+
constructor(entries?: DietEntry<T>[]);
|
|
63
|
+
get refinedPalate(): boolean;
|
|
64
|
+
get garish(): boolean;
|
|
65
|
+
get saucemaven(): boolean;
|
|
66
|
+
get tuxedoShirt(): boolean;
|
|
67
|
+
get pinkyRing(): boolean;
|
|
68
|
+
expectedAdventures(): number;
|
|
69
|
+
expectedValue(mpa: number, method?: "gross" | "net"): number;
|
|
70
|
+
expectedPrice(): number;
|
|
71
|
+
copy(): Diet<T>;
|
|
72
|
+
static from<T>(rawDiet: RawDiet<T>): Diet<T>;
|
|
73
|
+
static plan<T>(mpa: number, menu: MenuItem<T>[], organCapacities?: OrganCapacity): Diet<T>;
|
|
74
|
+
}
|
|
40
75
|
export {};
|
package/dist/diet/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { canEquip, fullnessLimit,
|
|
1
|
+
import { canEquip, fullnessLimit, inebrietyLimit, itemType, mallPrice, mallPrices, myFullness, myInebriety, myLevel, myPrimestat, mySpleenUse, npcPrice, spleenLimit, } from "kolmafia";
|
|
2
2
|
import { knapsack } from "./knapsack";
|
|
3
3
|
import { have } from "../lib";
|
|
4
4
|
import { get as getModifier } from "../modifier";
|
|
5
5
|
import { get } from "../property";
|
|
6
6
|
import { $effect, $item, $items, $skill, $stat } from "../template-string";
|
|
7
|
-
import { sum } from "../utils";
|
|
7
|
+
import { sum, sumNumbers } from "../utils";
|
|
8
|
+
import { Mayo, installed as mayoInstalled } from "../resources/2015/MayoClinic";
|
|
8
9
|
function isMonday() {
|
|
9
10
|
// Checking Tuesday's ruby is a hack to see if it's Monday in Arizona.
|
|
10
11
|
return getModifier("Muscle Percent", $item `Tuesday's ruby`) > 0;
|
|
@@ -55,59 +56,64 @@ export class MenuItem {
|
|
|
55
56
|
size;
|
|
56
57
|
maximum;
|
|
57
58
|
additionalValue;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
59
|
+
effect;
|
|
60
|
+
priceOverride;
|
|
61
|
+
mayo;
|
|
62
|
+
data;
|
|
63
|
+
static defaultOptions() {
|
|
64
|
+
return new Map([
|
|
65
|
+
[
|
|
66
|
+
$item `distention pill`,
|
|
67
|
+
{
|
|
68
|
+
organ: "food",
|
|
69
|
+
maximum: !have($item `distention pill`) || get("_distentionPillUsed") ? 0 : 1,
|
|
70
|
+
size: -1,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
[
|
|
74
|
+
$item `synthetic dog hair pill`,
|
|
75
|
+
{
|
|
76
|
+
organ: "booze",
|
|
77
|
+
maximum: !have($item `synthetic dog hair pill`) ||
|
|
78
|
+
get("_syntheticDogHairPillUsed")
|
|
79
|
+
? 0
|
|
80
|
+
: 1,
|
|
81
|
+
size: -1,
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
$item `cuppa Voraci tea`,
|
|
86
|
+
{ organ: "food", maximum: get("_voraciTeaUsed") ? 0 : 1, size: -1 },
|
|
87
|
+
],
|
|
88
|
+
[
|
|
89
|
+
$item `cuppa Sobrie tea`,
|
|
90
|
+
{ organ: "booze", maximum: get("_sobrieTeaUsed") ? 0 : 1, size: -1 },
|
|
91
|
+
],
|
|
92
|
+
[
|
|
93
|
+
$item `mojo filter`,
|
|
94
|
+
{
|
|
95
|
+
organ: "spleen item",
|
|
96
|
+
maximum: 3 - get("currentMojoFilters"),
|
|
97
|
+
size: -1,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
[$item `spice melange`, { maximum: get("spiceMelangeUsed") ? 0 : 1 }],
|
|
101
|
+
[
|
|
102
|
+
$item `Ultra Mega Sour Ball`,
|
|
103
|
+
{ maximum: get("_ultraMegaSourBallUsed") ? 0 : 1 },
|
|
104
|
+
],
|
|
105
|
+
[
|
|
106
|
+
$item `The Plumber's mushroom stew`,
|
|
107
|
+
{ maximum: get("_plumbersMushroomStewEaten") ? 0 : 1 },
|
|
108
|
+
],
|
|
109
|
+
[$item `The Mad Liquor`, { maximum: get("_madLiquorDrunk") ? 0 : 1 }],
|
|
110
|
+
[
|
|
111
|
+
$item `Doc Clock's thyme cocktail`,
|
|
112
|
+
{ maximum: get("_docClocksThymeCocktailDrunk") ? 0 : 1 },
|
|
113
|
+
],
|
|
114
|
+
[$item `Mr. Burnsger`, { maximum: get("_mrBurnsgerEaten") ? 0 : 1 }],
|
|
115
|
+
]);
|
|
116
|
+
}
|
|
111
117
|
/**
|
|
112
118
|
* Construct a new menu item, possibly with extra properties. Items in MenuItem.defaultOptions have intelligent defaults.
|
|
113
119
|
* @param item Item to add to menu.
|
|
@@ -115,17 +121,22 @@ export class MenuItem {
|
|
|
115
121
|
* @param options.size Override item organ size. Necessary for any non-food/booze/spleen item.
|
|
116
122
|
* @param options.maximum Maximum uses remaining today, or "auto" to check dailyusesleft Mafia property.
|
|
117
123
|
* @param options.additionalValue Additional value (positive) or cost (negative) to consider with item, e.g. from buffs.
|
|
118
|
-
* @param options.
|
|
124
|
+
* @param options.effect Effect associated with this menu item (pocket wish effect, sweet synthesis effect, pill keeper potion extension)
|
|
125
|
+
* @param options.mayo Which mayo to use before item (ignored if mayo clinic is not installed or item is not a food)
|
|
126
|
+
* @param options.note Any note to track information about item, to be used later
|
|
119
127
|
*/
|
|
120
128
|
constructor(item, options = {}) {
|
|
121
|
-
const { size, organ, maximum, additionalValue,
|
|
129
|
+
const { size, organ, maximum, additionalValue, effect, priceOverride, mayo, data, } = {
|
|
122
130
|
...options,
|
|
123
|
-
...(MenuItem.defaultOptions.get(item) ?? {}),
|
|
131
|
+
...(MenuItem.defaultOptions().get(item) ?? {}),
|
|
124
132
|
};
|
|
125
133
|
this.item = item;
|
|
126
134
|
this.maximum = maximum === "auto" ? item.dailyusesleft : maximum;
|
|
127
135
|
this.additionalValue = additionalValue;
|
|
128
|
-
this.
|
|
136
|
+
this.effect = effect;
|
|
137
|
+
this.priceOverride = priceOverride;
|
|
138
|
+
this.mayo = mayo;
|
|
139
|
+
this.data = data;
|
|
129
140
|
const typ = itemType(this.item);
|
|
130
141
|
this.organ = organ ?? (isOrgan(typ) ? typ : undefined);
|
|
131
142
|
this.size =
|
|
@@ -139,13 +150,17 @@ export class MenuItem {
|
|
|
139
150
|
: 0);
|
|
140
151
|
}
|
|
141
152
|
equals(other) {
|
|
142
|
-
return this.item === other.item && this.
|
|
153
|
+
return this.item === other.item && this.effect === other.effect;
|
|
143
154
|
}
|
|
144
155
|
toString() {
|
|
156
|
+
if (this.effect) {
|
|
157
|
+
return `${this.item}:${this.effect}`;
|
|
158
|
+
}
|
|
145
159
|
return this.item.toString();
|
|
146
160
|
}
|
|
147
161
|
price() {
|
|
148
|
-
return
|
|
162
|
+
return (this.priceOverride ??
|
|
163
|
+
(npcPrice(this.item) > 0 ? npcPrice(this.item) : mallPrice(this.item)));
|
|
149
164
|
}
|
|
150
165
|
}
|
|
151
166
|
const organs = ["food", "booze", "spleen item"];
|
|
@@ -155,20 +170,24 @@ function isOrgan(x) {
|
|
|
155
170
|
class DietPlanner {
|
|
156
171
|
mpa;
|
|
157
172
|
menu;
|
|
173
|
+
mayoLookup;
|
|
158
174
|
fork;
|
|
159
175
|
mug;
|
|
160
176
|
seasoning;
|
|
161
|
-
mayoflex;
|
|
162
177
|
spleenValue = 0;
|
|
163
178
|
constructor(mpa, menu) {
|
|
164
179
|
this.mpa = mpa;
|
|
165
180
|
this.fork = menu.find((item) => item.item === $item `Ol' Scratch's salad fork`);
|
|
166
181
|
this.mug = menu.find((item) => item.item === $item `Frosty's frosty mug`);
|
|
167
182
|
this.seasoning = menu.find((item) => item.item === $item `Special Seasoning`);
|
|
168
|
-
this.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
183
|
+
this.mayoLookup = new Map();
|
|
184
|
+
if (mayoInstalled()) {
|
|
185
|
+
for (const mayo of [Mayo.flex, Mayo.zapine]) {
|
|
186
|
+
const menuItem = menu.find((item) => item.item === mayo);
|
|
187
|
+
if (menuItem)
|
|
188
|
+
this.mayoLookup.set(mayo, menuItem);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
172
191
|
this.menu = menu.filter((item) => item.organ);
|
|
173
192
|
if (menu.length > 100) {
|
|
174
193
|
mallPrices("food");
|
|
@@ -203,15 +222,19 @@ class DietPlanner {
|
|
|
203
222
|
this.mpa > mallPrice($item `Special Seasoning`)) {
|
|
204
223
|
helpers.push(this.seasoning);
|
|
205
224
|
}
|
|
206
|
-
if (this.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
225
|
+
if (itemType(menuItem.item) === "food" && this.mayoLookup.size) {
|
|
226
|
+
const mayo = menuItem.mayo
|
|
227
|
+
? this.mayoLookup.get(menuItem.mayo)
|
|
228
|
+
: this.mayoLookup.get(Mayo.flex);
|
|
229
|
+
if (mayo)
|
|
230
|
+
helpers.push(mayo);
|
|
210
231
|
}
|
|
211
232
|
const defaultModifiers = {
|
|
212
233
|
forkMug: false,
|
|
213
234
|
seasoning: this.seasoning ? helpers.includes(this.seasoning) : false,
|
|
214
|
-
mayoflex: this.
|
|
235
|
+
mayoflex: this.mayoLookup.size
|
|
236
|
+
? helpers.some((item) => item.item === Mayo.flex)
|
|
237
|
+
: false,
|
|
215
238
|
refinedPalate: have($effect `Refined Palate`),
|
|
216
239
|
garish: have($effect `Gar-ish`),
|
|
217
240
|
saucemaven: have($skill `Saucemaven`),
|
|
@@ -297,10 +320,10 @@ class DietPlanner {
|
|
|
297
320
|
}
|
|
298
321
|
const organCapacitiesWith = [...organCapacitiesWithMap];
|
|
299
322
|
const isRefinedPalate = (trialItem.item === $item `pocket wish` &&
|
|
300
|
-
trialItem.
|
|
323
|
+
trialItem.effect === $effect `Refined Palate`) ||
|
|
301
324
|
trialItem.item === $item `toasted brie`;
|
|
302
325
|
const isGarish = (trialItem.item === $item `pocket wish` &&
|
|
303
|
-
trialItem.
|
|
326
|
+
trialItem.effect === $effect `Gar-ish`) ||
|
|
304
327
|
trialItem.item === $item `potion of the field gar`;
|
|
305
328
|
const [valueWithout, planWithout] = this.planOrgansWithTrials(organCapacities, trialItems.slice(1), overrideModifiers);
|
|
306
329
|
const [valueWith, planWith] = this.planOrgansWithTrials(organCapacitiesWith, trialItems.slice(1), {
|
|
@@ -374,7 +397,7 @@ const interactingItems = [
|
|
|
374
397
|
* @param organCapacities Optional override of each organ's capacity.
|
|
375
398
|
* @returns Array of [menu item and helpers, count].
|
|
376
399
|
*/
|
|
377
|
-
|
|
400
|
+
function planDiet(mpa, menu, organCapacities = [
|
|
378
401
|
["food", null],
|
|
379
402
|
["booze", null],
|
|
380
403
|
["spleen item", null],
|
|
@@ -400,7 +423,7 @@ export function planDiet(mpa, menu, organCapacities = [
|
|
|
400
423
|
.map((menuItem) => {
|
|
401
424
|
const interacting = interactingItems.find(([itemOrEffect]) => menuItem.item === itemOrEffect ||
|
|
402
425
|
(menuItem.item === $item `pocket wish` &&
|
|
403
|
-
menuItem.
|
|
426
|
+
menuItem.effect === itemOrEffect));
|
|
404
427
|
if (interacting) {
|
|
405
428
|
const [, organSizes] = interacting;
|
|
406
429
|
return [menuItem, organSizes];
|
|
@@ -434,3 +457,127 @@ export function planDiet(mpa, menu, organCapacities = [
|
|
|
434
457
|
return planFoodBooze;
|
|
435
458
|
}
|
|
436
459
|
}
|
|
460
|
+
class DietEntry {
|
|
461
|
+
menuItems;
|
|
462
|
+
quantity;
|
|
463
|
+
constructor(menuItems, quantity) {
|
|
464
|
+
this.menuItems = menuItems;
|
|
465
|
+
this.quantity = quantity;
|
|
466
|
+
}
|
|
467
|
+
target() {
|
|
468
|
+
return this.menuItems[this.menuItems.length - 1];
|
|
469
|
+
}
|
|
470
|
+
helpers() {
|
|
471
|
+
if (this.menuItems.length > 1) {
|
|
472
|
+
return this.menuItems.slice(0, -1);
|
|
473
|
+
}
|
|
474
|
+
return [];
|
|
475
|
+
}
|
|
476
|
+
expectedAdventures(diet) {
|
|
477
|
+
{
|
|
478
|
+
if (this.menuItems.length === 0 || this.quantity === 0) {
|
|
479
|
+
return 0;
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
const items = this.menuItems.map((m) => m.item);
|
|
483
|
+
const targetItem = this.menuItems[this.menuItems.length - 1].item;
|
|
484
|
+
const fork = itemType(targetItem) === "food" &&
|
|
485
|
+
items.includes($item `Ol' Scratch's salad fork`);
|
|
486
|
+
const mug = itemType(targetItem) === "booze" &&
|
|
487
|
+
items.includes($item `Frosty's frosty mug`);
|
|
488
|
+
return (this.quantity *
|
|
489
|
+
expectedAdventures(this.menuItems[this.menuItems.length - 1].item, {
|
|
490
|
+
forkMug: fork || mug,
|
|
491
|
+
seasoning: items.includes($item `Special Seasoning`),
|
|
492
|
+
mayoflex: items.includes(Mayo.flex),
|
|
493
|
+
refinedPalate: diet.refinedPalate,
|
|
494
|
+
garish: diet.garish,
|
|
495
|
+
saucemaven: diet.saucemaven,
|
|
496
|
+
pinkyRing: diet.pinkyRing,
|
|
497
|
+
tuxedoShirt: diet.tuxedoShirt,
|
|
498
|
+
}));
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
expectedValue(mpa, diet, method = "gross") {
|
|
503
|
+
const adventures = this.expectedAdventures(diet);
|
|
504
|
+
const gross = this.quantity *
|
|
505
|
+
(mpa * adventures +
|
|
506
|
+
sumNumbers(this.menuItems.map((menuItem) => menuItem.additionalValue ?? 0)));
|
|
507
|
+
if (method === "gross") {
|
|
508
|
+
return gross;
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
return gross - this.expectedPrice();
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
expectedPrice() {
|
|
515
|
+
return (this.quantity *
|
|
516
|
+
sumNumbers(this.menuItems.map((menuItem) => menuItem.price())));
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* A representation of a potential diet
|
|
521
|
+
*/
|
|
522
|
+
export class Diet {
|
|
523
|
+
entries;
|
|
524
|
+
constructor(entries = []) {
|
|
525
|
+
this.entries = entries;
|
|
526
|
+
}
|
|
527
|
+
get refinedPalate() {
|
|
528
|
+
return this.entries.some((dietEntry) => dietEntry.menuItems.some((trialItem) => (trialItem.item === $item `pocket wish` &&
|
|
529
|
+
trialItem.effect === $effect `Refined Palate`) ||
|
|
530
|
+
trialItem.item === $item `toasted brie`));
|
|
531
|
+
}
|
|
532
|
+
get garish() {
|
|
533
|
+
return this.entries.some((dietEntry) => dietEntry.menuItems.some((trialItem) => (trialItem.item === $item `pocket wish` &&
|
|
534
|
+
trialItem.effect === $effect `Gar-ish`) ||
|
|
535
|
+
trialItem.item === $item `potion of the field gar`));
|
|
536
|
+
}
|
|
537
|
+
get saucemaven() {
|
|
538
|
+
return have($skill `Saucemaven`);
|
|
539
|
+
}
|
|
540
|
+
get tuxedoShirt() {
|
|
541
|
+
return have($item `tuxedo shirt`) && canEquip($item `tuxedo shirt`);
|
|
542
|
+
}
|
|
543
|
+
get pinkyRing() {
|
|
544
|
+
return have($item `mafia pinky ring`) && canEquip($item `mafia pinky ring`);
|
|
545
|
+
}
|
|
546
|
+
expectedAdventures() {
|
|
547
|
+
return sumNumbers(this.entries.map((dietEntry) => dietEntry.expectedAdventures(this)));
|
|
548
|
+
}
|
|
549
|
+
expectedValue(mpa, method = "gross") {
|
|
550
|
+
return sumNumbers(this.entries.map((dietEntry) => dietEntry.expectedValue(mpa, this, method)));
|
|
551
|
+
}
|
|
552
|
+
expectedPrice() {
|
|
553
|
+
return sumNumbers(this.entries.map((dietEntry) => dietEntry.expectedPrice()));
|
|
554
|
+
}
|
|
555
|
+
copy() {
|
|
556
|
+
return new Diet([...this.entries]);
|
|
557
|
+
}
|
|
558
|
+
static from(rawDiet) {
|
|
559
|
+
const diet = rawDiet.map((item) => {
|
|
560
|
+
const [menuItems, quantity] = item;
|
|
561
|
+
return new DietEntry(menuItems, quantity);
|
|
562
|
+
});
|
|
563
|
+
return new Diet(diet);
|
|
564
|
+
}
|
|
565
|
+
static plan(mpa, menu, organCapacities = {
|
|
566
|
+
food: "auto",
|
|
567
|
+
booze: "auto",
|
|
568
|
+
spleen: "auto",
|
|
569
|
+
}) {
|
|
570
|
+
const { food, booze, spleen } = organCapacities;
|
|
571
|
+
const plannerCapacity = [];
|
|
572
|
+
if (food) {
|
|
573
|
+
plannerCapacity.push(["food", food === "auto" ? null : food]);
|
|
574
|
+
}
|
|
575
|
+
if (booze) {
|
|
576
|
+
plannerCapacity.push(["booze", booze === "auto" ? null : booze]);
|
|
577
|
+
}
|
|
578
|
+
if (spleen) {
|
|
579
|
+
plannerCapacity.push(["spleen item", spleen === "auto" ? null : spleen]);
|
|
580
|
+
}
|
|
581
|
+
return Diet.from(planDiet(mpa, menu, plannerCapacity));
|
|
582
|
+
}
|
|
583
|
+
}
|
package/dist/freerun.d.ts
CHANGED
|
@@ -20,4 +20,5 @@ export declare class FreeRun {
|
|
|
20
20
|
options?: FreeRunOptions;
|
|
21
21
|
constructor(name: string, available: () => boolean, macro: Macro, options?: FreeRunOptions);
|
|
22
22
|
}
|
|
23
|
-
export declare function
|
|
23
|
+
export declare function tryFindFreeRun(useFamiliar?: boolean): FreeRun | null;
|
|
24
|
+
export declare function ensureFreeRun(useFamiliar?: boolean): FreeRun;
|
package/dist/freerun.js
CHANGED
|
@@ -87,10 +87,13 @@ function cheapestRunSource() {
|
|
|
87
87
|
}
|
|
88
88
|
function cheapestItemRun() {
|
|
89
89
|
const cheapestRun = cheapestRunSource();
|
|
90
|
-
return new FreeRun("Cheap Combat Item", () => retrieveItem(cheapestRun), Macro.trySkill($skill `Asdon Martin: Spring-Loaded Front Bumper`).item(
|
|
90
|
+
return new FreeRun("Cheap Combat Item", () => retrieveItem(cheapestRun), Macro.trySkill($skill `Asdon Martin: Spring-Loaded Front Bumper`).item(cheapestRun), {
|
|
91
91
|
preparation: () => retrieveItem(cheapestRun),
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
|
-
export function
|
|
95
|
-
return (freeRuns.find((run) => run.available() && (useFamiliar || run?.options?.familiar)) ??
|
|
94
|
+
export function tryFindFreeRun(useFamiliar = true) {
|
|
95
|
+
return (freeRuns.find((run) => run.available() && (useFamiliar || run?.options?.familiar)) ?? null);
|
|
96
|
+
}
|
|
97
|
+
export function ensureFreeRun(useFamiliar = true) {
|
|
98
|
+
return tryFindFreeRun(useFamiliar) ?? cheapestItemRun();
|
|
96
99
|
}
|