libram 0.8.13 → 0.8.15

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,10 @@ export declare enum Lifestyle {
6
6
  normal = 2,
7
7
  hardcore = 3
8
8
  }
9
+ export declare enum KolGender {
10
+ male = 1,
11
+ female = 2
12
+ }
9
13
  /**
10
14
  * Get a mapping of permed skills to the extent to which they're permed.
11
15
  *
@@ -40,21 +44,32 @@ export declare function signNameToId(moon: MoonSign): number;
40
44
  */
41
45
  export declare function signIdToName(id: number): MoonSign | "None";
42
46
  /**
43
- * Hops the gash, perming no skills
47
+ * Hops the gash, perming no skills by default
44
48
  *
45
- * @param path path of choice, as a Path object--these exist as properties of Paths
46
- * @param playerClass Your class of choice for this ascension
47
- * @param lifestyle 1 for casual, 2 for softcore, 3 for hardcore. Alternately, use the Lifestyle enum
48
- * @param moon Your moon sign as a string, or the zone you're looking for as a string
49
- * @param consumable From the astral deli. Pick the container item, not the product.
50
- * @param pet From the astral pet store.
51
- * @param permOptions Options for perming during a player's stay in Valhalla
52
- * @param permOptions.permSkills A Map<Skill, Lifestyle> of skills you'd like to perm, ordered by priority.
53
- * @param permOptions.neverAbort Whether the ascension shouold abort on failure
49
+ * @param options Configuration for the ascension
50
+ * @param options.path path of choice, as a Path object--these exist as properties of Paths
51
+ * @param options.playerClass Your class of choice for this ascension
52
+ * @param options.lifestyle 1 for casual, 2 for softcore, 3 for hardcore. Alternately, use the Lifestyle enum
53
+ * @param options.kolGender An entry from the KolGender enum: 1 for male, 2 for female (sorry that it's limited to those). Defaults to 2 or the corresponding value for defaultGenderOverride pref (which should be 'male' or 'female')
54
+ * @param options.moon Your moon sign as a string, or the zone you're looking for as a string
55
+ * @param options.consumable From the astral deli. Pick the container item, not the product. Defaults to astral six-pack, provide $item`none` for nothing.
56
+ * @param options.pet From the astral pet store.
57
+ * @param options.permOptions Options for perming during a player's stay in Valhalla
58
+ * @param options.permOptions.permSkills A Map<Skill, Lifestyle> of skills you'd like to perm, ordered by priority.
59
+ * @param options.permOptions.neverAbort Whether the ascension should abort on failure
54
60
  */
55
- export declare function ascend(path: Path, playerClass: Class, lifestyle: Lifestyle, moon: InputMoonSign, consumable?: Item | undefined, pet?: Item | undefined, permOptions?: {
56
- permSkills: Map<Skill, Lifestyle>;
57
- neverAbort: boolean;
61
+ export declare function ascend(options: {
62
+ path: Path;
63
+ playerClass: Class;
64
+ lifestyle: Lifestyle;
65
+ kolGender?: KolGender;
66
+ moon: InputMoonSign;
67
+ consumable?: Item;
68
+ pet?: Item;
69
+ permOptions?: {
70
+ permSkills: Map<Skill, Lifestyle>;
71
+ neverAbort: boolean;
72
+ };
58
73
  }): void;
59
74
  /**
60
75
  * Sets up various iotms you may want to use in the coming ascension
package/dist/ascend.js CHANGED
@@ -10,6 +10,11 @@ export var Lifestyle;
10
10
  Lifestyle[Lifestyle["normal"] = 2] = "normal";
11
11
  Lifestyle[Lifestyle["hardcore"] = 3] = "hardcore";
12
12
  })(Lifestyle || (Lifestyle = {}));
13
+ export var KolGender;
14
+ (function (KolGender) {
15
+ KolGender[KolGender["male"] = 1] = "male";
16
+ KolGender[KolGender["female"] = 2] = "female";
17
+ })(KolGender || (KolGender = {}));
13
18
  /**
14
19
  * Get a mapping of permed skills to the extent to which they're permed.
15
20
  *
@@ -179,19 +184,29 @@ function isInValhalla() {
179
184
  return matches !== null;
180
185
  }
181
186
  /**
182
- * Hops the gash, perming no skills
187
+ * Hops the gash, perming no skills by default
183
188
  *
184
- * @param path path of choice, as a Path object--these exist as properties of Paths
185
- * @param playerClass Your class of choice for this ascension
186
- * @param lifestyle 1 for casual, 2 for softcore, 3 for hardcore. Alternately, use the Lifestyle enum
187
- * @param moon Your moon sign as a string, or the zone you're looking for as a string
188
- * @param consumable From the astral deli. Pick the container item, not the product.
189
- * @param pet From the astral pet store.
190
- * @param permOptions Options for perming during a player's stay in Valhalla
191
- * @param permOptions.permSkills A Map<Skill, Lifestyle> of skills you'd like to perm, ordered by priority.
192
- * @param permOptions.neverAbort Whether the ascension shouold abort on failure
189
+ * @param options Configuration for the ascension
190
+ * @param options.path path of choice, as a Path object--these exist as properties of Paths
191
+ * @param options.playerClass Your class of choice for this ascension
192
+ * @param options.lifestyle 1 for casual, 2 for softcore, 3 for hardcore. Alternately, use the Lifestyle enum
193
+ * @param options.kolGender An entry from the KolGender enum: 1 for male, 2 for female (sorry that it's limited to those). Defaults to 2 or the corresponding value for defaultGenderOverride pref (which should be 'male' or 'female')
194
+ * @param options.moon Your moon sign as a string, or the zone you're looking for as a string
195
+ * @param options.consumable From the astral deli. Pick the container item, not the product. Defaults to astral six-pack, provide $item`none` for nothing.
196
+ * @param options.pet From the astral pet store.
197
+ * @param options.permOptions Options for perming during a player's stay in Valhalla
198
+ * @param options.permOptions.permSkills A Map<Skill, Lifestyle> of skills you'd like to perm, ordered by priority.
199
+ * @param options.permOptions.neverAbort Whether the ascension should abort on failure
193
200
  */
194
- export function ascend(path, playerClass, lifestyle, moon, consumable = $item `astral six-pack`, pet = undefined, permOptions) {
201
+ export function ascend(options) {
202
+ const DEFAULT_OPTIONS = {
203
+ kolGender: get("defaultGenderOverride", "female") === "male"
204
+ ? KolGender.male
205
+ : KolGender.female,
206
+ consumable: $item `astral six-pack`,
207
+ pet: $item `none`,
208
+ };
209
+ const { path, playerClass, lifestyle, kolGender, moon, consumable, pet, permOptions, } = { ...DEFAULT_OPTIONS, ...options };
195
210
  if (playerClass.path !== (path.avatar ? path : Path.none)) {
196
211
  throw new AscendError(playerClass);
197
212
  }
@@ -200,12 +215,10 @@ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `a
200
215
  const moonId = inputToMoonId(moon, playerClass);
201
216
  if (moonId < 1 || moonId > 9)
202
217
  throw new Error(`Invalid moon ${moon}`);
203
- if (consumable &&
204
- !$items `astral six-pack, astral hot dog dinner, [10882]carton of astral energy drinks`.includes(consumable)) {
218
+ if (!$items `none, astral six-pack, astral hot dog dinner, [10882]carton of astral energy drinks`.includes(consumable)) {
205
219
  throw new AscendError(consumable);
206
220
  }
207
- if (pet &&
208
- !$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)) {
221
+ if (!$items `none, 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)) {
209
222
  throw new AscendError(pet);
210
223
  }
211
224
  const illegalSkill = permOptions
@@ -221,11 +234,12 @@ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `a
221
234
  throw new AscendError();
222
235
  }
223
236
  visitUrl("afterlife.php?action=pearlygates");
224
- if (consumable) {
237
+ if (consumable !== $item `none`) {
225
238
  visitUrl(`afterlife.php?action=buydeli&whichitem=${consumable.id}`);
226
239
  }
227
- if (pet)
240
+ if (pet !== $item `none`) {
228
241
  visitUrl(`afterlife.php?action=buyarmory&whichitem=${pet.id}`);
242
+ }
229
243
  if (permOptions) {
230
244
  const currentPerms = permedSkills();
231
245
  let karma = get("bankedKarma");
@@ -244,7 +258,7 @@ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `a
244
258
  }
245
259
  }
246
260
  }
247
- visitUrl(`afterlife.php?action=ascend&confirmascend=1&whichsign=${moonId}&gender=2&whichclass=${playerClass.id}&whichpath=${path.id}&asctype=${lifestyle}&nopetok=1&noskillsok=1&lamepathok=1&lamesignok=1&pwd`, true);
261
+ visitUrl(`afterlife.php?action=ascend&confirmascend=1&whichsign=${moonId}&gender=${kolGender}&whichclass=${playerClass.id}&whichpath=${path.id}&asctype=${lifestyle}&nopetok=1&noskillsok=1&lamepathok=1&lamesignok=1&pwd`, true);
248
262
  }
249
263
  /**
250
264
  * Sets up various iotms you may want to use in the coming ascension
@@ -1,3 +1,4 @@
1
+ import { Effect } from "kolmafia";
1
2
  import { Requirement } from "../../maximize";
2
3
  export default class CommunityService {
3
4
  private choice;
@@ -86,6 +87,11 @@ export default class CommunityService {
86
87
  * @returns The number of turns to complete this test according to council.php.
87
88
  */
88
89
  actualCost(): number;
90
+ /**
91
+ * @param effects A spread array of Effects to consider
92
+ * @returns The number of turns we expect to save if we start using those effects
93
+ */
94
+ turnsSavedBy(...effects: Effect[]): number;
89
95
  /**
90
96
  * A log of the predicted turns, actual turns, and duration of each CS test performed.
91
97
  */
@@ -1,11 +1,10 @@
1
1
  import { equippedItem, familiarWeight, getPower, haveEquipped, myAdventures, myBasestat, myBuffedstat, myFamiliar, myMaxhp, myThrall, myTurncount, numericModifier, print, runChoice, toSlot, visitUrl, weightAdjustment, } from "kolmafia";
2
2
  import { have } from "../../lib";
3
3
  import { Requirement } from "../../maximize";
4
- import { get as getModifier } from "../../modifier";
5
4
  import { get } from "../../property";
6
5
  import { MummingTrunk } from "../../resources";
7
6
  import { $effect, $familiar, $item, $items, $path, $slot, $stat, $thrall, } from "../../template-string";
8
- import { sum } from "../../utils";
7
+ import { clamp, sum } from "../../utils";
9
8
  const thralls = new Map([
10
9
  [$stat `muscle`, $thrall `Elbow Macaroni`],
11
10
  [$stat `moxie`, $thrall `Penne Dreadful`],
@@ -20,6 +19,11 @@ const statCommunityServicePredictor = (stat) => {
20
19
  };
21
20
  const visitCouncil = () => visitUrl("council.php");
22
21
  const baseWeight = () => have($effect `Fidoxene`) ? 20 : familiarWeight(myFamiliar());
22
+ function hypotheticalModifier(modifier, ...effects) {
23
+ const newEffects = effects.filter((e) => !have(e));
24
+ return (numericModifier(modifier) +
25
+ sum(newEffects, (effect) => numericModifier(effect, modifier)));
26
+ }
23
27
  export default class CommunityService {
24
28
  choice;
25
29
  stat;
@@ -194,6 +198,15 @@ export default class CommunityService {
194
198
  actualCost() {
195
199
  return this._actualCost(visitCouncil());
196
200
  }
201
+ /**
202
+ * @param effects A spread array of Effects to consider
203
+ * @returns The number of turns we expect to save if we start using those effects
204
+ */
205
+ turnsSavedBy(...effects) {
206
+ const currentTurns = clamp(this.prediction, 1, 60);
207
+ const newTurns = clamp(this.predictor(...effects), 1, 60);
208
+ return currentTurns - newTurns;
209
+ }
197
210
  /**
198
211
  * A log of the predicted turns, actual turns, and duration of each CS test performed.
199
212
  */
@@ -226,8 +239,9 @@ export default class CommunityService {
226
239
  static Muscle = new CommunityService(2, "Muscle", "Feed The Children", statCommunityServicePredictor($stat `Muscle`), new Requirement(["Muscle"], {}));
227
240
  static Mysticality = new CommunityService(3, "Mysticality", "Build Playground Mazes", statCommunityServicePredictor($stat `Mysticality`), new Requirement(["Mysticality"], {}));
228
241
  static Moxie = new CommunityService(4, "Moxie", "Feed Conspirators", statCommunityServicePredictor($stat `Moxie`), new Requirement(["Moxie"], {}));
229
- static FamiliarWeight = new CommunityService(5, "Familiar Weight", "Breed More Collies", () => 60 - Math.floor((baseWeight() + weightAdjustment()) / 5), new Requirement(["Familiar Weight"], {}));
230
- static WeaponDamage = new CommunityService(6, "Weapon Damage", "Reduce Gazelle Population", () => {
242
+ static FamiliarWeight = new CommunityService(5, "Familiar Weight", "Breed More Collies", (...effects) => 60 -
243
+ Math.floor((baseWeight() + hypotheticalModifier("Familiar Weight", ...effects)) / 5), new Requirement(["Familiar Weight"], {}));
244
+ static WeaponDamage = new CommunityService(6, "Weapon Damage", "Reduce Gazelle Population", (...effects) => {
231
245
  const weaponPower = getPower(equippedItem($slot `weapon`));
232
246
  const offhandPower = toSlot(equippedItem($slot `off-hand`)) === $slot `weapon`
233
247
  ? getPower(equippedItem($slot `off-hand`))
@@ -240,27 +254,39 @@ export default class CommunityService {
240
254
  // We add 0.001 because the floor function sometimes introduces weird rounding errors
241
255
  return (60 -
242
256
  Math.floor((multiplier *
243
- (getModifier("Weapon Damage") -
257
+ (hypotheticalModifier("Weapon Damage", ...effects) -
244
258
  0.15 * (weaponPower + offhandPower + familiarPower))) /
245
259
  50 +
246
260
  0.001) -
247
- Math.floor((multiplier * getModifier("Weapon Damage Percent")) / 50 + 0.001));
261
+ Math.floor((multiplier *
262
+ hypotheticalModifier("Weapon Damage Percent", ...effects)) /
263
+ 50 +
264
+ 0.001));
248
265
  }, new Requirement(["Weapon Damage", "Weapon Damage Percent"], {}));
249
- static SpellDamage = new CommunityService(7, "Spell Damage", "Make Sausage", () => {
266
+ static SpellDamage = new CommunityService(7, "Spell Damage", "Make Sausage", (...effects) => {
250
267
  const dragonfishDamage = myFamiliar() === $familiar `Magic Dragonfish`
251
268
  ? numericModifier($familiar `Magic Dragonfish`, "Spell Damage Percent", baseWeight() + weightAdjustment(), $item.none)
252
269
  : 0;
253
270
  // We add 0.001 because the floor function sometimes introduces weird rounding errors
254
271
  return (60 -
255
- Math.floor(getModifier("Spell Damage") / 50 + 0.001) -
256
- Math.floor((getModifier("Spell Damage Percent") - dragonfishDamage) / 50 + 0.001));
272
+ Math.floor(hypotheticalModifier("Spell Damage", ...effects) / 50 + 0.001) -
273
+ Math.floor((hypotheticalModifier("Spell Damage Percent", ...effects) -
274
+ dragonfishDamage) /
275
+ 50 +
276
+ 0.001));
257
277
  }, new Requirement(["Spell Damage", "Spell Damage Percent"], {}));
258
- static Noncombat = new CommunityService(8, "Non-Combat", "Be a Living Statue", () => {
259
- const noncombatRate = -1 * getModifier("Combat Rate");
278
+ static Noncombat = new CommunityService(8, "Non-Combat", "Be a Living Statue", (...effects) => {
279
+ const noncombatRate = -1 * hypotheticalModifier("Combat Rate", ...effects);
260
280
  const unsoftcappedRate = noncombatRate > 25 ? 25 + (noncombatRate - 25) * 5 : noncombatRate;
261
- return 60 - 3 * Math.floor(unsoftcappedRate / 5);
281
+ const currentFamiliarModifier = -1 *
282
+ numericModifier(myFamiliar(), "Combat Rate", familiarWeight(myFamiliar()) + numericModifier("Familiar Weight"), equippedItem($slot `familiar`));
283
+ const newFamiliarModifier = -1 *
284
+ numericModifier(myFamiliar(), "Combat Rate", familiarWeight(myFamiliar()) +
285
+ hypotheticalModifier("Combat Rate", ...effects), equippedItem($slot `familiar`));
286
+ const adjustedRate = unsoftcappedRate - currentFamiliarModifier + newFamiliarModifier;
287
+ return 60 - 3 * Math.floor(adjustedRate / 5);
262
288
  }, new Requirement(["-combat"], {}));
263
- static BoozeDrop = new CommunityService(9, "Item Drop", "Make Margaritas", () => {
289
+ static BoozeDrop = new CommunityService(9, "Item Drop", "Make Margaritas", (...effects) => {
264
290
  const mummingCostume = MummingTrunk.currentCostumes().get(myFamiliar());
265
291
  const mummingBuff = mummingCostume && mummingCostume[0] === "Item Drop"
266
292
  ? mummingCostume[1]
@@ -277,16 +303,26 @@ export default class CommunityService {
277
303
  // We add 0.001 because the floor function sometimes introduces weird rounding errors
278
304
  return (60 -
279
305
  Math.floor((multiplier *
280
- (getModifier("Item Drop") -
306
+ (hypotheticalModifier("Item Drop", ...effects) -
281
307
  familiarItemDrop -
282
308
  numericModifier(myThrall(), "Item Drop"))) /
283
309
  30 +
284
310
  0.001) -
285
- Math.floor((getModifier("Booze Drop") - familiarBoozeDrop) / 15 + 0.001));
311
+ Math.floor((hypotheticalModifier("Booze Drop", ...effects) - familiarBoozeDrop) /
312
+ 15 +
313
+ 0.001));
286
314
  }, new Requirement(["Item Drop", "2 Booze Drop"], {
287
315
  preventEquip: $items `broken champagne bottle`,
288
316
  }));
289
- static HotRes = new CommunityService(10, "Hot Resistance", "Clean Steam Tunnels", () => 60 - getModifier("Hot Resistance"), new Requirement(["Hot Resistance"], {}));
317
+ static HotRes = new CommunityService(10, "Hot Resistance", "Clean Steam Tunnels", (...effects) => {
318
+ const currentFamiliarModifier = numericModifier(myFamiliar(), "Hot Resistance", familiarWeight(myFamiliar()) + numericModifier("Familiar Weight"), equippedItem($slot `familiar`));
319
+ const newFamiliarModifier = numericModifier(myFamiliar(), "Hot Resistance", familiarWeight(myFamiliar()) +
320
+ hypotheticalModifier("Familiar Weight", ...effects), equippedItem($slot `familiar`));
321
+ return (60 -
322
+ (hypotheticalModifier("Hot Resistance", ...effects) -
323
+ currentFamiliarModifier +
324
+ newFamiliarModifier));
325
+ }, new Requirement(["Hot Resistance"], {}));
290
326
  static CoilWire = new CommunityService(11, "Coil Wire", "Coil Wire", () => 60, new Requirement([], {}));
291
327
  static donate = () => {
292
328
  visitCouncil();
package/dist/mood.js CHANGED
@@ -150,9 +150,9 @@ class PotionMoodElement extends MoodElement {
150
150
  // fractional part
151
151
  const remainingDifference = ensureTurns - haveEffect(effect);
152
152
  if (remainingDifference > 0) {
153
- const price = Math.floor(this.maxPricePerTurn * remainingDifference);
154
- if (price <= mallPrice(this.potion)) {
155
- if (availableAmount(this.potion) || buy(1, this.potion, price)) {
153
+ const maxPrice = Math.floor(this.maxPricePerTurn * remainingDifference);
154
+ if (mallPrice(this.potion) <= maxPrice) {
155
+ if (availableAmount(this.potion) || buy(1, this.potion, maxPrice)) {
156
156
  use(1, this.potion);
157
157
  }
158
158
  }