libram 0.6.22 → 0.7.0

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
@@ -1,5 +1,4 @@
1
- import { Skill, Class, Item, MafiaClass } from "kolmafia";
2
- import { Path } from "./Path";
1
+ import { Skill, Class, Item, Path, MafiaClass } from "kolmafia";
3
2
  import { ChateauMantegna } from "./resources";
4
3
  export declare enum Lifestyle {
5
4
  casual = 1,
package/dist/ascend.js CHANGED
@@ -1,5 +1,4 @@
1
- import { Skill, Class, containsText, eudoraItem, getCampground, getWorkshed, Item, toInt, use, visitUrl, xpath, haveSkill, } from "kolmafia";
2
- import { Path } from "./Path";
1
+ import { Skill, Class, containsText, eudoraItem, getCampground, getWorkshed, Item, Path, toInt, use, visitUrl, xpath, haveSkill, } from "kolmafia";
3
2
  import { ChateauMantegna } from "./resources";
4
3
  import { $item, $items, $stat } from "./template-string";
5
4
  import { createStringUnionTypeGuardFunction } from "./utils";
@@ -163,7 +162,8 @@ function toMoonId(moon, playerClass) {
163
162
  * @param pet From the astral pet store.
164
163
  */
165
164
  export function ascend(path, playerClass, lifestyle, moon, consumable = $item `astral six-pack`, pet = undefined, permSkills = undefined) {
166
- if (!path.classes.includes(playerClass)) {
165
+ if (path === Path.none ||
166
+ playerClass.path !== (path.avatar ? path : Path.none)) {
167
167
  throw new AscendError(playerClass);
168
168
  }
169
169
  if (path.id < 0)
@@ -216,7 +216,7 @@ export default class CommunityService {
216
216
  }, new Requirement(["Weapon Damage", "Weapon Damage Percent"], {}));
217
217
  static SpellDamage = new CommunityService(7, "Spell Damage", "Make Sausage", () => {
218
218
  const dragonfishDamage = myFamiliar() === $familiar `Magic Dragonfish`
219
- ? numericModifier($familiar `Magic Dragonfish`, "Spell Damage Percent", familiarWeight($familiar `Magic Dragonfish`) + weightAdjustment(), $item `none`)
219
+ ? numericModifier($familiar `Magic Dragonfish`, "Spell Damage Percent", familiarWeight($familiar `Magic Dragonfish`) + weightAdjustment(), $item.none)
220
220
  : 0;
221
221
  // We add 0.001 because the floor function sometimes introduces weird rounding errors
222
222
  return (60 -
package/dist/combat.js CHANGED
@@ -78,7 +78,7 @@ export class Macro {
78
78
  * Convert macro to string.
79
79
  */
80
80
  toString() {
81
- return this.components.join(";");
81
+ return (this.components.join(";") + ";").replace(/;;+/g, ";");
82
82
  }
83
83
  /**
84
84
  * Gives your macro a new name to be used when saving an autoattack.
@@ -115,10 +115,7 @@ export class Macro {
115
115
  */
116
116
  step(...nextSteps) {
117
117
  const nextStepsStrings = [].concat(...nextSteps.map((x) => (x instanceof Macro ? x.components : [x])));
118
- this.components = [
119
- ...this.components,
120
- ...nextStepsStrings.filter((s) => s.length > 0),
121
- ];
118
+ this.components.push(...nextStepsStrings.filter((s) => s.length > 0));
122
119
  return this;
123
120
  }
124
121
  /**
@@ -225,7 +225,7 @@ class DietPlanner {
225
225
  const helpers = [];
226
226
  if (this.seasoning &&
227
227
  itemType(menuItem.item) === "food" &&
228
- this.mpa > mallPrice($item `Special Seasoning`)) {
228
+ this.mpa * 0.5 > mallPrice($item `Special Seasoning`)) {
229
229
  helpers.push(this.seasoning);
230
230
  }
231
231
  if (itemType(menuItem.item) === "food" && this.mayoLookup.size) {
package/dist/lib.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /** @module GeneralLibrary */
2
2
  import "core-js/modules/es.object.entries";
3
3
  import "core-js/features/array/flat";
4
- import { appearanceRates, autosellPrice, availableAmount, booleanModifier, choiceFollowsFight, cliExecute, currentRound, Effect, elementalResistance, Familiar, fullnessLimit, getCampground, getCounters, getPlayerId, getPlayerName, getRelated, handlingChoice, haveEffect, haveFamiliar, haveServant, haveSkill, holiday, inebrietyLimit, inMultiFight, Item, Location, mallPrice, Monster, myEffects, myFamiliar, myFullness, myInebriety, myPath, mySpleenUse, myThrall, myTurncount, numericModifier, Servant, Skill, spleenLimit, Thrall, toItem, toSkill, totalTurnsPlayed, } from "kolmafia";
4
+ import { appearanceRates, autosellPrice, availableAmount, booleanModifier, choiceFollowsFight, cliExecute, currentRound, Effect, elementalResistance, Familiar, fullnessLimit, getCampground, getCounters, getPlayerId, getPlayerName, getRelated, handlingChoice, haveEffect, haveFamiliar, haveServant, haveSkill, holiday, inebrietyLimit, inMultiFight, Item, Location, mallPrice, Monster, myEffects, myFamiliar, myFullness, myInebriety, myPath, mySpleenUse, myThrall, myTurncount, numericModifier, Path, Servant, Skill, spleenLimit, Thrall, toItem, toSkill, totalTurnsPlayed, } from "kolmafia";
5
5
  import { get } from "./property";
6
6
  import { $class, $element, $familiar, $item, $items, $monsters, $skill, $stat, } from "./template-string";
7
7
  import { chunk } from "./utils";
@@ -178,7 +178,8 @@ export function haveWandererCounter(wanderer) {
178
178
  * @category Wanderers
179
179
  */
180
180
  export function isVoteWandererNow() {
181
- return totalTurnsPlayed() % 11 == 1;
181
+ return (totalTurnsPlayed() % 11 === 1 &&
182
+ get("lastVoteMonsterTurn") < totalTurnsPlayed());
182
183
  }
183
184
  /**
184
185
  * Tells us whether we can expect a given wanderer now. Behaves differently
@@ -200,7 +201,7 @@ export function isWandererNow(wanderer) {
200
201
  if (deterministicWanderers.includes(wanderer)) {
201
202
  return haveCounter(wanderer, 0, 0);
202
203
  }
203
- if (wanderer == Wanderer.Kramco) {
204
+ if (wanderer === Wanderer.Kramco) {
204
205
  return true;
205
206
  }
206
207
  if (wanderer === Wanderer.Vote) {
@@ -327,12 +328,12 @@ export function getBanishedMonsters() {
327
328
  result.set($skill `Use the Force`, Monster.get(foe));
328
329
  }
329
330
  else if ([
330
- Item.get("none"),
331
+ Item.none,
331
332
  Item.get(`training scroll: Snokebomb`),
332
333
  Item.get(`tomayohawk-style reflex hammer`),
333
334
  null,
334
335
  ].includes(banisherItem)) {
335
- if (Skill.get(banisher) === $skill `none`) {
336
+ if (Skill.get(banisher) === $skill.none) {
336
337
  break;
337
338
  }
338
339
  else {
@@ -354,16 +355,16 @@ export function getBanishedMonsters() {
354
355
  */
355
356
  export function canUse(item) {
356
357
  const path = myPath();
357
- if (path !== "Nuclear Autumn") {
358
+ if (path !== Path.get("Nuclear Autumn")) {
358
359
  if ($items `Shrieking Weasel holo-record, Power-Guy 2000 holo-record, Lucky Strikes holo-record, EMD holo-record, Superdrifter holo-record, The Pigs holo-record, Drunk Uncles holo-record`.includes(item)) {
359
360
  return false;
360
361
  }
361
362
  }
362
- if (path === "G-Lover") {
363
+ if (path === Path.get("G-Lover")) {
363
364
  if (!item.name.toLowerCase().includes("g"))
364
365
  return false;
365
366
  }
366
- if (path === "Bees Hate You") {
367
+ if (path === Path.get("Bees Hate You")) {
367
368
  if (item.name.toLowerCase().includes("b"))
368
369
  return false;
369
370
  }
@@ -376,13 +377,13 @@ export function canUse(item) {
376
377
  */
377
378
  export function noneToNull(thing) {
378
379
  if (thing instanceof Effect) {
379
- return thing === Effect.get("none") ? null : thing;
380
+ return thing === Effect.none ? null : thing;
380
381
  }
381
382
  if (thing instanceof Familiar) {
382
- return thing === Familiar.get("none") ? null : thing;
383
+ return thing === Familiar.none ? null : thing;
383
384
  }
384
385
  if (thing instanceof Item) {
385
- return thing === Item.get("none") ? null : thing;
386
+ return thing === Item.none ? null : thing;
386
387
  }
387
388
  return thing;
388
389
  }
@@ -513,11 +514,11 @@ export const Environment = {
513
514
  */
514
515
  export function findLeprechaunMultiplier(familiar) {
515
516
  if (familiar === $familiar `Mutant Cactus Bud`) {
516
- return numericModifier(familiar, "Leprechaun Effectiveness", 1, $item `none`);
517
+ return numericModifier(familiar, "Leprechaun Effectiveness", 1, $item.none);
517
518
  }
518
519
  if (familiar === $familiar `Reanimated Reanimator`)
519
520
  return 0;
520
- const meatBonus = numericModifier(familiar, "Meat Drop", 1, $item `none`);
521
+ const meatBonus = numericModifier(familiar, "Meat Drop", 1, $item.none);
521
522
  if (meatBonus === 0)
522
523
  return 0;
523
524
  return Math.pow(Math.sqrt(meatBonus / 2 + 55 / 4 + 3) - Math.sqrt(55) / 2, 2);
@@ -530,11 +531,11 @@ export function findLeprechaunMultiplier(familiar) {
530
531
  */
531
532
  export function findFairyMultiplier(familiar) {
532
533
  if (familiar === $familiar `Mutant Fire Ant`) {
533
- return numericModifier(familiar, "Fairy Effectiveness", 1, $item `none`);
534
+ return numericModifier(familiar, "Fairy Effectiveness", 1, $item.none);
534
535
  }
535
536
  if (familiar === $familiar `Reanimated Reanimator`)
536
537
  return 0;
537
- const itemBonus = numericModifier(familiar, "Item Drop", 1, $item `none`);
538
+ const itemBonus = numericModifier(familiar, "Item Drop", 1, $item.none);
538
539
  if (itemBonus === 0)
539
540
  return 0;
540
541
  return Math.pow(Math.sqrt(itemBonus + 55 / 4 + 3) - Math.sqrt(55) / 2, 2);
package/dist/maximize.js CHANGED
@@ -195,11 +195,11 @@ function applyCached(entry, options) {
195
195
  }
196
196
  if (equippedAmount($item `Crown of Thrones`) > 0 &&
197
197
  entry.rider.get($item `Crown of Thrones`)) {
198
- enthroneFamiliar(entry.rider.get($item `Crown of Thrones`) || $familiar `none`);
198
+ enthroneFamiliar(entry.rider.get($item `Crown of Thrones`) || $familiar.none);
199
199
  }
200
200
  if (equippedAmount($item `Buddy Bjorn`) > 0 &&
201
201
  entry.rider.get($item `Buddy Bjorn`)) {
202
- bjornifyFamiliar(entry.rider.get($item `Buddy Bjorn`) || $familiar `none`);
202
+ bjornifyFamiliar(entry.rider.get($item `Buddy Bjorn`) || $familiar.none);
203
203
  }
204
204
  }
205
205
  const slotStructure = [
@@ -312,28 +312,39 @@ export function maximizeCached(objectives, options = {}) {
312
312
  const { forceEquip, preventEquip, bonusEquip, onlySlot, preventSlot, forceUpdate, } = fullOptions;
313
313
  // Sort each group in objective to ensure consistent ordering in string
314
314
  const objective = [
315
- ...objectives.sort(),
316
- ...forceEquip.map((item) => `equip ${item}`).sort(),
317
- ...preventEquip.map((item) => `-equip ${item}`).sort(),
318
- ...onlySlot.map((slot) => `${slot}`).sort(),
319
- ...preventSlot.map((slot) => `-${slot}`).sort(),
320
- ...Array.from(bonusEquip.entries())
321
- .filter(([, bonus]) => bonus !== 0)
322
- .map(([item, bonus]) => `${Math.round(bonus * 100) / 100} bonus ${item}`)
323
- .sort(),
315
+ ...new Set([
316
+ ...objectives.sort(),
317
+ ...forceEquip.map((item) => `equip ${item}`).sort(),
318
+ ...preventEquip.map((item) => `-equip ${item}`).sort(),
319
+ ...onlySlot.map((slot) => `${slot}`).sort(),
320
+ ...preventSlot.map((slot) => `-${slot}`).sort(),
321
+ ...Array.from(bonusEquip.entries())
322
+ .filter(([, bonus]) => bonus !== 0)
323
+ .map(([item, bonus]) => `${Math.round(bonus * 100) / 100} bonus ${item}`)
324
+ .sort(),
325
+ ]),
324
326
  ].join(", ");
325
- const cacheEntry = checkCache(objective, fullOptions);
327
+ // Items equipped in slots not touched by the maximizer must be in the cache key
328
+ const untouchedSlots = cachedSlots.filter((slot) => preventSlot.includes(slot) ||
329
+ (onlySlot.length > 0 && !onlySlot.includes(slot)));
330
+ const cacheKey = [
331
+ objective,
332
+ ...untouchedSlots
333
+ .map((slot) => `${slot}:${equippedItem(slot)}`)
334
+ .sort(),
335
+ ].join("; ");
336
+ const cacheEntry = checkCache(cacheKey, fullOptions);
326
337
  if (cacheEntry && !forceUpdate) {
327
338
  logger.info("Equipment found in maximize cache, equipping...");
328
339
  applyCached(cacheEntry, fullOptions);
329
340
  if (verifyCached(cacheEntry)) {
330
- logger.info(`Equipped cached ${objective}`);
341
+ logger.info(`Equipped cached ${cacheKey}`);
331
342
  return true;
332
343
  }
333
344
  logger.warning("Maximize cache application failed, maximizing...");
334
345
  }
335
346
  const result = maximize(objective, false);
336
- saveCached(objective, fullOptions);
347
+ saveCached(cacheKey, fullOptions);
337
348
  return result;
338
349
  }
339
350
  export class Requirement {
package/dist/mood.js CHANGED
@@ -104,7 +104,7 @@ class SkillMoodElement extends MoodElement {
104
104
  let maxCasts;
105
105
  if (hpCost(this.skill) > 0) {
106
106
  // FIXME: restore HP
107
- maxCasts = Math.floor(myHp() / hpCost(this.skill));
107
+ maxCasts = Math.max(0, Math.floor((myHp() - 1) / hpCost(this.skill))); // Do not allow ourselves to hit 0 hp
108
108
  }
109
109
  else {
110
110
  const cost = mpCost(this.skill);
@@ -274,7 +274,7 @@ export class Mood {
274
274
  */
275
275
  effect(effect, gainEffect) {
276
276
  const skill = toSkill(effect);
277
- if (!gainEffect && skill !== $skill `none`) {
277
+ if (!gainEffect && skill !== $skill.none) {
278
278
  this.skill(skill);
279
279
  }
280
280
  else {
package/dist/property.js CHANGED
@@ -13,7 +13,7 @@ const createMafiaClassPropertyGetter = (Type, toType) => createPropertyGetter((v
13
13
  if (value === "")
14
14
  return null;
15
15
  const v = toType(value);
16
- return v === Type.get("none") ? null : v;
16
+ return v === Type.none ? null : v;
17
17
  });
18
18
  export const getString = createPropertyGetter((value) => value);
19
19
  export const getCommaSeparated = createPropertyGetter((value) => value.split(/, ?/));