libram 0.6.11 → 0.6.14

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.
@@ -58,6 +58,7 @@ export declare type ActionConstraints = {
58
58
  * A combat-based action resource in the game (e.g. a free run or free kill).
59
59
  */
60
60
  export declare class ActionSource {
61
+ static defaultPriceFunction: (item: Item) => number;
61
62
  source: Item | Skill | Familiar | Array<Item | Skill | Familiar>;
62
63
  potential: () => number;
63
64
  macro: Macro;
@@ -1,4 +1,4 @@
1
- import { useFamiliar } from "kolmafia";
1
+ import { mallPrice, useFamiliar } from "kolmafia";
2
2
  import { Macro } from "../combat";
3
3
  import { Requirement } from "../maximize";
4
4
  import { sum } from "../utils";
@@ -30,6 +30,7 @@ function mergeConstraints(...allConstraints) {
30
30
  * A combat-based action resource in the game (e.g. a free run or free kill).
31
31
  */
32
32
  export class ActionSource {
33
+ static defaultPriceFunction = (item) => mallPrice(item) > 0 ? mallPrice(item) : Infinity;
33
34
  source;
34
35
  potential; // Infinity: unlimited
35
36
  macro;
@@ -140,10 +141,10 @@ function filterAction(action, constraints) {
140
141
  * @returns Available action source satisfying constraints, or null.
141
142
  */
142
143
  export function findActionSource(actions, constraints = {}) {
143
- return (actions
144
- .filter((actions) => filterAction(actions, constraints))
145
- .sort((a, b) => a.cost() - b.cost())
146
- .find((action) => action) ?? null);
144
+ const validActions = actions.filter((actions) => filterAction(actions, constraints));
145
+ return validActions.length
146
+ ? validActions.reduce((a, b) => (a.cost() > b.cost() ? a : b))
147
+ : null;
147
148
  }
148
149
  /**
149
150
  * Count available action sources subject to constraints. Note that, if
@@ -1,4 +1,4 @@
1
- import { mallPrice, myLightning, restoreMp, retrieveItem, use } from "kolmafia";
1
+ import { myLightning, restoreMp, retrieveItem, use } from "kolmafia";
2
2
  import { Macro } from "../combat";
3
3
  import { have } from "../lib";
4
4
  import { Requirement } from "../maximize";
@@ -37,17 +37,17 @@ const freeKillSources = [
37
37
  // Expensive limited sources
38
38
  new ActionSource($item `powdered madness`, () => 5 - get("_powderedMadnessUses"), Macro.item($item `powdered madness`), {
39
39
  preparation: () => retrieveItem($item `powdered madness`),
40
- cost: () => mallPrice($item `powdered madness`),
40
+ cost: () => ActionSource.defaultPriceFunction($item `powdered madness`),
41
41
  }),
42
42
  new ActionSource($familiar `Puck Man`, () => (have($familiar `Puck Man`) ? 20 - get("_powerPillUses") : 0), Macro.item($item `power pill`), {
43
43
  familiar: () => $familiar `Puck Man`,
44
44
  preparation: () => retrieveItem($item `power pill`),
45
- cost: () => mallPrice($item `power pill`),
45
+ cost: () => ActionSource.defaultPriceFunction($item `power pill`),
46
46
  }),
47
47
  new ActionSource($familiar `Ms. Puck Man`, () => (have($familiar `Ms. Puck Man`) ? 20 - get("_powerPillUses") : 0), Macro.item($item `power pill`), {
48
48
  familiar: () => $familiar `Ms. Puck Man`,
49
49
  preparation: () => retrieveItem($item `power pill`),
50
- cost: () => mallPrice($item `power pill`),
50
+ cost: () => ActionSource.defaultPriceFunction($item `power pill`),
51
51
  }),
52
52
  // Expensive unlimited sources
53
53
  new ActionSource($skill `Shocking Lick`, () => Infinity, Macro.skill($skill `Shocking Lick`), {
@@ -58,11 +58,11 @@ const freeKillSources = [
58
58
  }
59
59
  return get("shockingLickCharges") > 0;
60
60
  },
61
- cost: () => mallPrice($item `battery (AAA)`) * 4,
61
+ cost: () => ActionSource.defaultPriceFunction($item `battery (AAA)`) * 4,
62
62
  }),
63
63
  ...$items `Daily Affirmation: Think Win-Lose, superduperheated metal`.map((item) => new ActionSource(item, () => Infinity, Macro.item(item), {
64
64
  preparation: () => retrieveItem(item),
65
- cost: () => mallPrice(item),
65
+ cost: () => ActionSource.defaultPriceFunction(item),
66
66
  })),
67
67
  ];
68
68
  /**
@@ -1,4 +1,4 @@
1
- import { cliExecute, mallPrice, myTurncount, restoreMp, retrieveItem, visitUrl, } from "kolmafia";
1
+ import { cliExecute, myTurncount, restoreMp, retrieveItem, visitUrl, } from "kolmafia";
2
2
  import { Macro } from "../combat";
3
3
  import { ensureEffect, getFoldGroup, getSongCount, getSongLimit, have, } from "../lib";
4
4
  import { Requirement } from "../maximize";
@@ -108,16 +108,16 @@ const freeRunSources = [
108
108
  }),
109
109
  new ActionSource($item `peppermint parasol`, () => Math.max(0, 3 - get("_navelRunaways")), Macro.item($item `peppermint parasol`), {
110
110
  preparation: () => retrieveItem($item `peppermint parasol`),
111
- cost: () => Math.min(mallPrice($item `peppermint sprout`) * 5, mallPrice($item `peppermint parasol`)) / 10, // Breaks after 10 successful runaways.
111
+ cost: () => Math.min(ActionSource.defaultPriceFunction($item `peppermint sprout`) * 5, ActionSource.defaultPriceFunction($item `peppermint parasol`)) / 10, // Breaks after 10 successful runaways.
112
112
  }),
113
113
  new ActionSource($item `human musk`, () => Math.max(0, 3 - get("_humanMuskUses")), Macro.item($item `human musk`), {
114
114
  preparation: () => retrieveItem($item `human musk`),
115
- cost: () => mallPrice($item `human musk`),
115
+ cost: () => ActionSource.defaultPriceFunction($item `human musk`),
116
116
  }),
117
117
  // Expensive unlimited sources
118
118
  ...$items `Louder Than Bomb, divine champagne popper, tennis ball`.map((item) => new ActionSource(item, () => Infinity, Macro.item(item), {
119
119
  preparation: () => retrieveItem(item),
120
- cost: () => mallPrice(item),
120
+ cost: () => ActionSource.defaultPriceFunction(item),
121
121
  })),
122
122
  ];
123
123
  /**
@@ -14,7 +14,9 @@ const statCommunityServicePredictor = (stat) => {
14
14
  return () => 60 -
15
15
  Math.floor((1 / 30) *
16
16
  (myBuffedstat(stat) -
17
- myBasestat(thralls.get(stat) === myThrall() ? $stat `mysticality` : stat)));
17
+ myBasestat(thralls.get(stat) === myThrall() && !have($effect `Expert Oiliness`)
18
+ ? $stat `mysticality`
19
+ : stat)));
18
20
  };
19
21
  const visitCouncil = () => visitUrl("council.php");
20
22
  export default class CommunityService {
package/dist/lib.d.ts 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 { Effect, Familiar, Item, Location, Monster, Servant, Skill, Thrall } from "kolmafia";
4
+ import { Effect, Element, Familiar, Item, Location, Monster, Servant, Skill, Thrall } from "kolmafia";
5
5
  /**
6
6
  * Returns the current maximum Accordion Thief songs the player can have in their head
7
7
  *
@@ -269,3 +269,14 @@ export declare function findLeprechaunMultiplier(familiar: Familiar): number;
269
269
  export declare function findFairyMultiplier(familiar: Familiar): number;
270
270
  export declare const holidayWanderers: Map<string, Monster[]>;
271
271
  export declare function getTodaysHolidayWanderers(): Monster[];
272
+ /**
273
+ * Determines & returns whether or not we can safely call visitUrl(), based on whether we're in a fight, multi-fight, choice, etc
274
+ */
275
+ export declare function canVisitUrl(): boolean;
276
+ /**
277
+ * Calculate damage taken from a specific element after factoring in resistance
278
+ * @param baseDamage
279
+ * @param element
280
+ * @returns damage after factoring in resistances
281
+ */
282
+ export declare function damageTakenByElement(baseDamage: number, element: Element): number;
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, cliExecute, Effect, Familiar, fullnessLimit, getCampground, getCounters, getPlayerId, getPlayerName, getRelated, haveEffect, haveFamiliar, haveServant, haveSkill, holiday, inebrietyLimit, 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, Servant, Skill, spleenLimit, Thrall, toItem, toSkill, totalTurnsPlayed, } from "kolmafia";
5
5
  import { get } from "./property";
6
6
  import { $class, $familiar, $item, $items, $monsters, $skill, } from "./template-string";
7
7
  import { chunk } from "./utils";
@@ -548,3 +548,24 @@ export function getTodaysHolidayWanderers() {
548
548
  .map((holiday) => holidayWanderers.get(holiday) ?? [])
549
549
  .flat();
550
550
  }
551
+ /**
552
+ * Determines & returns whether or not we can safely call visitUrl(), based on whether we're in a fight, multi-fight, choice, etc
553
+ */
554
+ export function canVisitUrl() {
555
+ return !(currentRound() ||
556
+ inMultiFight() ||
557
+ choiceFollowsFight() ||
558
+ handlingChoice());
559
+ }
560
+ /**
561
+ * Calculate damage taken from a specific element after factoring in resistance
562
+ * @param baseDamage
563
+ * @param element
564
+ * @returns damage after factoring in resistances
565
+ */
566
+ export function damageTakenByElement(baseDamage, element) {
567
+ if (baseDamage < 0)
568
+ return 1;
569
+ const res = elementalResistance(element);
570
+ return Math.max(1, Math.ceil(baseDamage - (baseDamage * res) / 100));
571
+ }
package/dist/mood.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import "core-js/modules/es.object.values";
2
2
  import { Effect, Item, Skill } from "kolmafia";
3
3
  export declare abstract class MpSource {
4
- usesRemaining(): number | null;
4
+ usesRemaining(): number;
5
5
  abstract availableMpMin(): number;
6
6
  availableMpMax(): number;
7
7
  abstract execute(): void;
@@ -9,13 +9,14 @@ export declare abstract class MpSource {
9
9
  export declare class OscusSoda extends MpSource {
10
10
  static instance: OscusSoda;
11
11
  available(): boolean;
12
- usesRemaining(): number | null;
12
+ usesRemaining(): number;
13
13
  availableMpMin(): number;
14
14
  availableMpMax(): number;
15
15
  execute(): void;
16
16
  }
17
17
  export declare class MagicalSausages extends MpSource {
18
18
  static instance: MagicalSausages;
19
+ available(): boolean;
19
20
  usesRemaining(): number;
20
21
  availableMpMin(): number;
21
22
  execute(): void;
package/dist/mood.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "core-js/modules/es.object.values";
2
- import { availableAmount, buy, cliExecute, eat, effectModifier, haveEffect, haveSkill, hpCost, itemAmount, mallPrice, mpCost, myHp, myMaxmp, myMp, numericModifier, retrieveItem, toEffect, toSkill, turnsPerCast, use, useSkill, } from "kolmafia";
2
+ import { availableAmount, buy, cliExecute, eat, effectModifier, haveEffect, haveSkill, hpCost, mallPrice, mpCost, myHp, myMaxmp, myMp, numericModifier, retrieveItem, toEffect, toSkill, turnsPerCast, use, useSkill, } from "kolmafia";
3
3
  import { getActiveSongs, have, isSong } from "./lib";
4
4
  import { get } from "./property";
5
5
  import { AsdonMartin } from "./resources";
@@ -7,7 +7,7 @@ import { $item, $skill } from "./template-string";
7
7
  import { clamp, sum } from "./utils";
8
8
  export class MpSource {
9
9
  usesRemaining() {
10
- return null;
10
+ return 0;
11
11
  }
12
12
  availableMpMax() {
13
13
  return this.availableMpMin();
@@ -22,10 +22,10 @@ export class OscusSoda extends MpSource {
22
22
  return get("oscusSodaUsed") ? 0 : 1;
23
23
  }
24
24
  availableMpMin() {
25
- return this.available() ? 200 : 0;
25
+ return this.available() && this.usesRemaining() > 0 ? 200 : 0;
26
26
  }
27
27
  availableMpMax() {
28
- return this.available() ? 300 : 0;
28
+ return this.available() && this.usesRemaining() > 0 ? 300 : 0;
29
29
  }
30
30
  execute() {
31
31
  use($item `Oscus's neverending soda`);
@@ -33,22 +33,26 @@ export class OscusSoda extends MpSource {
33
33
  }
34
34
  export class MagicalSausages extends MpSource {
35
35
  static instance = new MagicalSausages();
36
+ available() {
37
+ return have($item `Kramco Sausage-o-Matic™`);
38
+ }
36
39
  usesRemaining() {
37
- return have($item `Kramco Sausage-o-Matic™`)
38
- ? 23 - get("_sausagesEaten")
40
+ const maxSausages = availableAmount($item `magical sausage`) +
41
+ availableAmount($item `magical sausage casing`);
42
+ return this.available()
43
+ ? clamp(23 - get("_sausagesEaten"), 0, maxSausages)
39
44
  : 0;
40
45
  }
41
46
  availableMpMin() {
42
- const maxSausages = Math.min(this.usesRemaining(), itemAmount($item `magical sausage`) +
43
- itemAmount($item `magical sausage casing`));
44
- return Math.min(myMaxmp(), 999) * maxSausages;
47
+ return this.available()
48
+ ? Math.min(myMaxmp(), 999) * this.usesRemaining()
49
+ : 0;
45
50
  }
46
51
  execute() {
47
52
  const mpSpaceAvailable = myMaxmp() - myMp();
48
53
  if (mpSpaceAvailable < 700)
49
54
  return;
50
- const maxSausages = Math.min(this.usesRemaining(), itemAmount($item `magical sausage`) +
51
- itemAmount($item `magical sausage casing`), Math.floor((myMaxmp() - myMp()) / Math.min(myMaxmp() - myMp(), 999)));
55
+ const maxSausages = Math.min(this.usesRemaining(), Math.floor((myMaxmp() - myMp()) / Math.min(myMaxmp() - myMp(), 999)));
52
56
  retrieveItem(maxSausages, $item `magical sausage`);
53
57
  eat(maxSausages, $item `magical sausage`);
54
58
  }
@@ -102,10 +106,10 @@ class SkillMoodElement extends MoodElement {
102
106
  }
103
107
  else {
104
108
  const cost = mpCost(this.skill);
105
- maxCasts = Math.floor(myMp() / cost);
109
+ maxCasts = Math.floor(Math.min(mood.availableMp(), myMp()) / cost);
106
110
  if (maxCasts === 0) {
107
111
  mood.moreMp(cost);
108
- maxCasts = Math.floor(myMp() / cost);
112
+ maxCasts = Math.floor(Math.min(mood.availableMp(), myMp()) / cost);
109
113
  }
110
114
  }
111
115
  const casts = clamp(remainingCasts, 0, Math.min(100, maxCasts));
@@ -236,9 +240,10 @@ export class Mood {
236
240
  return (sum(this.options.mpSources, (mpSource) => mpSource.availableMpMin()) + Math.max(myMp() - this.options.reserveMp, 0));
237
241
  }
238
242
  moreMp(minimumTarget) {
243
+ if (myMp() >= minimumTarget)
244
+ return;
239
245
  for (const mpSource of this.options.mpSources) {
240
- const usesRemaining = mpSource.usesRemaining();
241
- if (usesRemaining !== null && usesRemaining > 0) {
246
+ if (mpSource.usesRemaining() > 0) {
242
247
  mpSource.execute();
243
248
  if (myMp() >= minimumTarget)
244
249
  break;
@@ -315,6 +320,7 @@ export class Mood {
315
320
  }
316
321
  completeSuccess = element.execute(this, elementTurns) && completeSuccess;
317
322
  }
323
+ this.moreMp(this.options.reserveMp);
318
324
  return completeSuccess;
319
325
  }
320
326
  }
@@ -93,6 +93,12 @@ export declare class PropertiesManager {
93
93
  setChoices(choicesToSet: {
94
94
  [choice: number]: number | string;
95
95
  }): void;
96
+ /**
97
+ * Sets a single choice adventure property to the given value, storing the old value.
98
+ * @param choiceToSet The number of the choice adventure to set the property for.
99
+ * @param value The value to assign to that choice adventure.
100
+ */
101
+ setChoice(choiceToSet: number, value: number | string): void;
96
102
  /**
97
103
  * Resets the given properties to their original stored value. Does not delete entries from the manager.
98
104
  * @param properties Collection of properties to reset.
@@ -125,5 +131,36 @@ export declare class PropertiesManager {
125
131
  * @returns Whether we needed to change the property.
126
132
  */
127
133
  setMaximumValue(property: NumericProperty, value: number): boolean;
134
+ /**
135
+ * Creates a new PropertiesManager with identical stored values to this one.
136
+ * @returns A new PropertiesManager, with identical stored values to this one.
137
+ */
138
+ clone(): PropertiesManager;
139
+ /**
140
+ * Clamps a numeric property, modulating it up or down to fit within a specified range
141
+ * @param property The numeric property to clamp
142
+ * @param min The lower bound for what we want the property to be allowed to be.
143
+ * @param max The upper bound for what we want the property to be allowed to be.
144
+ * @returns Whether we ended up changing the property or not.
145
+ */
146
+ clamp(property: NumericProperty, min: number, max: number): boolean;
147
+ /**
148
+ * Determines whether this PropertiesManager has identical stored values to another.
149
+ * @param other The PropertiesManager to compare to this one.
150
+ * @returns Whether their StoredValues are identical.
151
+ */
152
+ equals(other: PropertiesManager): boolean;
153
+ /**
154
+ * Merges a PropertiesManager onto this one, letting the input win in the event that both PropertiesManagers have a value stored.
155
+ * @param other The PropertiesManager to be merged onto this one.
156
+ * @returns A new PropertiesManager with stored values from both its parents.
157
+ */
158
+ merge(other: PropertiesManager): PropertiesManager;
159
+ /**
160
+ * Merges an arbitrary collection of PropertiesManagers, letting the rightmost PropertiesManager win in the event of verlap.
161
+ * @param mergees The PropertiesManagers to merge together.
162
+ * @returns A PropertiesManager that is just an amalgam of all the constituents.
163
+ */
164
+ static merge(...mergees: PropertiesManager[]): PropertiesManager;
128
165
  }
129
166
  export {};
package/dist/property.js CHANGED
@@ -153,6 +153,14 @@ export class PropertiesManager {
153
153
  choiceValue,
154
154
  ])));
155
155
  }
156
+ /**
157
+ * Sets a single choice adventure property to the given value, storing the old value.
158
+ * @param choiceToSet The number of the choice adventure to set the property for.
159
+ * @param value The value to assign to that choice adventure.
160
+ */
161
+ setChoice(choiceToSet, value) {
162
+ this.setChoices({ [choiceToSet]: value });
163
+ }
156
164
  /**
157
165
  * Resets the given properties to their original stored value. Does not delete entries from the manager.
158
166
  * @param properties Collection of properties to reset.
@@ -214,4 +222,64 @@ export class PropertiesManager {
214
222
  }
215
223
  return false;
216
224
  }
225
+ /**
226
+ * Creates a new PropertiesManager with identical stored values to this one.
227
+ * @returns A new PropertiesManager, with identical stored values to this one.
228
+ */
229
+ clone() {
230
+ const newGuy = new PropertiesManager();
231
+ newGuy.properties = this.storedValues;
232
+ return newGuy;
233
+ }
234
+ /**
235
+ * Clamps a numeric property, modulating it up or down to fit within a specified range
236
+ * @param property The numeric property to clamp
237
+ * @param min The lower bound for what we want the property to be allowed to be.
238
+ * @param max The upper bound for what we want the property to be allowed to be.
239
+ * @returns Whether we ended up changing the property or not.
240
+ */
241
+ clamp(property, min, max) {
242
+ if (max < min)
243
+ return false;
244
+ const start = get(property);
245
+ this.setMinimumValue(property, min);
246
+ this.setMaximumValue(property, max);
247
+ return start !== get(property);
248
+ }
249
+ /**
250
+ * Determines whether this PropertiesManager has identical stored values to another.
251
+ * @param other The PropertiesManager to compare to this one.
252
+ * @returns Whether their StoredValues are identical.
253
+ */
254
+ equals(other) {
255
+ const thisProps = Object.entries(this.storedValues);
256
+ const otherProps = new Map(Object.entries(other.storedValues));
257
+ if (thisProps.length !== otherProps.size)
258
+ return false;
259
+ for (const [propertyName, propertyValue] of thisProps) {
260
+ if (otherProps.get(propertyName) === propertyValue)
261
+ return false;
262
+ }
263
+ return true;
264
+ }
265
+ /**
266
+ * Merges a PropertiesManager onto this one, letting the input win in the event that both PropertiesManagers have a value stored.
267
+ * @param other The PropertiesManager to be merged onto this one.
268
+ * @returns A new PropertiesManager with stored values from both its parents.
269
+ */
270
+ merge(other) {
271
+ const newGuy = new PropertiesManager();
272
+ newGuy.properties = { ...this.properties, ...other.properties };
273
+ return newGuy;
274
+ }
275
+ /**
276
+ * Merges an arbitrary collection of PropertiesManagers, letting the rightmost PropertiesManager win in the event of verlap.
277
+ * @param mergees The PropertiesManagers to merge together.
278
+ * @returns A PropertiesManager that is just an amalgam of all the constituents.
279
+ */
280
+ static merge(...mergees) {
281
+ if (mergees.length === 0)
282
+ return new PropertiesManager();
283
+ return mergees.reduce((a, b) => a.merge(b));
284
+ }
217
285
  }