libram 0.8.36 → 0.9.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.
Files changed (136) hide show
  1. package/dist/Clan.js +3 -3
  2. package/dist/Dungeon.js +4 -4
  3. package/dist/Kmail.js +3 -3
  4. package/dist/Macro.test.d.ts +1 -0
  5. package/dist/Macro.test.js +126 -0
  6. package/dist/actions/ActionSource.d.ts +2 -2
  7. package/dist/actions/ActionSource.js +3 -3
  8. package/dist/actions/Banish.d.ts +1 -1
  9. package/dist/actions/Banish.js +7 -7
  10. package/dist/actions/FreeKill.d.ts +1 -1
  11. package/dist/actions/FreeKill.js +7 -7
  12. package/dist/actions/FreeRun.d.ts +1 -1
  13. package/dist/actions/FreeRun.js +8 -8
  14. package/dist/actions/index.d.ts +4 -4
  15. package/dist/actions/index.js +4 -4
  16. package/dist/ascend.d.ts +2 -2
  17. package/dist/ascend.js +5 -5
  18. package/dist/challengePaths/2014/HeavyRains.js +3 -3
  19. package/dist/challengePaths/2015/CommunityService.d.ts +1 -1
  20. package/dist/challengePaths/2015/CommunityService.js +6 -6
  21. package/dist/challengePaths/2016/NuclearAutumn.js +1 -1
  22. package/dist/challengePaths/index.d.ts +3 -3
  23. package/dist/challengePaths/index.js +3 -3
  24. package/dist/combat.js +8 -6
  25. package/dist/diet/index.js +23 -9
  26. package/dist/diet/knapsack.js +1 -1
  27. package/dist/diet/knapsack.test.d.ts +1 -0
  28. package/dist/diet/knapsack.test.js +77 -0
  29. package/dist/index.d.ts +29 -29
  30. package/dist/index.js +26 -26
  31. package/dist/lib.d.ts +2 -2
  32. package/dist/lib.js +4 -4
  33. package/dist/lib.test.d.ts +1 -0
  34. package/dist/lib.test.js +142 -0
  35. package/dist/maximize.js +4 -4
  36. package/dist/modifier.d.ts +4 -9
  37. package/dist/modifier.js +5 -20
  38. package/dist/modifierTypes.d.ts +4 -14
  39. package/dist/modifierTypes.js +3 -8
  40. package/dist/mood.js +5 -5
  41. package/dist/property.d.ts +2 -2
  42. package/dist/property.js +1 -1
  43. package/dist/propertyTypes.d.ts +2 -2
  44. package/dist/propertyTypes.js +2 -2
  45. package/dist/propertyTyping.d.ts +1 -1
  46. package/dist/propertyTyping.js +1 -1
  47. package/dist/resources/2007/CandyHearts.js +2 -2
  48. package/dist/resources/2008/DivineFavors.js +3 -3
  49. package/dist/resources/2008/Stickers.js +1 -1
  50. package/dist/resources/2009/Bandersnatch.js +3 -3
  51. package/dist/resources/2009/LoveSongs.js +2 -2
  52. package/dist/resources/2009/SpookyPutty.js +3 -3
  53. package/dist/resources/2010/Brickos.js +3 -3
  54. package/dist/resources/2010/CrownOfThrones.d.ts +1 -1
  55. package/dist/resources/2010/CrownOfThrones.js +4 -4
  56. package/dist/resources/2010/LookingGlass.js +3 -3
  57. package/dist/resources/2011/Gygaxian.js +2 -2
  58. package/dist/resources/2011/ObtuseAngel.d.ts +1 -1
  59. package/dist/resources/2011/ObtuseAngel.js +4 -4
  60. package/dist/resources/2011/StompingBoots.js +3 -3
  61. package/dist/resources/2012/RainDoh.js +3 -3
  62. package/dist/resources/2012/ReagnimatedGnome.js +2 -2
  63. package/dist/resources/2012/Resolutions.js +2 -2
  64. package/dist/resources/2013/Florist.d.ts +2 -2
  65. package/dist/resources/2013/Florist.js +4 -4
  66. package/dist/resources/2013/JungMan.js +2 -2
  67. package/dist/resources/2013/PulledTaffy.js +3 -3
  68. package/dist/resources/2014/CrimboShrub.js +3 -3
  69. package/dist/resources/2014/DNALab.js +8 -8
  70. package/dist/resources/2014/WinterGarden.d.ts +1 -1
  71. package/dist/resources/2014/WinterGarden.js +4 -4
  72. package/dist/resources/2015/BarrelShrine.js +3 -3
  73. package/dist/resources/2015/ChateauMantegna.d.ts +1 -1
  74. package/dist/resources/2015/ChateauMantegna.js +1 -1
  75. package/dist/resources/2015/DeckOfEveryCard.js +4 -4
  76. package/dist/resources/2015/Dinseylandfill.js +3 -3
  77. package/dist/resources/2015/MayoClinic.js +4 -4
  78. package/dist/resources/2016/GingerBread.js +2 -2
  79. package/dist/resources/2016/SourceTerminal.d.ts +1 -1
  80. package/dist/resources/2016/SourceTerminal.js +5 -5
  81. package/dist/resources/2016/Witchess.d.ts +1 -1
  82. package/dist/resources/2016/Witchess.js +3 -3
  83. package/dist/resources/2017/AsdonMartin.js +3 -3
  84. package/dist/resources/2017/Horsery.d.ts +1 -1
  85. package/dist/resources/2017/Horsery.js +1 -1
  86. package/dist/resources/2017/MummingTrunk.d.ts +1 -1
  87. package/dist/resources/2017/MummingTrunk.js +1 -1
  88. package/dist/resources/2017/Pantogram.js +2 -2
  89. package/dist/resources/2017/Robortender.js +2 -2
  90. package/dist/resources/2017/Spacegate.js +2 -2
  91. package/dist/resources/2017/TunnelOfLove.d.ts +1 -1
  92. package/dist/resources/2017/TunnelOfLove.js +4 -4
  93. package/dist/resources/2018/LatteLoversMembersMug.d.ts +1 -1
  94. package/dist/resources/2018/LatteLoversMembersMug.js +5 -5
  95. package/dist/resources/2018/SongBoom.js +3 -3
  96. package/dist/resources/2019/BeachComb.js +4 -4
  97. package/dist/resources/2019/CampAway.js +4 -4
  98. package/dist/resources/2019/Snapper.js +1 -1
  99. package/dist/resources/2020/Cartography.js +3 -3
  100. package/dist/resources/2020/Guzzlr.js +4 -4
  101. package/dist/resources/2020/RetroCape.d.ts +1 -1
  102. package/dist/resources/2020/RetroCape.js +9 -9
  103. package/dist/resources/2021/CrystalBall.js +3 -3
  104. package/dist/resources/2021/DaylightShavings.js +3 -3
  105. package/dist/resources/2022/AutumnAton.js +4 -4
  106. package/dist/resources/2022/CombatLoversLocket.d.ts +1 -1
  107. package/dist/resources/2022/CombatLoversLocket.js +4 -4
  108. package/dist/resources/2022/GreyGoose.js +4 -4
  109. package/dist/resources/2022/JuneCleaver.js +1 -1
  110. package/dist/resources/2022/TrainSet.d.ts +1 -1
  111. package/dist/resources/2022/TrainSet.js +4 -4
  112. package/dist/resources/2023/AugustScepter.d.ts +1 -1
  113. package/dist/resources/2023/AugustScepter.js +3 -3
  114. package/dist/resources/2023/BurningLeaves.js +3 -3
  115. package/dist/resources/2023/CinchoDeMayo.js +4 -4
  116. package/dist/resources/2023/ClosedCircuitPayphone.d.ts +1 -1
  117. package/dist/resources/2023/ClosedCircuitPayphone.js +4 -4
  118. package/dist/resources/2023/CursedMonkeyPaw.js +5 -5
  119. package/dist/resources/2024/AprilingBandHelmet.js +4 -4
  120. package/dist/resources/2024/ChestMimic.d.ts +1 -1
  121. package/dist/resources/2024/ChestMimic.js +3 -3
  122. package/dist/resources/2024/MayamCalendar.d.ts +12 -0
  123. package/dist/resources/2024/MayamCalendar.js +23 -6
  124. package/dist/resources/LibramSummon.js +10 -10
  125. package/dist/resources/index.d.ts +54 -54
  126. package/dist/resources/index.js +54 -54
  127. package/dist/resources/putty-likes.d.ts +1 -1
  128. package/dist/resources/putty-likes.js +3 -3
  129. package/dist/session.js +3 -3
  130. package/dist/template-string.d.ts +18 -1
  131. package/dist/template-string.js +2 -1
  132. package/dist/url.test.d.ts +1 -0
  133. package/dist/url.test.js +147 -0
  134. package/dist/utils.test.d.ts +1 -0
  135. package/dist/utils.test.js +8 -0
  136. package/package.json +21 -22
package/dist/Clan.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { decode as decodeEntities } from "html-entities";
2
2
  import { availableAmount, cliExecute, getClanId, getClanName, getPlayerId, Monster, putStash, refreshStash, retrieveItem, stashAmount, takeStash, visitUrl, xpath, } from "kolmafia";
3
- import { getFoldGroup } from "./lib";
4
- import logger from "./logger";
5
- import { arrayToCountedMap, countedMapToArray, countedMapToString, notNull, parseNumber, } from "./utils";
3
+ import { getFoldGroup } from "./lib.js";
4
+ import logger from "./logger.js";
5
+ import { arrayToCountedMap, countedMapToArray, countedMapToString, notNull, parseNumber, } from "./utils.js";
6
6
  const clanIdCache = {};
7
7
  const toPlayerId = (player) => typeof player === "string" ? getPlayerId(player) : player;
8
8
  const LOG_FAX_PATTERN = /(\d{2}\/\d{2}\/\d{2}, \d{2}:\d{2}(?:AM|PM): )<a [^>]+>([^<]+)<\/a>(?: faxed in a (?<monster>.*?))<br>/;
package/dist/Dungeon.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { getClanName, toItem, visitUrl, xpath } from "kolmafia";
2
- import { Clan } from "./Clan";
3
- import { getPlayerFromIdOrName } from "./lib";
4
- import { $items } from "./template-string";
5
- import { countedMapToArray } from "./utils";
2
+ import { Clan } from "./Clan.js";
3
+ import { getPlayerFromIdOrName } from "./lib.js";
4
+ import { $items } from "./template-string.js";
5
+ import { countedMapToArray } from "./utils.js";
6
6
  export class Dungeon {
7
7
  name_;
8
8
  loot;
package/dist/Kmail.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { decode as decodeEntities } from "html-entities";
2
2
  import { extractMeat, isGiftable, visitUrl } from "kolmafia";
3
- import { extractItems } from "./lib";
4
- import { combineQuery, EMPTY_VALUE, fetchUrl } from "./url";
5
- import { arrayToCountedMap, chunk } from "./utils";
3
+ import { extractItems } from "./lib.js";
4
+ import { combineQuery, EMPTY_VALUE, fetchUrl } from "./url.js";
5
+ import { arrayToCountedMap, chunk } from "./utils.js";
6
6
  export default class Kmail {
7
7
  id;
8
8
  date;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,126 @@
1
+ /* eslint-disable libram/verify-constants */
2
+ import { describe, it, expect } from "vitest";
3
+ import { InvalidMacroError, Macro } from "./combat.js";
4
+ import { $class, $effect, $item, $location, $monster, $skill, $stat, } from "./template-string.js";
5
+ describe(Macro, () => {
6
+ it("abort", () => {
7
+ expect(Macro.abort().toString()).toEqual(`abort;`);
8
+ });
9
+ it("abortWithWarning", () => {
10
+ expect(Macro.abortWithWarning("test").toString()).toEqual(`abort "test";`);
11
+ });
12
+ it("runaway", () => {
13
+ expect(Macro.runaway().toString()).toEqual(`runaway;`);
14
+ });
15
+ it("if_", () => {
16
+ expect(Macro.if_("mock", Macro.abort()).toString()).toEqual(`if mock;abort;endif;`);
17
+ });
18
+ it("ifNot", () => {
19
+ expect(Macro.ifNot("mock", Macro.abort()).toString()).toEqual(`if !(mock);abort;endif;`);
20
+ });
21
+ it("while_", () => {
22
+ expect(Macro.while_("mock", Macro.abort()).toString()).toEqual(`while mock;abort;endwhile;`);
23
+ });
24
+ it("externalIf false", () => {
25
+ expect(Macro.externalIf(false, "true", "false").toString()).toEqual(`false;`);
26
+ });
27
+ it("externalIf true", () => {
28
+ expect(Macro.externalIf(true, "true", "false").toString()).toEqual(`true;`);
29
+ });
30
+ it("repeat", () => {
31
+ expect(Macro.attack().repeat().toString()).toEqual(`attack;repeat;`);
32
+ });
33
+ it("repeat message", () => {
34
+ expect(Macro.attack().repeat("mock").toString()).toEqual(`attack;repeat mock;`);
35
+ });
36
+ it("skill", () => {
37
+ const mock = $skill `mock skill`;
38
+ expect(Macro.skill(mock).toString()).toEqual(`skill ${mock.name};`);
39
+ });
40
+ it("trySkill", () => {
41
+ const mock = $skill `mock skill`;
42
+ expect(Macro.trySkill(mock).toString()).toEqual(`if hasskill ${mock.name};skill ${mock.name};endif;`);
43
+ });
44
+ it("trySkillRepeat", () => {
45
+ const mock = $skill `mock skill`;
46
+ expect(Macro.trySkillRepeat(mock).toString()).toEqual(`if hasskill ${mock.name};skill ${mock.name};repeat hasskill ${mock.name};endif;`);
47
+ });
48
+ it("item", () => {
49
+ const mock = $item `mock item`;
50
+ expect(Macro.item(mock).toString()).toEqual(`use ${mock.name};`);
51
+ });
52
+ it("tryItem", () => {
53
+ const mock = $item `mock item`;
54
+ expect(Macro.tryItem(mock).toString()).toEqual(`if hascombatitem mock item;use ${mock.name};endif;`);
55
+ });
56
+ it("attack", () => {
57
+ expect(Macro.attack().toString()).toEqual(`attack;`);
58
+ });
59
+ it.todo("ifHolidayWanderer");
60
+ it.todo("ifNotHolidayWanderer");
61
+ });
62
+ describe(Macro.makeBALLSPredicate, () => {
63
+ it("Monster", () => {
64
+ const mock = $monster `mock monster`;
65
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`monsterid ${mock.id}`);
66
+ });
67
+ it("Monster[]", () => {
68
+ const mockArray = [$monster `mock monster1`, $monster `mock monster2`];
69
+ expect(Macro.makeBALLSPredicate(mockArray)).toEqual(`(monsterid ${mockArray[0].id} || monsterid ${mockArray[1].id})`);
70
+ });
71
+ it("Effect", () => {
72
+ const mock = $effect `mock effect`;
73
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`haseffect ${mock.id}`);
74
+ });
75
+ it("Skill", () => {
76
+ const mock = $skill `mock skill`;
77
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`hasskill ${mock.name}`);
78
+ });
79
+ it("Skill Overlapping", () => {
80
+ const mock = $skill `Thrust-Smack`;
81
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`hasskill ${mock.id}`);
82
+ });
83
+ it("Item", () => {
84
+ const mock = $item `mock item`;
85
+ // @ts-expect-error TypeScript believes that this is readonly
86
+ mock.combat = true;
87
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`hascombatitem ${mock.name}`);
88
+ });
89
+ it("Item Overlapping", () => {
90
+ const mock = $item `spider web`;
91
+ // @ts-expect-error TypeScript believes that this is readonly
92
+ mock.combat = true;
93
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`hascombatitem ${mock.id}`);
94
+ });
95
+ it("Item Invalid", () => {
96
+ const mock = $item `invalid mock item`;
97
+ expect(() => Macro.makeBALLSPredicate(mock)).toThrow(InvalidMacroError);
98
+ });
99
+ it("Location", () => {
100
+ const mock = $location `mock location`;
101
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`snarfblat ${mock.id}`);
102
+ });
103
+ it("Location Invalid", () => {
104
+ const mock = $location `invalid mock location`;
105
+ // @ts-expect-error TypeScript believes that this is readonly
106
+ mock.id = -1;
107
+ expect(() => Macro.makeBALLSPredicate(mock)).toThrow(InvalidMacroError);
108
+ });
109
+ it("Class", () => {
110
+ const mock = $class `Mock Name`;
111
+ // @ts-expect-error TypeScript believes that this is readonly
112
+ mock.id = 1;
113
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`mockname`);
114
+ });
115
+ it("Class Invalid", () => {
116
+ const mock = $class `invalid mock class`;
117
+ expect(() => Macro.makeBALLSPredicate(mock)).toThrow(InvalidMacroError);
118
+ });
119
+ it("Stat", () => {
120
+ const mock = $stat `Mock`;
121
+ expect(Macro.makeBALLSPredicate(mock)).toEqual(`mockclass`);
122
+ });
123
+ it("string", () => {
124
+ expect(Macro.makeBALLSPredicate("mock")).toEqual("mock");
125
+ });
126
+ });
@@ -1,6 +1,6 @@
1
1
  import { Familiar, Item, Skill } from "kolmafia";
2
- import { Macro } from "../combat";
3
- import { Requirement } from "../maximize";
2
+ import { Macro } from "../combat.js";
3
+ import { Requirement } from "../maximize.js";
4
4
  export type FindActionSourceConstraints = {
5
5
  /**
6
6
  * Function returning true if we only accept familiar-based actions.
@@ -1,7 +1,7 @@
1
1
  import { mallPrice, useFamiliar } from "kolmafia";
2
- import { Macro } from "../combat";
3
- import { Requirement } from "../maximize";
4
- import { sum, flat } from "../utils";
2
+ import { Macro } from "../combat.js";
3
+ import { Requirement } from "../maximize.js";
4
+ import { sum, flat } from "../utils.js";
5
5
  /**
6
6
  * Merge a set of constraints into one
7
7
  *
@@ -1,4 +1,4 @@
1
- import { ActionSource, FindActionSourceConstraints } from "./ActionSource";
1
+ import { ActionSource, FindActionSourceConstraints } from "./ActionSource.js";
2
2
  /**
3
3
  * Find an available banish source subject to constraints.
4
4
  *
@@ -1,11 +1,11 @@
1
1
  import { canEquip, cliExecute, myTurncount, restoreMp, retrieveItem, visitUrl, } from "kolmafia";
2
- import { Macro } from "../combat";
3
- import { getFoldGroup, have } from "../lib";
4
- import { Requirement } from "../maximize";
5
- import { get } from "../property";
6
- import * as AsdonMartin from "../resources/2017/AsdonMartin";
7
- import { $item, $items, $skill } from "../template-string";
8
- import { ActionSource, findActionSource, } from "./ActionSource";
2
+ import { Macro } from "../combat.js";
3
+ import { getFoldGroup, have } from "../lib.js";
4
+ import { Requirement } from "../maximize.js";
5
+ import { get } from "../property.js";
6
+ import * as AsdonMartin from "../resources/2017/AsdonMartin.js";
7
+ import { $item, $items, $skill } from "../template-string.js";
8
+ import { ActionSource, findActionSource, } from "./ActionSource.js";
9
9
  // Value of _lastCombatStarted the last time we updated scrapbook charges.
10
10
  let scrapbookChargesLastUpdated = get("_lastCombatStarted");
11
11
  // Free unlimited source every 30 turns.
@@ -1,4 +1,4 @@
1
- import { ActionSource, FindActionSourceConstraints } from "./ActionSource";
1
+ import { ActionSource, FindActionSourceConstraints } from "./ActionSource.js";
2
2
  /**
3
3
  * Find an available free kill source subject to constraints.
4
4
  *
@@ -1,11 +1,11 @@
1
1
  import { canEquip, myLightning, restoreMp, retrieveItem, use } from "kolmafia";
2
- import { Macro } from "../combat";
3
- import { have } from "../lib";
4
- import { Requirement } from "../maximize";
5
- import { get } from "../property";
6
- import * as AsdonMartin from "../resources/2017/AsdonMartin";
7
- import { $familiar, $item, $items, $skill } from "../template-string";
8
- import { ActionSource, findActionSource, } from "./ActionSource";
2
+ import { Macro } from "../combat.js";
3
+ import { have } from "../lib.js";
4
+ import { Requirement } from "../maximize.js";
5
+ import { get } from "../property.js";
6
+ import * as AsdonMartin from "../resources/2017/AsdonMartin.js";
7
+ import { $familiar, $item, $items, $skill } from "../template-string.js";
8
+ import { ActionSource, findActionSource, } from "./ActionSource.js";
9
9
  const freeKillSources = [
10
10
  // Free limited sources
11
11
  new ActionSource($skill `Gingerbread Mob Hit`, () => !get("_gingerbreadMobHitUsed") && have($skill `Gingerbread Mob Hit`)
@@ -1,4 +1,4 @@
1
- import { ActionSource, FindActionSourceConstraints } from "./ActionSource";
1
+ import { ActionSource, FindActionSourceConstraints } from "./ActionSource.js";
2
2
  /**
3
3
  * Find an available free run source subject to constraints.
4
4
  *
@@ -1,12 +1,12 @@
1
1
  import { retrieveItem } from "kolmafia";
2
- import { Macro } from "../combat";
3
- import { ensureEffect, getSongCount, getSongLimit, have } from "../lib";
4
- import { Requirement } from "../maximize";
5
- import { get } from "../property";
6
- import * as Bandersnatch from "../resources/2009/Bandersnatch";
7
- import * as StompingBoots from "../resources/2011/StompingBoots";
8
- import { $effect, $familiar, $item, $items, $skill } from "../template-string";
9
- import { ActionSource, findActionSource, } from "./ActionSource";
2
+ import { Macro } from "../combat.js";
3
+ import { ensureEffect, getSongCount, getSongLimit, have } from "../lib.js";
4
+ import { Requirement } from "../maximize.js";
5
+ import { get } from "../property.js";
6
+ import * as Bandersnatch from "../resources/2009/Bandersnatch.js";
7
+ import * as StompingBoots from "../resources/2011/StompingBoots.js";
8
+ import { $effect, $familiar, $item, $items, $skill, } from "../template-string.js";
9
+ import { ActionSource, findActionSource, } from "./ActionSource.js";
10
10
  const everythingLooksGreen = (otherClause = () => true) => () => otherClause() && !have($effect `Everything Looks Green`) ? 1 : 0;
11
11
  const freeRunSources = [
12
12
  // Free unlimited source
@@ -1,4 +1,4 @@
1
- export * from "./ActionSource";
2
- export * from "./Banish";
3
- export * from "./FreeKill";
4
- export * from "./FreeRun";
1
+ export * from "./ActionSource.js";
2
+ export * from "./Banish.js";
3
+ export * from "./FreeKill.js";
4
+ export * from "./FreeRun.js";
@@ -1,4 +1,4 @@
1
- export * from "./ActionSource";
2
- export * from "./Banish";
3
- export * from "./FreeKill";
4
- export * from "./FreeRun";
1
+ export * from "./ActionSource.js";
2
+ export * from "./Banish.js";
3
+ export * from "./FreeKill.js";
4
+ export * from "./FreeRun.js";
package/dist/ascend.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Skill, Class, Item, Path, MafiaClass } from "kolmafia";
2
- import { MoonSign } from "./moonSign";
3
- import { ChateauMantegna } from "./resources";
2
+ import { MoonSign } from "./moonSign.js";
3
+ import { ChateauMantegna } from "./resources/index.js";
4
4
  export declare enum Lifestyle {
5
5
  casual = 1,
6
6
  softcore = 2,
package/dist/ascend.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { eudoraItem, getCampground, Item, Path, use, visitUrl, xpath, haveSkill, getPermedSkills, toSkill, } from "kolmafia";
2
- import { signNameToId } from "./moonSign";
3
- import { get } from "./property";
4
- import { ChateauMantegna } from "./resources";
5
- import { $item, $items, $stat } from "./template-string";
6
- import { arrayContains, tc } from "./utils";
2
+ import { signNameToId } from "./moonSign.js";
3
+ import { get } from "./property.js";
4
+ import { ChateauMantegna } from "./resources/index.js";
5
+ import { $item, $items, $stat } from "./template-string.js";
6
+ import { arrayContains, tc } from "./utils.js";
7
7
  export var Lifestyle;
8
8
  (function (Lifestyle) {
9
9
  Lifestyle[Lifestyle["casual"] = 1] = "casual";
@@ -1,7 +1,7 @@
1
1
  import { Modifier, Monster, monsterFactoidsAvailable, myRain, numericModifier, useSkill, visitUrl, } from "kolmafia";
2
- import { have } from "../../lib";
3
- import { withChoice } from "../../property";
4
- import { $monster, $path, $skill } from "../../template-string";
2
+ import { have } from "../../lib.js";
3
+ import { withChoice } from "../../property.js";
4
+ import { $monster, $path, $skill } from "../../template-string.js";
5
5
  /**
6
6
  * Cast Rain Man and fight the target monster
7
7
  * @param target the monster to fight
@@ -1,5 +1,5 @@
1
1
  import { Effect } from "kolmafia";
2
- import { Requirement } from "../../maximize";
2
+ import { Requirement } from "../../maximize.js";
3
3
  export default class CommunityService {
4
4
  private choice;
5
5
  private stat;
@@ -1,10 +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
- import { have } from "../../lib";
3
- import { Requirement } from "../../maximize";
4
- import { get } from "../../property";
5
- import { MummingTrunk } from "../../resources";
6
- import { $effect, $familiar, $item, $items, $path, $slot, $stat, $thrall, } from "../../template-string";
7
- import { clamp, sum } from "../../utils";
2
+ import { have } from "../../lib.js";
3
+ import { Requirement } from "../../maximize.js";
4
+ import { get } from "../../property.js";
5
+ import { MummingTrunk } from "../../resources/index.js";
6
+ import { $effect, $familiar, $item, $items, $path, $slot, $stat, $thrall, } from "../../template-string.js";
7
+ import { clamp, sum } from "../../utils.js";
8
8
  const thralls = new Map([
9
9
  [$stat `muscle`, $thrall `Elbow Macaroni`],
10
10
  [$stat `moxie`, $thrall `Penne Dreadful`],
@@ -1,5 +1,5 @@
1
1
  import { visitUrl } from "kolmafia";
2
- import { $path } from "../../template-string";
2
+ import { $path } from "../../template-string.js";
3
3
  /**
4
4
  * Visits the Cooling Tank on level 8 of the Fallout shelter to gain 300 rads
5
5
  */
@@ -1,4 +1,4 @@
1
- import * as HeavyRains from "./2014/HeavyRains";
2
- import CommunityService from "./2015/CommunityService";
3
- import * as NuclearAutumn from "./2016/NuclearAutumn";
1
+ import * as HeavyRains from "./2014/HeavyRains.js";
2
+ import CommunityService from "./2015/CommunityService.js";
3
+ import * as NuclearAutumn from "./2016/NuclearAutumn.js";
4
4
  export { CommunityService, NuclearAutumn, HeavyRains };
@@ -1,4 +1,4 @@
1
- import * as HeavyRains from "./2014/HeavyRains";
2
- import CommunityService from "./2015/CommunityService";
3
- import * as NuclearAutumn from "./2016/NuclearAutumn";
1
+ import * as HeavyRains from "./2014/HeavyRains.js";
2
+ import CommunityService from "./2015/CommunityService.js";
3
+ import * as NuclearAutumn from "./2016/NuclearAutumn.js";
4
4
  export { CommunityService, NuclearAutumn, HeavyRains };
package/dist/combat.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { adv1, choiceFollowsFight, Class, Effect, getAutoAttack, inMultiFight, Item, Location, Monster, removeProperty, runCombat, setAutoAttack, Skill, Stat, urlEncode, visitUrl, xpath, } from "kolmafia";
2
- import { getTodaysHolidayWanderers } from "./lib";
3
- import { overlappingItemNames, overlappingSkillNames, } from "./overlappingNames";
4
- import { get, set } from "./property";
2
+ import { getTodaysHolidayWanderers } from "./lib.js";
3
+ import { overlappingItemNames, overlappingSkillNames, } from "./overlappingNames.js";
4
+ import { get, set } from "./property.js";
5
5
  const MACRO_NAME = "Script Autoattack Macro";
6
6
  /**
7
7
  * Get the KoL native ID of the macro with name name.
@@ -442,8 +442,10 @@ export class Macro {
442
442
  * @returns {Macro} This object itself.
443
443
  */
444
444
  trySkill(...skills) {
445
- return this.step(...skills.map((skill) => {
446
- return Macro.if_(`hasskill ${skillBallsMacroName(skill)}`, Macro.skill(skill));
445
+ return this.step(...skills
446
+ .map((skillOrName) => skillOrNameToSkill(skillOrName))
447
+ .map((skill) => {
448
+ return Macro.if_(Macro.makeBALLSPredicate(skill), Macro.skill(skill));
447
449
  }));
448
450
  }
449
451
  /**
@@ -505,7 +507,7 @@ export class Macro {
505
507
  */
506
508
  tryItem(...items) {
507
509
  return this.step(...items.map((item) => {
508
- return Macro.if_(itemOrItemsBallsMacroPredicate(item), `use ${itemOrItemsBallsMacroName(item)}`);
510
+ return Macro.if_(itemOrItemsBallsMacroPredicate(item), Macro.item(item));
509
511
  }));
510
512
  }
511
513
  /**
@@ -1,11 +1,11 @@
1
1
  import { canEquip, fullnessLimit, historicalAge, historicalPrice, inebrietyLimit, itemType, mallPrice, mallPrices, myFullness, myInebriety, myLevel, myPrimestat, mySpleenUse, npcPrice, spleenLimit, } from "kolmafia";
2
- import { have } from "../lib";
3
- import { get as getModifier } from "../modifier";
4
- import { get } from "../property";
5
- import { Mayo, installed as mayoInstalled } from "../resources/2015/MayoClinic";
6
- import { $effect, $item, $items, $skill, $stat } from "../template-string";
7
- import { notNullish, sum } from "../utils";
8
- import { knapsack } from "./knapsack";
2
+ import { have } from "../lib.js";
3
+ import { get as getModifier } from "../modifier.js";
4
+ import { get } from "../property.js";
5
+ import { Mayo, installed as mayoInstalled, } from "../resources/2015/MayoClinic.js";
6
+ import { $effect, $item, $items, $skill, $stat } from "../template-string.js";
7
+ import { notNullish, sum } from "../utils.js";
8
+ import { knapsack } from "./knapsack.js";
9
9
  function isMonday() {
10
10
  // Checking Tuesday's ruby is a hack to see if it's Monday in Arizona.
11
11
  return getModifier("Muscle Percent", $item `Tuesday's ruby`) > 0;
@@ -31,6 +31,7 @@ function expectedAdventures(item, modifiers) {
31
31
  ? 1.5
32
32
  : 1.3;
33
33
  const seasoningAdventures = max - min <= 1 ? 1 : 0.5;
34
+ const aioliAdventures = item.fullness;
34
35
  const garish = modifiers.garish && item.notes?.includes("LASAGNA") && !isMonday();
35
36
  const refinedPalate = modifiers.refinedPalate && item.notes?.includes("WINE");
36
37
  const pinkyRing = modifiers.pinkyRing && item.notes?.includes("WINE");
@@ -55,6 +56,8 @@ function expectedAdventures(item, modifiers) {
55
56
  adventures++;
56
57
  if (itemType(item) === "food" && modifiers.seasoning)
57
58
  adventures += seasoningAdventures;
59
+ if (itemType(item) === "food" && modifiers.aioli)
60
+ adventures += aioliAdventures;
58
61
  if (itemType(item) === "food" && modifiers.whetStone)
59
62
  adventures++;
60
63
  return adventures;
@@ -234,6 +237,7 @@ class DietPlanner {
234
237
  mug;
235
238
  seasoning;
236
239
  whetStone;
240
+ aioli;
237
241
  spleenValue = 0;
238
242
  constructor(mpa, menu) {
239
243
  this.mpa = mpa;
@@ -249,6 +253,9 @@ class DietPlanner {
249
253
  const whetStone = menu.find((item) => item.item === $item `whet stone`);
250
254
  if (whetStone)
251
255
  this.whetStone = whetStone;
256
+ const aioli = menu.find((item) => item.item === $item `mini kiwi aioli`);
257
+ if (aioli)
258
+ this.aioli = aioli;
252
259
  this.mayoLookup = new Map();
253
260
  if (mayoInstalled()) {
254
261
  for (const mayo of [Mayo.flex, Mayo.zapine]) {
@@ -305,6 +312,7 @@ class DietPlanner {
305
312
  forkMug: false,
306
313
  seasoning: this.seasoning ? helpers.includes(this.seasoning) : false,
307
314
  whetStone: this.whetStone ? helpers.includes(this.whetStone) : false,
315
+ aioli: this.aioli ? helpers.includes(this.aioli) : false,
308
316
  mayoflex: this.mayoLookup.size
309
317
  ? helpers.some((item) => item.item === Mayo.flex)
310
318
  : false,
@@ -326,14 +334,19 @@ class DietPlanner {
326
334
  ...defaultModifiers,
327
335
  seasoning: false,
328
336
  })) >
329
- mallPrice($item `Special Seasoning`)) {
337
+ this.seasoning.price()) {
330
338
  helpers.push(this.seasoning);
331
339
  }
332
340
  if (this.whetStone &&
333
341
  itemType(menuItem.item) === "food" &&
334
- this.mpa > mallPrice($item `whet stone`)) {
342
+ this.mpa > this.whetStone.price()) {
335
343
  helpers.push(this.whetStone);
336
344
  }
345
+ if (this.aioli &&
346
+ itemType(menuItem.item) === "food" &&
347
+ this.mpa * menuItem.item.fullness > this.aioli.price()) {
348
+ helpers.push(this.aioli);
349
+ }
337
350
  const forkMug = itemType(menuItem.item) === "food"
338
351
  ? this.fork
339
352
  : itemType(menuItem.item) === "booze"
@@ -590,6 +603,7 @@ class DietEntry {
590
603
  forkMug: fork || mug,
591
604
  seasoning: items.includes($item `Special Seasoning`),
592
605
  whetStone: items.includes($item `whet stone`),
606
+ aioli: items.includes($item `mini kiwi aioli`),
593
607
  mayoflex: items.includes(Mayo.flex),
594
608
  refinedPalate: diet.refinedPalate,
595
609
  garish: diet.garish,
@@ -1,4 +1,4 @@
1
- import { sum } from "../utils";
1
+ import { sum } from "../utils.js";
2
2
  class Not {
3
3
  thing;
4
4
  constructor(thing) {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,77 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { knapsack } from "./knapsack.js";
3
+ function sortValues(items) {
4
+ return items.sort(([x], [y]) => (x < y ? -1 : x === y ? 0 : 1));
5
+ }
6
+ describe("knapsack", () => {
7
+ it("selects better items", () => {
8
+ const [value, items] = knapsack([
9
+ ["A", 1, 1],
10
+ ["B", 3, 2],
11
+ ], 4);
12
+ expect(sortValues(items)).toEqual([["B", 2]]);
13
+ expect(value).toEqual(6);
14
+ });
15
+ it("beats greedy", () => {
16
+ // Greedy would select CCC then A (25), but CCB (26) is better.
17
+ const [value, items] = knapsack([
18
+ ["A", 1, 1],
19
+ ["B", 10, 3],
20
+ ["C", 8, 2],
21
+ ], 7);
22
+ expect(sortValues(items)).toEqual([
23
+ ["B", 1],
24
+ ["C", 2],
25
+ ]);
26
+ expect(value).toEqual(26);
27
+ });
28
+ it("doesn't overfill", () => {
29
+ const [value, items] = knapsack([
30
+ ["A", 2, 2],
31
+ ["B", 2, 4],
32
+ ], 5);
33
+ expect(sortValues(items)).toEqual([["A", 2]]);
34
+ expect(value).toEqual(4);
35
+ });
36
+ it("respects maximum quantity", () => {
37
+ const [value, items] = knapsack([
38
+ ["A", 10, 1, 1],
39
+ ["B", 1, 2],
40
+ ], 5);
41
+ expect(sortValues(items)).toEqual([
42
+ ["A", 1],
43
+ ["B", 2],
44
+ ]);
45
+ expect(value).toEqual(12);
46
+ });
47
+ it("respects zero maximum quantity", () => {
48
+ const [value, items] = knapsack([
49
+ ["A", 10, 1, 0],
50
+ ["B", 1, 2],
51
+ ], 4);
52
+ expect(sortValues(items)).toEqual([["B", 2]]);
53
+ expect(value).toEqual(2);
54
+ });
55
+ it("uses negative items", () => {
56
+ const [value, items] = knapsack([
57
+ ["A", 1, 1],
58
+ ["B", 0, -1, 1],
59
+ ], 2);
60
+ expect(sortValues(items)).toEqual([
61
+ ["A", 3],
62
+ ["B", 1],
63
+ ]);
64
+ expect(value).toEqual(3);
65
+ });
66
+ it("uses negative items with cost", () => {
67
+ const [value, items] = knapsack([
68
+ ["A", 2, 1],
69
+ ["B", -1, -1, 1],
70
+ ], 2);
71
+ expect(sortValues(items)).toEqual([
72
+ ["A", 3],
73
+ ["B", 1],
74
+ ]);
75
+ expect(value).toEqual(5);
76
+ });
77
+ });