libram 0.7.1 → 0.7.2

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/ascend.d.ts CHANGED
@@ -6,6 +6,7 @@ export declare enum Lifestyle {
6
6
  normal = 2,
7
7
  hardcore = 3
8
8
  }
9
+ export declare function permedSkills(): Map<Skill, Lifestyle>;
9
10
  export declare class AscendError extends Error {
10
11
  cause?: Skill | Item | Class | Path | string;
11
12
  constructor(cause?: Skill | Item | Class | Path | string);
@@ -29,8 +30,12 @@ declare type MoonSign = number | "mongoose" | "wallaby" | "vole" | "platypus" |
29
30
  * @param moon Your moon sign as a string, or the zone you're looking for as a string
30
31
  * @param consumable From the astral deli. Pick the container item, not the product.
31
32
  * @param pet From the astral pet store.
33
+ * @param permSkills A Map<Skill, Lifestyle> of skills you'd like to perm, ordered by priority.
32
34
  */
33
- export declare function ascend(path: Path, playerClass: Class, lifestyle: Lifestyle, moon: MoonSign, consumable?: Item | undefined, pet?: Item | undefined, permSkills?: Map<Skill, Lifestyle> | undefined): void;
35
+ export declare function ascend(path: Path, playerClass: Class, lifestyle: Lifestyle, moon: MoonSign, consumable?: Item | undefined, pet?: Item | undefined, permOptions?: {
36
+ permSkills: Map<Skill, Lifestyle>;
37
+ neverAbort: boolean;
38
+ }): void;
34
39
  /**
35
40
  * Sets up various iotms you may want to use in the coming ascension
36
41
  * @param ascensionItems.workshed Workshed to switch to.
package/dist/ascend.js CHANGED
@@ -1,4 +1,5 @@
1
- import { Skill, Class, containsText, eudoraItem, getCampground, getWorkshed, Item, Path, toInt, use, visitUrl, xpath, haveSkill, } from "kolmafia";
1
+ import { Skill, Class, containsText, eudoraItem, getCampground, getWorkshed, Item, Path, toInt, use, visitUrl, xpath, haveSkill, getPermedSkills, toSkill, } from "kolmafia";
2
+ import { get } from "./property";
2
3
  import { ChateauMantegna } from "./resources";
3
4
  import { $item, $items, $stat } from "./template-string";
4
5
  import { createStringUnionTypeGuardFunction } from "./utils";
@@ -9,6 +10,12 @@ export var Lifestyle;
9
10
  Lifestyle[Lifestyle["normal"] = 2] = "normal";
10
11
  Lifestyle[Lifestyle["hardcore"] = 3] = "hardcore";
11
12
  })(Lifestyle || (Lifestyle = {}));
13
+ export function permedSkills() {
14
+ return new Map(Array.from(Object.entries(getPermedSkills())).map(([skillName, isHardcore]) => [
15
+ toSkill(skillName),
16
+ isHardcore ? Lifestyle.hardcore : Lifestyle.softcore,
17
+ ]));
18
+ }
12
19
  export class AscendError extends Error {
13
20
  cause;
14
21
  constructor(cause) {
@@ -18,7 +25,7 @@ export class AscendError extends Error {
18
25
  else if (cause instanceof Skill) {
19
26
  const reason = cause.permable
20
27
  ? haveSkill(cause)
21
- ? "invalid for mysterious reasons"
28
+ ? "too karmaically expensive"
22
29
  : "not a skill you currently know"
23
30
  : "unpermable";
24
31
  super(`Skill ${cause} is ${reason}!`);
@@ -160,8 +167,9 @@ function toMoonId(moon, playerClass) {
160
167
  * @param moon Your moon sign as a string, or the zone you're looking for as a string
161
168
  * @param consumable From the astral deli. Pick the container item, not the product.
162
169
  * @param pet From the astral pet store.
170
+ * @param permSkills A Map<Skill, Lifestyle> of skills you'd like to perm, ordered by priority.
163
171
  */
164
- export function ascend(path, playerClass, lifestyle, moon, consumable = $item `astral six-pack`, pet = undefined, permSkills = undefined) {
172
+ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `astral six-pack`, pet = undefined, permOptions) {
165
173
  if (playerClass.path !== (path.avatar ? path : Path.none)) {
166
174
  throw new AscendError(playerClass);
167
175
  }
@@ -178,8 +186,8 @@ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `a
178
186
  !$items `astral bludgeon, astral shield, astral chapeau, astral bracer, astral longbow, astral shorts, astral mace, astral trousers, astral ring, astral statuette, astral pistol, astral mask, astral pet sweater, astral shirt, astral belt`.includes(pet)) {
179
187
  throw new AscendError(pet);
180
188
  }
181
- const illegalSkill = permSkills
182
- ? Array.from(permSkills.keys()).find((skill) => !skill.permable || !haveSkill(skill))
189
+ const illegalSkill = permOptions
190
+ ? Array.from(permOptions.permSkills.keys()).find((skill) => !skill.permable || !haveSkill(skill))
183
191
  : undefined;
184
192
  if (illegalSkill) {
185
193
  throw new AscendError(illegalSkill);
@@ -196,10 +204,20 @@ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `a
196
204
  }
197
205
  if (pet)
198
206
  visitUrl(`afterlife.php?action=buyarmory&whichitem=${toInt(pet)}`);
199
- if (permSkills) {
200
- for (const [skill, permLevel] of permSkills.entries()) {
201
- if (permLevel !== Lifestyle.casual) {
202
- const permText = permLevel === Lifestyle.hardcore ? "hcperm" : "scperm";
207
+ if (permOptions) {
208
+ const currentPerms = permedSkills();
209
+ let karma = get("bankedKarma");
210
+ for (const [skill, prospectivePermLevel,] of permOptions.permSkills.entries()) {
211
+ const currentPermLevel = currentPerms.get(skill) ?? Lifestyle.casual;
212
+ if (prospectivePermLevel > currentPermLevel) {
213
+ const expectedKarma = 100 * (prospectivePermLevel - currentPermLevel);
214
+ if (karma < expectedKarma) {
215
+ if (!permOptions.neverAbort)
216
+ throw new AscendError(skill);
217
+ continue;
218
+ }
219
+ karma -= expectedKarma;
220
+ const permText = prospectivePermLevel === Lifestyle.hardcore ? "hcperm" : "scperm";
203
221
  visitUrl(`afterlife.php?action=${permText}&whichskill=${toInt(skill)}`);
204
222
  }
205
223
  }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Visits the Cooling Tank on level 8 of the Fallout shelter to gain 300 rads
3
+ */
4
+ export declare function coolingTank(): void;
5
+ /**
6
+ * Visits the Spa Simulation Chamber on level 4 of the Fallout shelter for 100 turns of "100% all stats"
7
+ */
8
+ export declare function spa(): void;
9
+ /**
10
+ * Visits the Chronodynamics Laboratory on level 5 of the Fallout shelter to permanently increase radiation level by 3
11
+ */
12
+ export declare function chronoLab(): void;
@@ -0,0 +1,19 @@
1
+ import { visitUrl } from "kolmafia";
2
+ /**
3
+ * Visits the Cooling Tank on level 8 of the Fallout shelter to gain 300 rads
4
+ */
5
+ export function coolingTank() {
6
+ visitUrl("place.php?whichplace=falloutshelter&action=vault8");
7
+ }
8
+ /**
9
+ * Visits the Spa Simulation Chamber on level 4 of the Fallout shelter for 100 turns of "100% all stats"
10
+ */
11
+ export function spa() {
12
+ visitUrl("place.php?whichplace=falloutshelter&action=vault3");
13
+ }
14
+ /**
15
+ * Visits the Chronodynamics Laboratory on level 5 of the Fallout shelter to permanently increase radiation level by 3
16
+ */
17
+ export function chronoLab() {
18
+ visitUrl("place.php?whichplace=falloutshelter&action=vault5");
19
+ }
@@ -1,2 +1,3 @@
1
1
  import CommunityService from "./2015/CommunityService";
2
- export { CommunityService };
2
+ import * as NuclearAutumn from "./2016/NuclearAutumn";
3
+ export { CommunityService, NuclearAutumn };
@@ -1,2 +1,3 @@
1
1
  import CommunityService from "./2015/CommunityService";
2
- export { CommunityService };
2
+ import * as NuclearAutumn from "./2016/NuclearAutumn";
3
+ export { CommunityService, NuclearAutumn };
@@ -15,7 +15,7 @@ function expectedAdventures(item, modifiers) {
15
15
  if (item.adventures === "")
16
16
  return 0;
17
17
  const [min, recordedMax] = item.adventures
18
- .split(/[-–—]/)
18
+ .split(/[-]/)
19
19
  .map((s) => parseInt(s));
20
20
  const max = recordedMax ?? min;
21
21
  const interpolated = [...new Array(max - min + 1).keys()].map((n) => n + min);
@@ -23,6 +23,7 @@ function expectedAdventures(item, modifiers) {
23
23
  (itemType(item) === "booze" && item.notes?.includes("BEER"))
24
24
  ? 1.5
25
25
  : 1.3;
26
+ const seasoningAdventures = max - min <= 1 ? 1 : 0.5;
26
27
  const garish = modifiers.garish && item.notes?.includes("LASAGNA") && !isMonday();
27
28
  const refinedPalate = modifiers.refinedPalate && item.notes?.includes("WINE");
28
29
  const pinkyRing = modifiers.pinkyRing && item.notes?.includes("WINE");
@@ -46,7 +47,7 @@ function expectedAdventures(item, modifiers) {
46
47
  if (itemType(item) === "food" && modifiers.mayoflex)
47
48
  adventures++;
48
49
  if (itemType(item) === "food" && modifiers.seasoning)
49
- adventures += 0.5;
50
+ adventures += seasoningAdventures;
50
51
  return adventures;
51
52
  }) / interpolated.length);
52
53
  }
@@ -223,11 +224,6 @@ class DietPlanner {
223
224
  */
224
225
  consumptionHelpersAndValue(menuItem, overrideModifiers) {
225
226
  const helpers = [];
226
- if (this.seasoning &&
227
- itemType(menuItem.item) === "food" &&
228
- this.mpa * 0.5 > mallPrice($item `Special Seasoning`)) {
229
- helpers.push(this.seasoning);
230
- }
231
227
  if (itemType(menuItem.item) === "food" && this.mayoLookup.size) {
232
228
  const mayo = menuItem.mayo
233
229
  ? this.mayoLookup.get(menuItem.mayo)
@@ -248,6 +244,20 @@ class DietPlanner {
248
244
  tuxedoShirt: have($item `tuxedo shirt`) && canEquip($item `tuxedo shirt`),
249
245
  ...overrideModifiers,
250
246
  };
247
+ if (this.seasoning &&
248
+ itemType(menuItem.item) === "food" &&
249
+ this.mpa *
250
+ (expectedAdventures(menuItem.item, {
251
+ ...defaultModifiers,
252
+ seasoning: true,
253
+ }) -
254
+ expectedAdventures(menuItem.item, {
255
+ ...defaultModifiers,
256
+ seasoning: false,
257
+ })) >
258
+ mallPrice($item `Special Seasoning`)) {
259
+ helpers.push(this.seasoning);
260
+ }
251
261
  const forkMug = itemType(menuItem.item) === "food"
252
262
  ? this.fork
253
263
  : itemType(menuItem.item) === "booze"
@@ -340,7 +350,7 @@ class DietPlanner {
340
350
  const [helpersAndItem, value] = this.consumptionHelpersAndValue(trialItem, {});
341
351
  return valueWithout > valueWith + value
342
352
  ? [valueWithout, planWithout]
343
- : [valueWith, [...planWith, [helpersAndItem, 1]]];
353
+ : [valueWith + value, [...planWith, [helpersAndItem, 1]]];
344
354
  }
345
355
  }
346
356
  /**
package/dist/lib.js CHANGED
@@ -327,6 +327,9 @@ export function getBanishedMonsters() {
327
327
  if (banisher.toLowerCase() === "saber force") {
328
328
  result.set($skill `Use the Force`, Monster.get(foe));
329
329
  }
330
+ else if (banisher.toLowerCase() === "nanorhino") {
331
+ result.set($skill `Unleash Nanites`, Monster.get(foe));
332
+ }
330
333
  else if ([
331
334
  Item.none,
332
335
  Item.get(`training scroll: Snokebomb`),
package/dist/maximize.js CHANGED
@@ -1,4 +1,4 @@
1
- import { availableAmount, bjornifyFamiliar, canEquip, cliExecute, enthroneFamiliar, equip, equippedAmount, equippedItem, isWearingOutfit, Item, maximize, myBasestat, myBjornedFamiliar, myEnthronedFamiliar, myFamiliar, outfit, Slot, } from "kolmafia";
1
+ import { availableAmount, bjornifyFamiliar, canEquip, cliExecute, enthroneFamiliar, equip, equippedAmount, equippedItem, getProperty, haveEquipped, isWearingOutfit, Item, maximize, myBasestat, myBjornedFamiliar, myEnthronedFamiliar, myFamiliar, outfit, Slot, } from "kolmafia";
2
2
  import logger from "./logger";
3
3
  import { $familiar, $item, $slot, $slots, $stats } from "./template-string";
4
4
  import { setEqual } from "./utils";
@@ -54,6 +54,50 @@ const defaultMaximizeOptions = {
54
54
  export function setDefaultMaximizeOptions(options) {
55
55
  Object.assign(defaultMaximizeOptions, options);
56
56
  }
57
+ const modeableCommands = [
58
+ "backupcamera",
59
+ "umbrella",
60
+ "snowsuit",
61
+ "edpiece",
62
+ "retrocape",
63
+ "parka",
64
+ ];
65
+ const modeableItems = {
66
+ backupcamera: $item `backup camera`,
67
+ umbrella: $item `unbreakable umbrella`,
68
+ snowsuit: $item `Snow Suit`,
69
+ edpiece: $item `The Crown of Ed the Undying`,
70
+ retrocape: $item `unwrapped knock-off retro superhero cape`,
71
+ parka: $item `Jurassic Parka`,
72
+ };
73
+ const modeableState = {
74
+ backupcamera: () => getProperty("backupCameraMode"),
75
+ umbrella: () => getProperty("umbrellaState"),
76
+ snowsuit: () => getProperty("snowsuit"),
77
+ edpiece: () => getProperty("edPiece"),
78
+ retrocape: () => getProperty("retroCapeSuperhero") +
79
+ " " +
80
+ getProperty("retroCapeWashingInstructions"),
81
+ parka: () => getProperty("parkaMode"),
82
+ };
83
+ function getCurrentModes() {
84
+ const modes = {};
85
+ for (const key of modeableCommands) {
86
+ if (haveEquipped(modeableItems[key])) {
87
+ modes[key] = modeableState[key]();
88
+ }
89
+ }
90
+ return modes;
91
+ }
92
+ function applyModes(modes) {
93
+ for (const command of modeableCommands) {
94
+ if (haveEquipped(modeableItems[command])) {
95
+ if (modeableState[command]() !== modes[command]) {
96
+ cliExecute(command + " " + modes[command]);
97
+ }
98
+ }
99
+ }
100
+ }
57
101
  // Subset of slots that are valid for caching.
58
102
  const cachedSlots = $slots `hat, weapon, off-hand, back, shirt, pants, acc1, acc2, acc3, familiar`;
59
103
  class CacheEntry {
@@ -61,11 +105,13 @@ class CacheEntry {
61
105
  rider;
62
106
  familiar;
63
107
  canEquipItemCount;
64
- constructor(equipment, rider, familiar, canEquipItemCount) {
108
+ modes;
109
+ constructor(equipment, rider, familiar, canEquipItemCount, modes) {
65
110
  this.equipment = equipment;
66
111
  this.rider = rider;
67
112
  this.familiar = familiar;
68
113
  this.canEquipItemCount = canEquipItemCount;
114
+ this.modes = modes;
69
115
  }
70
116
  }
71
117
  class OutfitLRUCache {
@@ -201,6 +247,7 @@ function applyCached(entry, options) {
201
247
  entry.rider.get($item `Buddy Bjorn`)) {
202
248
  bjornifyFamiliar(entry.rider.get($item `Buddy Bjorn`) || $familiar.none);
203
249
  }
250
+ applyModes(entry.modes);
204
251
  }
205
252
  const slotStructure = [
206
253
  $slots `hat`,
@@ -288,7 +335,7 @@ function saveCached(cacheKey, options) {
288
335
  rider.delete($item `Crown of Thrones`);
289
336
  }
290
337
  }
291
- const entry = new CacheEntry(equipment, rider, myFamiliar(), canEquipItemCount());
338
+ const entry = new CacheEntry(equipment, rider, myFamiliar(), canEquipItemCount(), getCurrentModes());
292
339
  cachedObjectives[cacheKey] = entry;
293
340
  if (options.useOutfitCaching) {
294
341
  const outfitName = outfitCache.insert(entry);