libram 0.8.26 → 0.8.28
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/package.json +9 -8
- package/dist/Clan.d.ts +0 -128
- package/dist/Clan.js +0 -300
- package/dist/Copier.d.ts +0 -9
- package/dist/Copier.js +0 -15
- package/dist/Dungeon.d.ts +0 -45
- package/dist/Dungeon.js +0 -115
- package/dist/Kmail.d.ts +0 -104
- package/dist/Kmail.js +0 -182
- package/dist/actions/ActionSource.d.ts +0 -131
- package/dist/actions/ActionSource.js +0 -177
- package/dist/actions/Banish.d.ts +0 -16
- package/dist/actions/Banish.js +0 -121
- package/dist/actions/FreeKill.d.ts +0 -16
- package/dist/actions/FreeKill.js +0 -94
- package/dist/actions/FreeRun.d.ts +0 -16
- package/dist/actions/FreeRun.js +0 -77
- package/dist/actions/index.d.ts +0 -4
- package/dist/actions/index.js +0 -4
- package/dist/ascend.d.ts +0 -83
- package/dist/ascend.js +0 -268
- package/dist/challengePaths/2014/HeavyRains.d.ts +0 -22
- package/dist/challengePaths/2014/HeavyRains.js +0 -75
- package/dist/challengePaths/2015/CommunityService.d.ts +0 -125
- package/dist/challengePaths/2015/CommunityService.js +0 -334
- package/dist/challengePaths/2016/NuclearAutumn.d.ts +0 -13
- package/dist/challengePaths/2016/NuclearAutumn.js +0 -21
- package/dist/challengePaths/index.d.ts +0 -4
- package/dist/challengePaths/index.js +0 -4
- package/dist/combat.d.ts +0 -414
- package/dist/combat.js +0 -711
- package/dist/console.d.ts +0 -12
- package/dist/console.js +0 -14
- package/dist/counter.d.ts +0 -22
- package/dist/counter.js +0 -37
- package/dist/diet/index.d.ts +0 -80
- package/dist/diet/index.js +0 -662
- package/dist/diet/knapsack.d.ts +0 -8
- package/dist/diet/knapsack.js +0 -128
- package/dist/index.d.ts +0 -29
- package/dist/index.js +0 -26
- package/dist/lib.d.ts +0 -497
- package/dist/lib.js +0 -958
- package/dist/logger.d.ts +0 -35
- package/dist/logger.js +0 -62
- package/dist/maximize.d.ts +0 -121
- package/dist/maximize.js +0 -525
- package/dist/modifier.d.ts +0 -41
- package/dist/modifier.js +0 -160
- package/dist/modifierTypes.d.ts +0 -16
- package/dist/modifierTypes.js +0 -9
- package/dist/mood.d.ts +0 -105
- package/dist/mood.js +0 -349
- package/dist/moonSign.d.ts +0 -13
- package/dist/moonSign.js +0 -25
- package/dist/overlappingNames.d.ts +0 -3
- package/dist/overlappingNames.js +0 -42
- package/dist/property.d.ts +0 -222
- package/dist/property.js +0 -385
- package/dist/propertyTypes.d.ts +0 -19
- package/dist/propertyTypes.js +0 -10
- package/dist/propertyTyping.d.ts +0 -65
- package/dist/propertyTyping.js +0 -91
- package/dist/resources/2007/CandyHearts.d.ts +0 -9
- package/dist/resources/2007/CandyHearts.js +0 -24
- package/dist/resources/2008/DivineFavors.d.ts +0 -9
- package/dist/resources/2008/DivineFavors.js +0 -27
- package/dist/resources/2008/Stickers.d.ts +0 -49
- package/dist/resources/2008/Stickers.js +0 -84
- package/dist/resources/2009/Bandersnatch.d.ts +0 -56
- package/dist/resources/2009/Bandersnatch.js +0 -93
- package/dist/resources/2009/LoveSongs.d.ts +0 -9
- package/dist/resources/2009/LoveSongs.js +0 -24
- package/dist/resources/2009/SpookyPutty.d.ts +0 -31
- package/dist/resources/2009/SpookyPutty.js +0 -49
- package/dist/resources/2010/Brickos.d.ts +0 -9
- package/dist/resources/2010/Brickos.js +0 -21
- package/dist/resources/2010/CrownOfThrones.d.ts +0 -68
- package/dist/resources/2010/CrownOfThrones.js +0 -418
- package/dist/resources/2010/LookingGlass.d.ts +0 -29
- package/dist/resources/2010/LookingGlass.js +0 -89
- package/dist/resources/2011/Gygaxian.d.ts +0 -9
- package/dist/resources/2011/Gygaxian.js +0 -24
- package/dist/resources/2011/ObtuseAngel.d.ts +0 -33
- package/dist/resources/2011/ObtuseAngel.js +0 -51
- package/dist/resources/2011/StompingBoots.d.ts +0 -37
- package/dist/resources/2011/StompingBoots.js +0 -57
- package/dist/resources/2012/RainDoh.d.ts +0 -25
- package/dist/resources/2012/RainDoh.js +0 -37
- package/dist/resources/2012/ReagnimatedGnome.d.ts +0 -31
- package/dist/resources/2012/ReagnimatedGnome.js +0 -46
- package/dist/resources/2012/Resolutions.d.ts +0 -9
- package/dist/resources/2012/Resolutions.js +0 -28
- package/dist/resources/2013/Florist.d.ts +0 -81
- package/dist/resources/2013/Florist.js +0 -245
- package/dist/resources/2013/JungMan.d.ts +0 -33
- package/dist/resources/2013/JungMan.js +0 -69
- package/dist/resources/2013/PulledTaffy.d.ts +0 -9
- package/dist/resources/2013/PulledTaffy.js +0 -33
- package/dist/resources/2014/CrimboShrub.d.ts +0 -42
- package/dist/resources/2014/CrimboShrub.js +0 -89
- package/dist/resources/2014/DNALab.d.ts +0 -56
- package/dist/resources/2014/DNALab.js +0 -162
- package/dist/resources/2014/WinterGarden.d.ts +0 -23
- package/dist/resources/2014/WinterGarden.js +0 -35
- package/dist/resources/2015/BarrelShrine.d.ts +0 -8
- package/dist/resources/2015/BarrelShrine.js +0 -25
- package/dist/resources/2015/ChateauMantegna.d.ts +0 -52
- package/dist/resources/2015/ChateauMantegna.js +0 -99
- package/dist/resources/2015/DeckOfEveryCard.d.ts +0 -29
- package/dist/resources/2015/DeckOfEveryCard.js +0 -122
- package/dist/resources/2015/Dinseylandfill.d.ts +0 -89
- package/dist/resources/2015/Dinseylandfill.js +0 -205
- package/dist/resources/2015/MayoClinic.d.ts +0 -23
- package/dist/resources/2015/MayoClinic.js +0 -49
- package/dist/resources/2016/GingerBread.d.ts +0 -32
- package/dist/resources/2016/GingerBread.js +0 -73
- package/dist/resources/2016/SourceTerminal.d.ts +0 -181
- package/dist/resources/2016/SourceTerminal.js +0 -275
- package/dist/resources/2016/Witchess.d.ts +0 -17
- package/dist/resources/2016/Witchess.js +0 -47
- package/dist/resources/2017/AsdonMartin.d.ts +0 -59
- package/dist/resources/2017/AsdonMartin.js +0 -238
- package/dist/resources/2017/Horsery.d.ts +0 -19
- package/dist/resources/2017/Horsery.js +0 -42
- package/dist/resources/2017/MummingTrunk.d.ts +0 -8
- package/dist/resources/2017/MummingTrunk.js +0 -33
- package/dist/resources/2017/Pantogram.d.ts +0 -92
- package/dist/resources/2017/Pantogram.js +0 -174
- package/dist/resources/2017/Robortender.d.ts +0 -30
- package/dist/resources/2017/Robortender.js +0 -90
- package/dist/resources/2017/Spacegate.d.ts +0 -86
- package/dist/resources/2017/Spacegate.js +0 -178
- package/dist/resources/2017/TunnelOfLove.d.ts +0 -39
- package/dist/resources/2017/TunnelOfLove.js +0 -120
- package/dist/resources/2018/LatteLoversMembersMug.d.ts +0 -392
- package/dist/resources/2018/LatteLoversMembersMug.js +0 -303
- package/dist/resources/2018/SongBoom.d.ts +0 -33
- package/dist/resources/2018/SongBoom.js +0 -55
- package/dist/resources/2019/BeachComb.d.ts +0 -72
- package/dist/resources/2019/BeachComb.js +0 -118
- package/dist/resources/2019/CampAway.d.ts +0 -39
- package/dist/resources/2019/CampAway.js +0 -72
- package/dist/resources/2019/Snapper.d.ts +0 -33
- package/dist/resources/2019/Snapper.js +0 -73
- package/dist/resources/2020/Cartography.d.ts +0 -16
- package/dist/resources/2020/Cartography.js +0 -48
- package/dist/resources/2020/Guzzlr.d.ts +0 -160
- package/dist/resources/2020/Guzzlr.js +0 -275
- package/dist/resources/2020/RetroCape.d.ts +0 -51
- package/dist/resources/2020/RetroCape.js +0 -115
- package/dist/resources/2021/CrystalBall.d.ts +0 -14
- package/dist/resources/2021/CrystalBall.js +0 -39
- package/dist/resources/2021/DaylightShavings.d.ts +0 -40
- package/dist/resources/2021/DaylightShavings.js +0 -74
- package/dist/resources/2022/AutumnAton.d.ts +0 -78
- package/dist/resources/2022/AutumnAton.js +0 -182
- package/dist/resources/2022/CombatLoversLocket.d.ts +0 -44
- package/dist/resources/2022/CombatLoversLocket.js +0 -82
- package/dist/resources/2022/GreyGoose.d.ts +0 -59
- package/dist/resources/2022/GreyGoose.js +0 -90
- package/dist/resources/2022/JuneCleaver.d.ts +0 -47
- package/dist/resources/2022/JuneCleaver.js +0 -69
- package/dist/resources/2022/TrainSet.d.ts +0 -146
- package/dist/resources/2022/TrainSet.js +0 -228
- package/dist/resources/2023/AugustScepter.d.ts +0 -25
- package/dist/resources/2023/AugustScepter.js +0 -40
- package/dist/resources/2023/BurningLeaves.d.ts +0 -25
- package/dist/resources/2023/BurningLeaves.js +0 -74
- package/dist/resources/2023/CinchoDeMayo.d.ts +0 -25
- package/dist/resources/2023/CinchoDeMayo.js +0 -45
- package/dist/resources/2023/ClosedCircuitPayphone.d.ts +0 -80
- package/dist/resources/2023/ClosedCircuitPayphone.js +0 -129
- package/dist/resources/2023/CursedMonkeyPaw.d.ts +0 -46
- package/dist/resources/2023/CursedMonkeyPaw.js +0 -113
- package/dist/resources/2024/AprilingBandHelmet.d.ts +0 -50
- package/dist/resources/2024/AprilingBandHelmet.js +0 -103
- package/dist/resources/2024/ChestMimic.d.ts +0 -35
- package/dist/resources/2024/ChestMimic.js +0 -108
- package/dist/resources/LibramSummon.d.ts +0 -18
- package/dist/resources/LibramSummon.js +0 -74
- package/dist/resources/index.d.ts +0 -54
- package/dist/resources/index.js +0 -54
- package/dist/resources/putty-likes.d.ts +0 -21
- package/dist/resources/putty-likes.js +0 -33
- package/dist/session.d.ts +0 -169
- package/dist/session.js +0 -284
- package/dist/since.d.ts +0 -51
- package/dist/since.js +0 -108
- package/dist/template-string.d.ts +0 -324
- package/dist/template-string.js +0 -265
- package/dist/url.d.ts +0 -35
- package/dist/url.js +0 -67
- package/dist/utils.d.ts +0 -178
- package/dist/utils.js +0 -255
package/dist/maximize.js
DELETED
|
@@ -1,525 +0,0 @@
|
|
|
1
|
-
import { availableAmount, bjornifyFamiliar, canEquip, cliExecute, enthroneFamiliar, equip, equippedAmount, equippedItem, getProperty, haveEquipped, isWearingOutfit, Item, maximize, myBasestat, myBjornedFamiliar, myEnthronedFamiliar, myFamiliar, outfit, Slot, } from "kolmafia";
|
|
2
|
-
import { have } from "./lib";
|
|
3
|
-
import logger from "./logger";
|
|
4
|
-
import { $effect, $familiar, $item, $slot, $slots, $stats, } from "./template-string";
|
|
5
|
-
import { setEqual } from "./utils";
|
|
6
|
-
function toMaximizerName({ name, id }) {
|
|
7
|
-
return name.includes(";") ? `¶${id}` : name;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Merges a partial set of maximizer options onto a full set maximizer options. We merge via overriding for all boolean properties and for onlySlot, and concat all other array properties.
|
|
11
|
-
*
|
|
12
|
-
* @param defaultOptions MaximizeOptions to use as a "base."
|
|
13
|
-
* @param addendums Options to attempt to merge onto defaultOptions.
|
|
14
|
-
* @returns Merged maximizer options
|
|
15
|
-
*/
|
|
16
|
-
export function mergeMaximizeOptions(defaultOptions, addendums) {
|
|
17
|
-
return {
|
|
18
|
-
updateOnFamiliarChange: addendums.updateOnFamiliarChange ?? defaultOptions.updateOnFamiliarChange,
|
|
19
|
-
updateOnCanEquipChanged: addendums.updateOnCanEquipChanged ??
|
|
20
|
-
defaultOptions.updateOnCanEquipChanged,
|
|
21
|
-
useOutfitCaching: addendums.useOutfitCaching ?? defaultOptions.useOutfitCaching,
|
|
22
|
-
forceEquip: [...defaultOptions.forceEquip, ...(addendums.forceEquip ?? [])],
|
|
23
|
-
preventEquip: [
|
|
24
|
-
...defaultOptions.preventEquip,
|
|
25
|
-
...(addendums.preventEquip ?? []),
|
|
26
|
-
].filter((item) => !defaultOptions.forceEquip.includes(item) &&
|
|
27
|
-
!addendums.forceEquip?.includes(item)),
|
|
28
|
-
bonusEquip: new Map([
|
|
29
|
-
...defaultOptions.bonusEquip,
|
|
30
|
-
...(addendums.bonusEquip ?? []),
|
|
31
|
-
]),
|
|
32
|
-
onlySlot: addendums.onlySlot ?? defaultOptions.onlySlot,
|
|
33
|
-
preventSlot: [
|
|
34
|
-
...defaultOptions.preventSlot,
|
|
35
|
-
...(addendums.preventSlot ?? []),
|
|
36
|
-
],
|
|
37
|
-
forceUpdate: addendums.forceUpdate ?? defaultOptions.forceUpdate,
|
|
38
|
-
modes: { ...defaultOptions.modes, ...(addendums.modes ?? {}) },
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const defaultMaximizeOptions = {
|
|
42
|
-
updateOnFamiliarChange: true,
|
|
43
|
-
updateOnCanEquipChanged: true,
|
|
44
|
-
useOutfitCaching: true,
|
|
45
|
-
forceEquip: [],
|
|
46
|
-
preventEquip: [],
|
|
47
|
-
bonusEquip: new Map(),
|
|
48
|
-
onlySlot: [],
|
|
49
|
-
preventSlot: [],
|
|
50
|
-
forceUpdate: false,
|
|
51
|
-
modes: {},
|
|
52
|
-
};
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
* @param options Default options for each maximizer run.
|
|
56
|
-
* @param options.updateOnFamiliarChange Re-run the maximizer if familiar has changed. Default true.
|
|
57
|
-
* @param options.updateOnCanEquipChanged Re-run the maximizer if stats have changed what can be equipped. Default true.
|
|
58
|
-
* @param options.forceEquip Equipment to force-equip ("equip X").
|
|
59
|
-
* @param options.preventEquip Equipment to prevent equipping ("-equip X").
|
|
60
|
-
* @param options.bonusEquip Equipment to apply a bonus to ("200 bonus X").
|
|
61
|
-
*/
|
|
62
|
-
export function setDefaultMaximizeOptions(options) {
|
|
63
|
-
Object.assign(defaultMaximizeOptions, options);
|
|
64
|
-
}
|
|
65
|
-
const modeableCommands = [
|
|
66
|
-
"backupcamera",
|
|
67
|
-
"umbrella",
|
|
68
|
-
"snowsuit",
|
|
69
|
-
"edpiece",
|
|
70
|
-
"retrocape",
|
|
71
|
-
"parka",
|
|
72
|
-
"jillcandle",
|
|
73
|
-
];
|
|
74
|
-
export const modeableItems = {
|
|
75
|
-
backupcamera: $item `backup camera`,
|
|
76
|
-
umbrella: $item `unbreakable umbrella`,
|
|
77
|
-
snowsuit: $item `Snow Suit`,
|
|
78
|
-
edpiece: $item `The Crown of Ed the Undying`,
|
|
79
|
-
retrocape: $item `unwrapped knock-off retro superhero cape`,
|
|
80
|
-
parka: $item `Jurassic Parka`,
|
|
81
|
-
jillcandle: $item `LED candle`,
|
|
82
|
-
};
|
|
83
|
-
export const modeableState = {
|
|
84
|
-
backupcamera: () => getProperty("backupCameraMode"),
|
|
85
|
-
umbrella: () => getProperty("umbrellaState"),
|
|
86
|
-
snowsuit: () => getProperty("snowsuit"),
|
|
87
|
-
edpiece: () => getProperty("edPiece"),
|
|
88
|
-
retrocape: () => getProperty("retroCapeSuperhero") +
|
|
89
|
-
" " +
|
|
90
|
-
getProperty("retroCapeWashingInstructions"),
|
|
91
|
-
parka: () => getProperty("parkaMode"),
|
|
92
|
-
jillcandle: () => getProperty("ledCandleMode"),
|
|
93
|
-
};
|
|
94
|
-
/**
|
|
95
|
-
* Get set of current modes for modeables
|
|
96
|
-
*
|
|
97
|
-
* @returns Set of modes
|
|
98
|
-
*/
|
|
99
|
-
export function getCurrentModes() {
|
|
100
|
-
const modes = {};
|
|
101
|
-
for (const key of modeableCommands) {
|
|
102
|
-
if (haveEquipped(modeableItems[key])) {
|
|
103
|
-
modes[key] = modeableState[key]();
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return modes;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Apply set of modes
|
|
110
|
-
*
|
|
111
|
-
* @param modes Modes to apply
|
|
112
|
-
*/
|
|
113
|
-
export function applyModes(modes) {
|
|
114
|
-
for (const command of modeableCommands) {
|
|
115
|
-
if (haveEquipped(modeableItems[command]) && modes[command] !== undefined) {
|
|
116
|
-
if (modeableState[command]() !== modes[command]) {
|
|
117
|
-
cliExecute(command + " " + modes[command]);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// Subset of slots that are valid for caching.
|
|
123
|
-
const cachedSlots = $slots `hat, weapon, off-hand, back, shirt, pants, acc1, acc2, acc3, familiar`;
|
|
124
|
-
class CacheEntry {
|
|
125
|
-
equipment;
|
|
126
|
-
rider;
|
|
127
|
-
familiar;
|
|
128
|
-
canEquipItemCount;
|
|
129
|
-
modes;
|
|
130
|
-
constructor(equipment, rider, familiar, canEquipItemCount, modes) {
|
|
131
|
-
this.equipment = equipment;
|
|
132
|
-
this.rider = rider;
|
|
133
|
-
this.familiar = familiar;
|
|
134
|
-
this.canEquipItemCount = canEquipItemCount;
|
|
135
|
-
this.modes = modes;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
class OutfitLRUCache {
|
|
139
|
-
static OUTFIT_PREFIX = "Script Outfit";
|
|
140
|
-
// Current outfits allocated
|
|
141
|
-
#outfitSlots = [];
|
|
142
|
-
// Array of indices into #outfitSlots in order of use. Most recent at the front.
|
|
143
|
-
#useHistory = [];
|
|
144
|
-
#maxSize;
|
|
145
|
-
constructor(maxSize) {
|
|
146
|
-
this.#maxSize = maxSize;
|
|
147
|
-
}
|
|
148
|
-
checkConsistent() {
|
|
149
|
-
if (this.#useHistory.length !== this.#outfitSlots.length ||
|
|
150
|
-
![...this.#useHistory].sort().every((value, index) => value === index)) {
|
|
151
|
-
throw new Error("Outfit cache consistency failed.");
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
promote(index) {
|
|
155
|
-
this.#useHistory = [index, ...this.#useHistory.filter((i) => i !== index)];
|
|
156
|
-
this.checkConsistent();
|
|
157
|
-
}
|
|
158
|
-
get(key) {
|
|
159
|
-
const index = this.#outfitSlots.indexOf(key);
|
|
160
|
-
if (index < 0)
|
|
161
|
-
return undefined;
|
|
162
|
-
this.promote(index);
|
|
163
|
-
return `${OutfitLRUCache.OUTFIT_PREFIX} ${index}`;
|
|
164
|
-
}
|
|
165
|
-
insert(key) {
|
|
166
|
-
let lastUseIndex = undefined;
|
|
167
|
-
if (this.#outfitSlots.length >= this.#maxSize) {
|
|
168
|
-
lastUseIndex = this.#useHistory.pop();
|
|
169
|
-
if (lastUseIndex === undefined) {
|
|
170
|
-
throw new Error("Outfit cache consistency failed.");
|
|
171
|
-
}
|
|
172
|
-
this.#useHistory.splice(0, 0, lastUseIndex);
|
|
173
|
-
this.#outfitSlots[lastUseIndex] = key;
|
|
174
|
-
this.checkConsistent();
|
|
175
|
-
return `${OutfitLRUCache.OUTFIT_PREFIX} ${lastUseIndex}`;
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
const index = this.#outfitSlots.push(key) - 1;
|
|
179
|
-
this.#useHistory.splice(0, 0, index);
|
|
180
|
-
this.checkConsistent();
|
|
181
|
-
return `${OutfitLRUCache.OUTFIT_PREFIX} ${index}`;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
clear() {
|
|
185
|
-
this.#outfitSlots = [];
|
|
186
|
-
this.#useHistory = [];
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Save current equipment as KoL-native outfit.
|
|
191
|
-
*
|
|
192
|
-
* @param name Name of new outfit.
|
|
193
|
-
*/
|
|
194
|
-
function saveOutfit(name) {
|
|
195
|
-
cliExecute(`outfit save ${name}`);
|
|
196
|
-
}
|
|
197
|
-
// Objective cache entries.
|
|
198
|
-
const cachedObjectives = {};
|
|
199
|
-
// Outfit cache entries. Keep 6 by default to avoid cluttering list.
|
|
200
|
-
const outfitCache = new OutfitLRUCache(6);
|
|
201
|
-
// Cache to prevent rescanning all items unnecessarily
|
|
202
|
-
let cachedStats = [0, 0, 0];
|
|
203
|
-
let cachedCanEquipItemCount = 0;
|
|
204
|
-
/**
|
|
205
|
-
* Count the number of unique items that can be equipped.
|
|
206
|
-
*
|
|
207
|
-
* @returns The count of unique items.
|
|
208
|
-
*/
|
|
209
|
-
function canEquipItemCount() {
|
|
210
|
-
const stats = $stats `Muscle, Mysticality, Moxie`.map((stat) => Math.min(myBasestat(stat), 300));
|
|
211
|
-
if (stats.every((value, index) => value === cachedStats[index])) {
|
|
212
|
-
return cachedCanEquipItemCount;
|
|
213
|
-
}
|
|
214
|
-
cachedStats = stats;
|
|
215
|
-
cachedCanEquipItemCount = Item.all().filter((item) => canEquip(item)).length;
|
|
216
|
-
return cachedCanEquipItemCount;
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Checks the objective cache for a valid entry.
|
|
220
|
-
*
|
|
221
|
-
* @param cacheKey The cache key to check.
|
|
222
|
-
* @param options Set of maximizer options
|
|
223
|
-
* @returns A valid CacheEntry or null.
|
|
224
|
-
*/
|
|
225
|
-
function checkCache(cacheKey, options) {
|
|
226
|
-
const entry = cachedObjectives[cacheKey];
|
|
227
|
-
if (!entry) {
|
|
228
|
-
return null;
|
|
229
|
-
}
|
|
230
|
-
if (options.updateOnFamiliarChange && myFamiliar() !== entry.familiar) {
|
|
231
|
-
logger.warning("Equipment found in maximize cache but familiar is different.");
|
|
232
|
-
return null;
|
|
233
|
-
}
|
|
234
|
-
if (options.updateOnCanEquipChanged &&
|
|
235
|
-
entry.canEquipItemCount !== canEquipItemCount()) {
|
|
236
|
-
logger.warning("Equipment found in maximize cache but equippable item list is out of date.");
|
|
237
|
-
return null;
|
|
238
|
-
}
|
|
239
|
-
return entry;
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Applies equipment that was found in the cache.
|
|
243
|
-
*
|
|
244
|
-
* @param entry The CacheEntry to apply
|
|
245
|
-
* @param options Set of maximizer options
|
|
246
|
-
*/
|
|
247
|
-
function applyCached(entry, options) {
|
|
248
|
-
const outfitName = options.useOutfitCaching
|
|
249
|
-
? outfitCache.get(entry)
|
|
250
|
-
: undefined;
|
|
251
|
-
if (outfitName) {
|
|
252
|
-
if (!isWearingOutfit(outfitName)) {
|
|
253
|
-
outfit(outfitName);
|
|
254
|
-
}
|
|
255
|
-
const familiarEquip = entry.equipment.get($slot `familiar`);
|
|
256
|
-
if (familiarEquip)
|
|
257
|
-
equip($slot `familiar`, familiarEquip);
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
for (const [slot, item] of entry.equipment) {
|
|
261
|
-
if (equippedItem(slot) !== item && availableAmount(item) > 0) {
|
|
262
|
-
equip(slot, item);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
if (verifyCached(entry) && options.useOutfitCaching) {
|
|
266
|
-
const outfitName = outfitCache.insert(entry);
|
|
267
|
-
logger.info(`Saving equipment to outfit ${outfitName}.`);
|
|
268
|
-
saveOutfit(outfitName);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
if (equippedAmount($item `Crown of Thrones`) > 0 &&
|
|
272
|
-
entry.rider.get($item `Crown of Thrones`)) {
|
|
273
|
-
enthroneFamiliar(entry.rider.get($item `Crown of Thrones`) || $familiar.none);
|
|
274
|
-
}
|
|
275
|
-
if (equippedAmount($item `Buddy Bjorn`) > 0 &&
|
|
276
|
-
entry.rider.get($item `Buddy Bjorn`)) {
|
|
277
|
-
bjornifyFamiliar(entry.rider.get($item `Buddy Bjorn`) || $familiar.none);
|
|
278
|
-
}
|
|
279
|
-
applyModes({ ...entry.modes, ...options.modes });
|
|
280
|
-
}
|
|
281
|
-
const slotStructure = [
|
|
282
|
-
$slots `hat`,
|
|
283
|
-
$slots `back`,
|
|
284
|
-
$slots `shirt`,
|
|
285
|
-
$slots `weapon, off-hand`,
|
|
286
|
-
$slots `pants`,
|
|
287
|
-
$slots `acc1, acc2, acc3`,
|
|
288
|
-
$slots `familiar`,
|
|
289
|
-
];
|
|
290
|
-
/**
|
|
291
|
-
* Verifies that a CacheEntry was applied successfully.
|
|
292
|
-
*
|
|
293
|
-
* @param entry The CacheEntry to verify
|
|
294
|
-
* @param warn Whether to warn if the cache could not be applied
|
|
295
|
-
* @returns If all desired equipment was appliedn in the correct slots.
|
|
296
|
-
*/
|
|
297
|
-
function verifyCached(entry, warn = true) {
|
|
298
|
-
let success = true;
|
|
299
|
-
for (const slotGroup of slotStructure) {
|
|
300
|
-
const desiredSlots = slotGroup
|
|
301
|
-
.map((slot) => [slot, entry.equipment.get(slot) ?? null])
|
|
302
|
-
.filter(([, item]) => item !== null);
|
|
303
|
-
const desiredSet = desiredSlots.map(([, item]) => item);
|
|
304
|
-
const equippedSet = desiredSlots.map(([slot]) => equippedItem(slot));
|
|
305
|
-
if (!setEqual(desiredSet, equippedSet)) {
|
|
306
|
-
if (warn) {
|
|
307
|
-
logger.warning(`Failed to apply cached ${desiredSet.join(", ")} in ${slotGroup.join(", ")}.`);
|
|
308
|
-
}
|
|
309
|
-
success = false;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
if (equippedAmount($item `Crown of Thrones`) > 0 &&
|
|
313
|
-
entry.rider.get($item `Crown of Thrones`)) {
|
|
314
|
-
if (entry.rider.get($item `Crown of Thrones`) !== myEnthronedFamiliar()) {
|
|
315
|
-
if (warn) {
|
|
316
|
-
logger.warning(`Failed to apply ${entry.rider.get($item `Crown of Thrones`)} in ${$item `Crown of Thrones`}.`);
|
|
317
|
-
}
|
|
318
|
-
success = false;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
if (equippedAmount($item `Buddy Bjorn`) > 0 &&
|
|
322
|
-
entry.rider.get($item `Buddy Bjorn`)) {
|
|
323
|
-
if (entry.rider.get($item `Buddy Bjorn`) !== myBjornedFamiliar()) {
|
|
324
|
-
if (warn) {
|
|
325
|
-
logger.warning(`Failed to apply${entry.rider.get($item `Buddy Bjorn`)} in ${$item `Buddy Bjorn`}.`);
|
|
326
|
-
}
|
|
327
|
-
success = false;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
return success;
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Save current equipment to the objective cache.
|
|
334
|
-
*
|
|
335
|
-
* @param cacheKey The cache key to save.
|
|
336
|
-
* @param options Set of maximizer options
|
|
337
|
-
*/
|
|
338
|
-
function saveCached(cacheKey, options) {
|
|
339
|
-
const equipment = new Map();
|
|
340
|
-
const rider = new Map();
|
|
341
|
-
for (const slot of cachedSlots) {
|
|
342
|
-
equipment.set(slot, equippedItem(slot));
|
|
343
|
-
}
|
|
344
|
-
if (equippedAmount($item `card sleeve`) > 0) {
|
|
345
|
-
equipment.set($slot `card-sleeve`, equippedItem($slot `card-sleeve`));
|
|
346
|
-
}
|
|
347
|
-
if (equippedAmount($item `Crown of Thrones`) > 0) {
|
|
348
|
-
rider.set($item `Crown of Thrones`, myEnthronedFamiliar());
|
|
349
|
-
}
|
|
350
|
-
if (equippedAmount($item `Buddy Bjorn`) > 0) {
|
|
351
|
-
rider.set($item `Buddy Bjorn`, myBjornedFamiliar());
|
|
352
|
-
}
|
|
353
|
-
if (options.preventSlot && options.preventSlot.length > 0) {
|
|
354
|
-
for (const slot of options.preventSlot) {
|
|
355
|
-
equipment.delete(slot);
|
|
356
|
-
}
|
|
357
|
-
if (options.preventSlot.includes($slot `buddy-bjorn`)) {
|
|
358
|
-
rider.delete($item `Buddy Bjorn`);
|
|
359
|
-
}
|
|
360
|
-
if (options.preventSlot.includes($slot `crown-of-thrones`)) {
|
|
361
|
-
rider.delete($item `Crown of Thrones`);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
if (options.onlySlot && options.onlySlot.length > 0) {
|
|
365
|
-
for (const slot of Slot.all()) {
|
|
366
|
-
if (!options.onlySlot.includes(slot)) {
|
|
367
|
-
equipment.delete(slot);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
if (!options.onlySlot.includes($slot `buddy-bjorn`)) {
|
|
371
|
-
rider.delete($item `Buddy Bjorn`);
|
|
372
|
-
}
|
|
373
|
-
if (!options.onlySlot.includes($slot `crown-of-thrones`)) {
|
|
374
|
-
rider.delete($item `Crown of Thrones`);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
const entry = new CacheEntry(equipment, rider, myFamiliar(), canEquipItemCount(), { ...getCurrentModes(), ...options.modes });
|
|
378
|
-
cachedObjectives[cacheKey] = entry;
|
|
379
|
-
if (options.useOutfitCaching) {
|
|
380
|
-
const outfitName = outfitCache.insert(entry);
|
|
381
|
-
logger.info(`Saving equipment to outfit ${outfitName}.`);
|
|
382
|
-
saveOutfit(outfitName);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Run the maximizer, but only if the objective and certain pieces of game state haven't changed since it was last run.
|
|
387
|
-
*
|
|
388
|
-
* @param objectives Objectives to maximize for.
|
|
389
|
-
* @param options Options for this run of the maximizer.
|
|
390
|
-
* @param options.updateOnFamiliarChange Re-run the maximizer if familiar has changed. Default true.
|
|
391
|
-
* @param options.updateOnCanEquipChanged Re-run the maximizer if stats have changed what can be equipped. Default true.
|
|
392
|
-
* @param options.forceEquip Equipment to force-equip ("equip X").
|
|
393
|
-
* @param options.preventEquip Equipment to prevent equipping ("-equip X").
|
|
394
|
-
* @param options.bonusEquip Equipment to apply a bonus to ("200 bonus X").
|
|
395
|
-
* @returns Whether the maximize call succeeded.
|
|
396
|
-
*/
|
|
397
|
-
export function maximizeCached(objectives, options = {}) {
|
|
398
|
-
const fullOptions = mergeMaximizeOptions(defaultMaximizeOptions, options);
|
|
399
|
-
const { forceEquip, preventEquip, bonusEquip, onlySlot, preventSlot, forceUpdate, } = fullOptions;
|
|
400
|
-
// Sort each group in objective to ensure consistent ordering in string
|
|
401
|
-
const objective = [
|
|
402
|
-
...new Set([
|
|
403
|
-
...objectives.sort(),
|
|
404
|
-
...forceEquip.map((item) => `"equip ${toMaximizerName(item)}"`).sort(),
|
|
405
|
-
...preventEquip.map((item) => `-"equip ${toMaximizerName(item)}"`).sort(),
|
|
406
|
-
...onlySlot.map((slot) => `${slot}`).sort(),
|
|
407
|
-
...preventSlot.map((slot) => `-${slot}`).sort(),
|
|
408
|
-
...Array.from(bonusEquip.entries())
|
|
409
|
-
.filter(([, bonus]) => bonus !== 0)
|
|
410
|
-
.map(([item, bonus]) => `${Math.round(bonus * 100) / 100} "bonus ${toMaximizerName(item)}"`)
|
|
411
|
-
.sort(),
|
|
412
|
-
]),
|
|
413
|
-
].join(", ");
|
|
414
|
-
// Items equipped in slots not touched by the maximizer must be in the cache key
|
|
415
|
-
const untouchedSlots = cachedSlots.filter((slot) => preventSlot.includes(slot) ||
|
|
416
|
-
(onlySlot.length > 0 && !onlySlot.includes(slot)));
|
|
417
|
-
const cacheKey = [
|
|
418
|
-
objective,
|
|
419
|
-
...untouchedSlots
|
|
420
|
-
.map((slot) => `${slot}:${equippedItem(slot)}`)
|
|
421
|
-
.sort(),
|
|
422
|
-
have($effect `Offhand Remarkable`),
|
|
423
|
-
].join("; ");
|
|
424
|
-
const cacheEntry = checkCache(cacheKey, fullOptions);
|
|
425
|
-
if (cacheEntry && !forceUpdate) {
|
|
426
|
-
if (verifyCached(cacheEntry, false))
|
|
427
|
-
return true;
|
|
428
|
-
logger.info("Equipment found in maximize cache, equipping...");
|
|
429
|
-
applyCached(cacheEntry, fullOptions);
|
|
430
|
-
if (verifyCached(cacheEntry)) {
|
|
431
|
-
logger.info(`Equipped cached ${cacheKey}`);
|
|
432
|
-
return true;
|
|
433
|
-
}
|
|
434
|
-
logger.warning("Maximize cache application failed, maximizing...");
|
|
435
|
-
}
|
|
436
|
-
const result = maximize(objective, false);
|
|
437
|
-
saveCached(cacheKey, fullOptions);
|
|
438
|
-
return result;
|
|
439
|
-
}
|
|
440
|
-
export class Requirement {
|
|
441
|
-
#maximizeParameters;
|
|
442
|
-
#maximizeOptions;
|
|
443
|
-
/**
|
|
444
|
-
* A convenient way of combining maximization parameters and options
|
|
445
|
-
*
|
|
446
|
-
* @param maximizeParameters Parameters you're attempting to maximize
|
|
447
|
-
* @param maximizeOptions Object potentially containing forceEquips, bonusEquips, preventEquips, and preventSlots
|
|
448
|
-
*/
|
|
449
|
-
constructor(maximizeParameters, maximizeOptions) {
|
|
450
|
-
this.#maximizeParameters = maximizeParameters;
|
|
451
|
-
this.#maximizeOptions = maximizeOptions;
|
|
452
|
-
}
|
|
453
|
-
get maximizeParameters() {
|
|
454
|
-
return this.#maximizeParameters;
|
|
455
|
-
}
|
|
456
|
-
get maximizeOptions() {
|
|
457
|
-
return this.#maximizeOptions;
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Merges two requirements, concanating relevant arrays. Typically used in static form.
|
|
461
|
-
*
|
|
462
|
-
* @param other Requirement to merge with.
|
|
463
|
-
*/
|
|
464
|
-
merge(other) {
|
|
465
|
-
const optionsA = this.maximizeOptions;
|
|
466
|
-
const optionsB = other.maximizeOptions;
|
|
467
|
-
return new Requirement([...this.maximizeParameters, ...other.maximizeParameters], {
|
|
468
|
-
updateOnFamiliarChange: optionsA.updateOnFamiliarChange ||
|
|
469
|
-
other.maximizeOptions.updateOnFamiliarChange,
|
|
470
|
-
updateOnCanEquipChanged: optionsA.updateOnCanEquipChanged ||
|
|
471
|
-
other.maximizeOptions.updateOnCanEquipChanged,
|
|
472
|
-
forceEquip: [
|
|
473
|
-
...(optionsA.forceEquip ?? []),
|
|
474
|
-
...(other.maximizeOptions.forceEquip ?? []),
|
|
475
|
-
].filter((x) => !other.maximizeOptions.preventEquip?.includes(x)),
|
|
476
|
-
preventEquip: [
|
|
477
|
-
...(optionsA.preventEquip ?? []),
|
|
478
|
-
...(other.maximizeOptions.preventEquip ?? []),
|
|
479
|
-
].filter((x) => !other.maximizeOptions.forceEquip?.includes(x)),
|
|
480
|
-
bonusEquip: new Map([
|
|
481
|
-
...(optionsA.bonusEquip?.entries() ?? []),
|
|
482
|
-
...(optionsB.bonusEquip?.entries() ?? []),
|
|
483
|
-
]),
|
|
484
|
-
onlySlot: [...(optionsA.onlySlot ?? []), ...(optionsB.onlySlot ?? [])],
|
|
485
|
-
preventSlot: [
|
|
486
|
-
...(optionsA.preventSlot ?? []),
|
|
487
|
-
...(optionsB.preventSlot ?? []),
|
|
488
|
-
],
|
|
489
|
-
forceUpdate: optionsA.forceUpdate || optionsB.forceUpdate,
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
/**
|
|
493
|
-
* Merges a set of requirements together, starting with an empty requirement.
|
|
494
|
-
*
|
|
495
|
-
* @param allRequirements Requirements to merge
|
|
496
|
-
* @returns Merged requirements
|
|
497
|
-
*/
|
|
498
|
-
static merge(allRequirements) {
|
|
499
|
-
return allRequirements.reduce((x, y) => x.merge(y), new Requirement([], {}));
|
|
500
|
-
}
|
|
501
|
-
/**
|
|
502
|
-
* Runs maximizeCached, using the maximizeParameters and maximizeOptions contained by this requirement.
|
|
503
|
-
*
|
|
504
|
-
* @returns Whether the maximize call succeeded.
|
|
505
|
-
*/
|
|
506
|
-
maximize() {
|
|
507
|
-
return maximizeCached(this.maximizeParameters, this.maximizeOptions);
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Merges requirements, and then runs maximizeCached on the combined requirement.
|
|
511
|
-
*
|
|
512
|
-
* @param requirements Requirements to maximize on
|
|
513
|
-
*/
|
|
514
|
-
static maximize(...requirements) {
|
|
515
|
-
Requirement.merge(requirements).maximize();
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
/**
|
|
519
|
-
* Clear all outfits cached by the maximizer.
|
|
520
|
-
*/
|
|
521
|
-
export function clearMaximizerCache() {
|
|
522
|
-
outfitCache.clear();
|
|
523
|
-
for (const member in cachedObjectives)
|
|
524
|
-
delete cachedObjectives[member];
|
|
525
|
-
}
|
package/dist/modifier.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Class, Effect, Familiar, Item, Monster, Skill, Stat } from "kolmafia";
|
|
2
|
-
import { BooleanModifier, ClassModifier, EffectModifier, MonsterModifier, NumericModifier, SkillModifier, StatModifier, StringModifier } from "./modifierTypes";
|
|
3
|
-
export declare function get(name: BooleanModifier, subject?: string | Item | Effect): boolean;
|
|
4
|
-
export declare function get(name: ClassModifier, subject: string | Item): Class;
|
|
5
|
-
export declare function get(name: EffectModifier, subject: string | Item): Effect;
|
|
6
|
-
export declare function get(name: MonsterModifier, subject: Effect): Monster;
|
|
7
|
-
export declare function get(name: NumericModifier, subject?: string | Item | Effect | Skill | Familiar): number;
|
|
8
|
-
export declare function get(name: SkillModifier, subject: string | Item): Skill;
|
|
9
|
-
export declare function get(name: StringModifier, subject?: string | Effect | Item): string;
|
|
10
|
-
export declare function get(name: StatModifier, subject: Effect): Stat;
|
|
11
|
-
export declare type ModifierValue<T> = T extends BooleanModifier ? boolean : T extends ClassModifier ? Class : T extends EffectModifier ? Effect : T extends MonsterModifier ? Monster : T extends NumericModifier ? number : T extends SkillModifier ? Skill : T extends StatModifier ? Stat : T extends StringModifier ? string : string;
|
|
12
|
-
export declare type Modifiers = Partial<{
|
|
13
|
-
[T in BooleanModifier | ClassModifier | EffectModifier | MonsterModifier | NumericModifier | SkillModifier | StatModifier | StringModifier]: ModifierValue<T>;
|
|
14
|
-
}>;
|
|
15
|
-
/**
|
|
16
|
-
* Merge arbitrarily many Modifiers objects into one, summing all numeric modifiers, and ||ing all boolean modifiers.
|
|
17
|
-
*
|
|
18
|
-
* @param modifierss Modifiers objects to be merged together.
|
|
19
|
-
* @returns A single Modifiers object obtained by merging.
|
|
20
|
-
*/
|
|
21
|
-
export declare function mergeModifiers(...modifierss: Modifiers[]): Modifiers;
|
|
22
|
-
/**
|
|
23
|
-
* Prints the modtrace to the log.
|
|
24
|
-
* Example: printModtrace("Meat Drop") or printModtrace(["Item Drop", "Booze Drop"])
|
|
25
|
-
*
|
|
26
|
-
* @param inputModifiers A string (or string[]) containing the modtrace lookup term(s).
|
|
27
|
-
* @param baseModifier A string where all the info about modifiers in the string[] array can be grabbed with this one lookup term. (Automatically generated in most cases)
|
|
28
|
-
* @param componentColor The print color for the sum returned for each input modifier
|
|
29
|
-
* @param totalColor The print color for the total sum over every input modifier
|
|
30
|
-
* @returns void
|
|
31
|
-
*/
|
|
32
|
-
export declare function printModtrace(inputModifiers: string | string[], // the user's list of modifiers to look up
|
|
33
|
-
baseModifier?: string, componentColor?: string, totalColor?: string): void;
|
|
34
|
-
/**
|
|
35
|
-
* Take the sum of a modifier over an array of Skills, Effects, and Items
|
|
36
|
-
*
|
|
37
|
-
* @param modifier A NumericModifier that we want to find the total value of
|
|
38
|
-
* @param subjects A rested array of Skills, Effects, and Items that we want to find the total value of
|
|
39
|
-
* @returns The sum of the appropriate modifier for all of the subjects
|
|
40
|
-
*/
|
|
41
|
-
export declare function getTotalModifier(modifier: NumericModifier, ...subjects: (Skill | Effect | Item)[]): number;
|