libram 0.4.5 → 0.4.9
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 -72
- 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.js +35 -4
- 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,56 +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
|
-
size: -1,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
{ maximum: get("
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
+
}
|
|
108
117
|
/**
|
|
109
118
|
* Construct a new menu item, possibly with extra properties. Items in MenuItem.defaultOptions have intelligent defaults.
|
|
110
119
|
* @param item Item to add to menu.
|
|
@@ -112,17 +121,22 @@ export class MenuItem {
|
|
|
112
121
|
* @param options.size Override item organ size. Necessary for any non-food/booze/spleen item.
|
|
113
122
|
* @param options.maximum Maximum uses remaining today, or "auto" to check dailyusesleft Mafia property.
|
|
114
123
|
* @param options.additionalValue Additional value (positive) or cost (negative) to consider with item, e.g. from buffs.
|
|
115
|
-
* @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
|
|
116
127
|
*/
|
|
117
128
|
constructor(item, options = {}) {
|
|
118
|
-
const { size, organ, maximum, additionalValue,
|
|
129
|
+
const { size, organ, maximum, additionalValue, effect, priceOverride, mayo, data, } = {
|
|
119
130
|
...options,
|
|
120
|
-
...(MenuItem.defaultOptions.get(item) ?? {}),
|
|
131
|
+
...(MenuItem.defaultOptions().get(item) ?? {}),
|
|
121
132
|
};
|
|
122
133
|
this.item = item;
|
|
123
134
|
this.maximum = maximum === "auto" ? item.dailyusesleft : maximum;
|
|
124
135
|
this.additionalValue = additionalValue;
|
|
125
|
-
this.
|
|
136
|
+
this.effect = effect;
|
|
137
|
+
this.priceOverride = priceOverride;
|
|
138
|
+
this.mayo = mayo;
|
|
139
|
+
this.data = data;
|
|
126
140
|
const typ = itemType(this.item);
|
|
127
141
|
this.organ = organ ?? (isOrgan(typ) ? typ : undefined);
|
|
128
142
|
this.size =
|
|
@@ -136,13 +150,17 @@ export class MenuItem {
|
|
|
136
150
|
: 0);
|
|
137
151
|
}
|
|
138
152
|
equals(other) {
|
|
139
|
-
return this.item === other.item && this.
|
|
153
|
+
return this.item === other.item && this.effect === other.effect;
|
|
140
154
|
}
|
|
141
155
|
toString() {
|
|
156
|
+
if (this.effect) {
|
|
157
|
+
return `${this.item}:${this.effect}`;
|
|
158
|
+
}
|
|
142
159
|
return this.item.toString();
|
|
143
160
|
}
|
|
144
161
|
price() {
|
|
145
|
-
return
|
|
162
|
+
return (this.priceOverride ??
|
|
163
|
+
(npcPrice(this.item) > 0 ? npcPrice(this.item) : mallPrice(this.item)));
|
|
146
164
|
}
|
|
147
165
|
}
|
|
148
166
|
const organs = ["food", "booze", "spleen item"];
|
|
@@ -152,20 +170,24 @@ function isOrgan(x) {
|
|
|
152
170
|
class DietPlanner {
|
|
153
171
|
mpa;
|
|
154
172
|
menu;
|
|
173
|
+
mayoLookup;
|
|
155
174
|
fork;
|
|
156
175
|
mug;
|
|
157
176
|
seasoning;
|
|
158
|
-
mayoflex;
|
|
159
177
|
spleenValue = 0;
|
|
160
178
|
constructor(mpa, menu) {
|
|
161
179
|
this.mpa = mpa;
|
|
162
180
|
this.fork = menu.find((item) => item.item === $item `Ol' Scratch's salad fork`);
|
|
163
181
|
this.mug = menu.find((item) => item.item === $item `Frosty's frosty mug`);
|
|
164
182
|
this.seasoning = menu.find((item) => item.item === $item `Special Seasoning`);
|
|
165
|
-
this.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
+
}
|
|
169
191
|
this.menu = menu.filter((item) => item.organ);
|
|
170
192
|
if (menu.length > 100) {
|
|
171
193
|
mallPrices("food");
|
|
@@ -200,15 +222,19 @@ class DietPlanner {
|
|
|
200
222
|
this.mpa > mallPrice($item `Special Seasoning`)) {
|
|
201
223
|
helpers.push(this.seasoning);
|
|
202
224
|
}
|
|
203
|
-
if (this.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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);
|
|
207
231
|
}
|
|
208
232
|
const defaultModifiers = {
|
|
209
233
|
forkMug: false,
|
|
210
234
|
seasoning: this.seasoning ? helpers.includes(this.seasoning) : false,
|
|
211
|
-
mayoflex: this.
|
|
235
|
+
mayoflex: this.mayoLookup.size
|
|
236
|
+
? helpers.some((item) => item.item === Mayo.flex)
|
|
237
|
+
: false,
|
|
212
238
|
refinedPalate: have($effect `Refined Palate`),
|
|
213
239
|
garish: have($effect `Gar-ish`),
|
|
214
240
|
saucemaven: have($skill `Saucemaven`),
|
|
@@ -294,10 +320,10 @@ class DietPlanner {
|
|
|
294
320
|
}
|
|
295
321
|
const organCapacitiesWith = [...organCapacitiesWithMap];
|
|
296
322
|
const isRefinedPalate = (trialItem.item === $item `pocket wish` &&
|
|
297
|
-
trialItem.
|
|
323
|
+
trialItem.effect === $effect `Refined Palate`) ||
|
|
298
324
|
trialItem.item === $item `toasted brie`;
|
|
299
325
|
const isGarish = (trialItem.item === $item `pocket wish` &&
|
|
300
|
-
trialItem.
|
|
326
|
+
trialItem.effect === $effect `Gar-ish`) ||
|
|
301
327
|
trialItem.item === $item `potion of the field gar`;
|
|
302
328
|
const [valueWithout, planWithout] = this.planOrgansWithTrials(organCapacities, trialItems.slice(1), overrideModifiers);
|
|
303
329
|
const [valueWith, planWith] = this.planOrgansWithTrials(organCapacitiesWith, trialItems.slice(1), {
|
|
@@ -371,7 +397,7 @@ const interactingItems = [
|
|
|
371
397
|
* @param organCapacities Optional override of each organ's capacity.
|
|
372
398
|
* @returns Array of [menu item and helpers, count].
|
|
373
399
|
*/
|
|
374
|
-
|
|
400
|
+
function planDiet(mpa, menu, organCapacities = [
|
|
375
401
|
["food", null],
|
|
376
402
|
["booze", null],
|
|
377
403
|
["spleen item", null],
|
|
@@ -397,7 +423,7 @@ export function planDiet(mpa, menu, organCapacities = [
|
|
|
397
423
|
.map((menuItem) => {
|
|
398
424
|
const interacting = interactingItems.find(([itemOrEffect]) => menuItem.item === itemOrEffect ||
|
|
399
425
|
(menuItem.item === $item `pocket wish` &&
|
|
400
|
-
menuItem.
|
|
426
|
+
menuItem.effect === itemOrEffect));
|
|
401
427
|
if (interacting) {
|
|
402
428
|
const [, organSizes] = interacting;
|
|
403
429
|
return [menuItem, organSizes];
|
|
@@ -431,3 +457,127 @@ export function planDiet(mpa, menu, organCapacities = [
|
|
|
431
457
|
return planFoodBooze;
|
|
432
458
|
}
|
|
433
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
|
}
|