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.
Files changed (195) hide show
  1. package/package.json +9 -8
  2. package/dist/Clan.d.ts +0 -128
  3. package/dist/Clan.js +0 -300
  4. package/dist/Copier.d.ts +0 -9
  5. package/dist/Copier.js +0 -15
  6. package/dist/Dungeon.d.ts +0 -45
  7. package/dist/Dungeon.js +0 -115
  8. package/dist/Kmail.d.ts +0 -104
  9. package/dist/Kmail.js +0 -182
  10. package/dist/actions/ActionSource.d.ts +0 -131
  11. package/dist/actions/ActionSource.js +0 -177
  12. package/dist/actions/Banish.d.ts +0 -16
  13. package/dist/actions/Banish.js +0 -121
  14. package/dist/actions/FreeKill.d.ts +0 -16
  15. package/dist/actions/FreeKill.js +0 -94
  16. package/dist/actions/FreeRun.d.ts +0 -16
  17. package/dist/actions/FreeRun.js +0 -77
  18. package/dist/actions/index.d.ts +0 -4
  19. package/dist/actions/index.js +0 -4
  20. package/dist/ascend.d.ts +0 -83
  21. package/dist/ascend.js +0 -268
  22. package/dist/challengePaths/2014/HeavyRains.d.ts +0 -22
  23. package/dist/challengePaths/2014/HeavyRains.js +0 -75
  24. package/dist/challengePaths/2015/CommunityService.d.ts +0 -125
  25. package/dist/challengePaths/2015/CommunityService.js +0 -334
  26. package/dist/challengePaths/2016/NuclearAutumn.d.ts +0 -13
  27. package/dist/challengePaths/2016/NuclearAutumn.js +0 -21
  28. package/dist/challengePaths/index.d.ts +0 -4
  29. package/dist/challengePaths/index.js +0 -4
  30. package/dist/combat.d.ts +0 -414
  31. package/dist/combat.js +0 -711
  32. package/dist/console.d.ts +0 -12
  33. package/dist/console.js +0 -14
  34. package/dist/counter.d.ts +0 -22
  35. package/dist/counter.js +0 -37
  36. package/dist/diet/index.d.ts +0 -80
  37. package/dist/diet/index.js +0 -662
  38. package/dist/diet/knapsack.d.ts +0 -8
  39. package/dist/diet/knapsack.js +0 -128
  40. package/dist/index.d.ts +0 -29
  41. package/dist/index.js +0 -26
  42. package/dist/lib.d.ts +0 -497
  43. package/dist/lib.js +0 -958
  44. package/dist/logger.d.ts +0 -35
  45. package/dist/logger.js +0 -62
  46. package/dist/maximize.d.ts +0 -121
  47. package/dist/maximize.js +0 -525
  48. package/dist/modifier.d.ts +0 -41
  49. package/dist/modifier.js +0 -160
  50. package/dist/modifierTypes.d.ts +0 -16
  51. package/dist/modifierTypes.js +0 -9
  52. package/dist/mood.d.ts +0 -105
  53. package/dist/mood.js +0 -349
  54. package/dist/moonSign.d.ts +0 -13
  55. package/dist/moonSign.js +0 -25
  56. package/dist/overlappingNames.d.ts +0 -3
  57. package/dist/overlappingNames.js +0 -42
  58. package/dist/property.d.ts +0 -222
  59. package/dist/property.js +0 -385
  60. package/dist/propertyTypes.d.ts +0 -19
  61. package/dist/propertyTypes.js +0 -10
  62. package/dist/propertyTyping.d.ts +0 -65
  63. package/dist/propertyTyping.js +0 -91
  64. package/dist/resources/2007/CandyHearts.d.ts +0 -9
  65. package/dist/resources/2007/CandyHearts.js +0 -24
  66. package/dist/resources/2008/DivineFavors.d.ts +0 -9
  67. package/dist/resources/2008/DivineFavors.js +0 -27
  68. package/dist/resources/2008/Stickers.d.ts +0 -49
  69. package/dist/resources/2008/Stickers.js +0 -84
  70. package/dist/resources/2009/Bandersnatch.d.ts +0 -56
  71. package/dist/resources/2009/Bandersnatch.js +0 -93
  72. package/dist/resources/2009/LoveSongs.d.ts +0 -9
  73. package/dist/resources/2009/LoveSongs.js +0 -24
  74. package/dist/resources/2009/SpookyPutty.d.ts +0 -31
  75. package/dist/resources/2009/SpookyPutty.js +0 -49
  76. package/dist/resources/2010/Brickos.d.ts +0 -9
  77. package/dist/resources/2010/Brickos.js +0 -21
  78. package/dist/resources/2010/CrownOfThrones.d.ts +0 -68
  79. package/dist/resources/2010/CrownOfThrones.js +0 -418
  80. package/dist/resources/2010/LookingGlass.d.ts +0 -29
  81. package/dist/resources/2010/LookingGlass.js +0 -89
  82. package/dist/resources/2011/Gygaxian.d.ts +0 -9
  83. package/dist/resources/2011/Gygaxian.js +0 -24
  84. package/dist/resources/2011/ObtuseAngel.d.ts +0 -33
  85. package/dist/resources/2011/ObtuseAngel.js +0 -51
  86. package/dist/resources/2011/StompingBoots.d.ts +0 -37
  87. package/dist/resources/2011/StompingBoots.js +0 -57
  88. package/dist/resources/2012/RainDoh.d.ts +0 -25
  89. package/dist/resources/2012/RainDoh.js +0 -37
  90. package/dist/resources/2012/ReagnimatedGnome.d.ts +0 -31
  91. package/dist/resources/2012/ReagnimatedGnome.js +0 -46
  92. package/dist/resources/2012/Resolutions.d.ts +0 -9
  93. package/dist/resources/2012/Resolutions.js +0 -28
  94. package/dist/resources/2013/Florist.d.ts +0 -81
  95. package/dist/resources/2013/Florist.js +0 -245
  96. package/dist/resources/2013/JungMan.d.ts +0 -33
  97. package/dist/resources/2013/JungMan.js +0 -69
  98. package/dist/resources/2013/PulledTaffy.d.ts +0 -9
  99. package/dist/resources/2013/PulledTaffy.js +0 -33
  100. package/dist/resources/2014/CrimboShrub.d.ts +0 -42
  101. package/dist/resources/2014/CrimboShrub.js +0 -89
  102. package/dist/resources/2014/DNALab.d.ts +0 -56
  103. package/dist/resources/2014/DNALab.js +0 -162
  104. package/dist/resources/2014/WinterGarden.d.ts +0 -23
  105. package/dist/resources/2014/WinterGarden.js +0 -35
  106. package/dist/resources/2015/BarrelShrine.d.ts +0 -8
  107. package/dist/resources/2015/BarrelShrine.js +0 -25
  108. package/dist/resources/2015/ChateauMantegna.d.ts +0 -52
  109. package/dist/resources/2015/ChateauMantegna.js +0 -99
  110. package/dist/resources/2015/DeckOfEveryCard.d.ts +0 -29
  111. package/dist/resources/2015/DeckOfEveryCard.js +0 -122
  112. package/dist/resources/2015/Dinseylandfill.d.ts +0 -89
  113. package/dist/resources/2015/Dinseylandfill.js +0 -205
  114. package/dist/resources/2015/MayoClinic.d.ts +0 -23
  115. package/dist/resources/2015/MayoClinic.js +0 -49
  116. package/dist/resources/2016/GingerBread.d.ts +0 -32
  117. package/dist/resources/2016/GingerBread.js +0 -73
  118. package/dist/resources/2016/SourceTerminal.d.ts +0 -181
  119. package/dist/resources/2016/SourceTerminal.js +0 -275
  120. package/dist/resources/2016/Witchess.d.ts +0 -17
  121. package/dist/resources/2016/Witchess.js +0 -47
  122. package/dist/resources/2017/AsdonMartin.d.ts +0 -59
  123. package/dist/resources/2017/AsdonMartin.js +0 -238
  124. package/dist/resources/2017/Horsery.d.ts +0 -19
  125. package/dist/resources/2017/Horsery.js +0 -42
  126. package/dist/resources/2017/MummingTrunk.d.ts +0 -8
  127. package/dist/resources/2017/MummingTrunk.js +0 -33
  128. package/dist/resources/2017/Pantogram.d.ts +0 -92
  129. package/dist/resources/2017/Pantogram.js +0 -174
  130. package/dist/resources/2017/Robortender.d.ts +0 -30
  131. package/dist/resources/2017/Robortender.js +0 -90
  132. package/dist/resources/2017/Spacegate.d.ts +0 -86
  133. package/dist/resources/2017/Spacegate.js +0 -178
  134. package/dist/resources/2017/TunnelOfLove.d.ts +0 -39
  135. package/dist/resources/2017/TunnelOfLove.js +0 -120
  136. package/dist/resources/2018/LatteLoversMembersMug.d.ts +0 -392
  137. package/dist/resources/2018/LatteLoversMembersMug.js +0 -303
  138. package/dist/resources/2018/SongBoom.d.ts +0 -33
  139. package/dist/resources/2018/SongBoom.js +0 -55
  140. package/dist/resources/2019/BeachComb.d.ts +0 -72
  141. package/dist/resources/2019/BeachComb.js +0 -118
  142. package/dist/resources/2019/CampAway.d.ts +0 -39
  143. package/dist/resources/2019/CampAway.js +0 -72
  144. package/dist/resources/2019/Snapper.d.ts +0 -33
  145. package/dist/resources/2019/Snapper.js +0 -73
  146. package/dist/resources/2020/Cartography.d.ts +0 -16
  147. package/dist/resources/2020/Cartography.js +0 -48
  148. package/dist/resources/2020/Guzzlr.d.ts +0 -160
  149. package/dist/resources/2020/Guzzlr.js +0 -275
  150. package/dist/resources/2020/RetroCape.d.ts +0 -51
  151. package/dist/resources/2020/RetroCape.js +0 -115
  152. package/dist/resources/2021/CrystalBall.d.ts +0 -14
  153. package/dist/resources/2021/CrystalBall.js +0 -39
  154. package/dist/resources/2021/DaylightShavings.d.ts +0 -40
  155. package/dist/resources/2021/DaylightShavings.js +0 -74
  156. package/dist/resources/2022/AutumnAton.d.ts +0 -78
  157. package/dist/resources/2022/AutumnAton.js +0 -182
  158. package/dist/resources/2022/CombatLoversLocket.d.ts +0 -44
  159. package/dist/resources/2022/CombatLoversLocket.js +0 -82
  160. package/dist/resources/2022/GreyGoose.d.ts +0 -59
  161. package/dist/resources/2022/GreyGoose.js +0 -90
  162. package/dist/resources/2022/JuneCleaver.d.ts +0 -47
  163. package/dist/resources/2022/JuneCleaver.js +0 -69
  164. package/dist/resources/2022/TrainSet.d.ts +0 -146
  165. package/dist/resources/2022/TrainSet.js +0 -228
  166. package/dist/resources/2023/AugustScepter.d.ts +0 -25
  167. package/dist/resources/2023/AugustScepter.js +0 -40
  168. package/dist/resources/2023/BurningLeaves.d.ts +0 -25
  169. package/dist/resources/2023/BurningLeaves.js +0 -74
  170. package/dist/resources/2023/CinchoDeMayo.d.ts +0 -25
  171. package/dist/resources/2023/CinchoDeMayo.js +0 -45
  172. package/dist/resources/2023/ClosedCircuitPayphone.d.ts +0 -80
  173. package/dist/resources/2023/ClosedCircuitPayphone.js +0 -129
  174. package/dist/resources/2023/CursedMonkeyPaw.d.ts +0 -46
  175. package/dist/resources/2023/CursedMonkeyPaw.js +0 -113
  176. package/dist/resources/2024/AprilingBandHelmet.d.ts +0 -50
  177. package/dist/resources/2024/AprilingBandHelmet.js +0 -103
  178. package/dist/resources/2024/ChestMimic.d.ts +0 -35
  179. package/dist/resources/2024/ChestMimic.js +0 -108
  180. package/dist/resources/LibramSummon.d.ts +0 -18
  181. package/dist/resources/LibramSummon.js +0 -74
  182. package/dist/resources/index.d.ts +0 -54
  183. package/dist/resources/index.js +0 -54
  184. package/dist/resources/putty-likes.d.ts +0 -21
  185. package/dist/resources/putty-likes.js +0 -33
  186. package/dist/session.d.ts +0 -169
  187. package/dist/session.js +0 -284
  188. package/dist/since.d.ts +0 -51
  189. package/dist/since.js +0 -108
  190. package/dist/template-string.d.ts +0 -324
  191. package/dist/template-string.js +0 -265
  192. package/dist/url.d.ts +0 -35
  193. package/dist/url.js +0 -67
  194. package/dist/utils.d.ts +0 -178
  195. 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
- }
@@ -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;