libram 0.8.28 → 0.8.29

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 (195) hide show
  1. package/dist/Clan.d.ts +128 -0
  2. package/dist/Clan.js +300 -0
  3. package/dist/Copier.d.ts +9 -0
  4. package/dist/Copier.js +15 -0
  5. package/dist/Dungeon.d.ts +45 -0
  6. package/dist/Dungeon.js +115 -0
  7. package/dist/Kmail.d.ts +133 -0
  8. package/dist/Kmail.js +259 -0
  9. package/dist/actions/ActionSource.d.ts +131 -0
  10. package/dist/actions/ActionSource.js +178 -0
  11. package/dist/actions/Banish.d.ts +16 -0
  12. package/dist/actions/Banish.js +121 -0
  13. package/dist/actions/FreeKill.d.ts +16 -0
  14. package/dist/actions/FreeKill.js +94 -0
  15. package/dist/actions/FreeRun.d.ts +16 -0
  16. package/dist/actions/FreeRun.js +81 -0
  17. package/dist/actions/index.d.ts +4 -0
  18. package/dist/actions/index.js +4 -0
  19. package/dist/ascend.d.ts +83 -0
  20. package/dist/ascend.js +268 -0
  21. package/dist/challengePaths/2014/HeavyRains.d.ts +22 -0
  22. package/dist/challengePaths/2014/HeavyRains.js +75 -0
  23. package/dist/challengePaths/2015/CommunityService.d.ts +125 -0
  24. package/dist/challengePaths/2015/CommunityService.js +334 -0
  25. package/dist/challengePaths/2016/NuclearAutumn.d.ts +13 -0
  26. package/dist/challengePaths/2016/NuclearAutumn.js +21 -0
  27. package/dist/challengePaths/index.d.ts +4 -0
  28. package/dist/challengePaths/index.js +4 -0
  29. package/dist/combat.d.ts +414 -0
  30. package/dist/combat.js +711 -0
  31. package/dist/console.d.ts +12 -0
  32. package/dist/console.js +14 -0
  33. package/dist/counter.d.ts +22 -0
  34. package/dist/counter.js +37 -0
  35. package/dist/diet/index.d.ts +80 -0
  36. package/dist/diet/index.js +680 -0
  37. package/dist/diet/knapsack.d.ts +8 -0
  38. package/dist/diet/knapsack.js +128 -0
  39. package/dist/index.d.ts +29 -0
  40. package/dist/index.js +26 -0
  41. package/dist/lib.d.ts +507 -0
  42. package/dist/lib.js +970 -0
  43. package/dist/logger.d.ts +35 -0
  44. package/dist/logger.js +62 -0
  45. package/dist/maximize.d.ts +122 -0
  46. package/dist/maximize.js +531 -0
  47. package/dist/modifier.d.ts +41 -0
  48. package/dist/modifier.js +160 -0
  49. package/dist/modifierTypes.d.ts +16 -0
  50. package/dist/modifierTypes.js +9 -0
  51. package/dist/mood.d.ts +105 -0
  52. package/dist/mood.js +349 -0
  53. package/dist/moonSign.d.ts +13 -0
  54. package/dist/moonSign.js +25 -0
  55. package/dist/overlappingNames.d.ts +3 -0
  56. package/dist/overlappingNames.js +42 -0
  57. package/dist/property.d.ts +222 -0
  58. package/dist/property.js +385 -0
  59. package/dist/propertyTypes.d.ts +19 -0
  60. package/dist/propertyTypes.js +10 -0
  61. package/dist/propertyTyping.d.ts +65 -0
  62. package/dist/propertyTyping.js +91 -0
  63. package/dist/resources/2007/CandyHearts.d.ts +9 -0
  64. package/dist/resources/2007/CandyHearts.js +24 -0
  65. package/dist/resources/2008/DivineFavors.d.ts +9 -0
  66. package/dist/resources/2008/DivineFavors.js +27 -0
  67. package/dist/resources/2008/Stickers.d.ts +49 -0
  68. package/dist/resources/2008/Stickers.js +84 -0
  69. package/dist/resources/2009/Bandersnatch.d.ts +56 -0
  70. package/dist/resources/2009/Bandersnatch.js +93 -0
  71. package/dist/resources/2009/LoveSongs.d.ts +9 -0
  72. package/dist/resources/2009/LoveSongs.js +24 -0
  73. package/dist/resources/2009/SpookyPutty.d.ts +31 -0
  74. package/dist/resources/2009/SpookyPutty.js +49 -0
  75. package/dist/resources/2010/Brickos.d.ts +9 -0
  76. package/dist/resources/2010/Brickos.js +21 -0
  77. package/dist/resources/2010/CrownOfThrones.d.ts +68 -0
  78. package/dist/resources/2010/CrownOfThrones.js +418 -0
  79. package/dist/resources/2010/LookingGlass.d.ts +29 -0
  80. package/dist/resources/2010/LookingGlass.js +89 -0
  81. package/dist/resources/2011/Gygaxian.d.ts +9 -0
  82. package/dist/resources/2011/Gygaxian.js +24 -0
  83. package/dist/resources/2011/ObtuseAngel.d.ts +33 -0
  84. package/dist/resources/2011/ObtuseAngel.js +51 -0
  85. package/dist/resources/2011/StompingBoots.d.ts +37 -0
  86. package/dist/resources/2011/StompingBoots.js +57 -0
  87. package/dist/resources/2012/RainDoh.d.ts +25 -0
  88. package/dist/resources/2012/RainDoh.js +37 -0
  89. package/dist/resources/2012/ReagnimatedGnome.d.ts +31 -0
  90. package/dist/resources/2012/ReagnimatedGnome.js +46 -0
  91. package/dist/resources/2012/Resolutions.d.ts +9 -0
  92. package/dist/resources/2012/Resolutions.js +28 -0
  93. package/dist/resources/2013/Florist.d.ts +81 -0
  94. package/dist/resources/2013/Florist.js +245 -0
  95. package/dist/resources/2013/JungMan.d.ts +33 -0
  96. package/dist/resources/2013/JungMan.js +69 -0
  97. package/dist/resources/2013/PulledTaffy.d.ts +9 -0
  98. package/dist/resources/2013/PulledTaffy.js +33 -0
  99. package/dist/resources/2014/CrimboShrub.d.ts +42 -0
  100. package/dist/resources/2014/CrimboShrub.js +89 -0
  101. package/dist/resources/2014/DNALab.d.ts +56 -0
  102. package/dist/resources/2014/DNALab.js +162 -0
  103. package/dist/resources/2014/WinterGarden.d.ts +23 -0
  104. package/dist/resources/2014/WinterGarden.js +35 -0
  105. package/dist/resources/2015/BarrelShrine.d.ts +8 -0
  106. package/dist/resources/2015/BarrelShrine.js +25 -0
  107. package/dist/resources/2015/ChateauMantegna.d.ts +52 -0
  108. package/dist/resources/2015/ChateauMantegna.js +99 -0
  109. package/dist/resources/2015/DeckOfEveryCard.d.ts +29 -0
  110. package/dist/resources/2015/DeckOfEveryCard.js +122 -0
  111. package/dist/resources/2015/Dinseylandfill.d.ts +89 -0
  112. package/dist/resources/2015/Dinseylandfill.js +205 -0
  113. package/dist/resources/2015/MayoClinic.d.ts +23 -0
  114. package/dist/resources/2015/MayoClinic.js +49 -0
  115. package/dist/resources/2016/GingerBread.d.ts +32 -0
  116. package/dist/resources/2016/GingerBread.js +73 -0
  117. package/dist/resources/2016/SourceTerminal.d.ts +181 -0
  118. package/dist/resources/2016/SourceTerminal.js +275 -0
  119. package/dist/resources/2016/Witchess.d.ts +17 -0
  120. package/dist/resources/2016/Witchess.js +47 -0
  121. package/dist/resources/2017/AsdonMartin.d.ts +59 -0
  122. package/dist/resources/2017/AsdonMartin.js +238 -0
  123. package/dist/resources/2017/Horsery.d.ts +19 -0
  124. package/dist/resources/2017/Horsery.js +42 -0
  125. package/dist/resources/2017/MummingTrunk.d.ts +8 -0
  126. package/dist/resources/2017/MummingTrunk.js +33 -0
  127. package/dist/resources/2017/Pantogram.d.ts +92 -0
  128. package/dist/resources/2017/Pantogram.js +174 -0
  129. package/dist/resources/2017/Robortender.d.ts +30 -0
  130. package/dist/resources/2017/Robortender.js +90 -0
  131. package/dist/resources/2017/Spacegate.d.ts +86 -0
  132. package/dist/resources/2017/Spacegate.js +178 -0
  133. package/dist/resources/2017/TunnelOfLove.d.ts +39 -0
  134. package/dist/resources/2017/TunnelOfLove.js +120 -0
  135. package/dist/resources/2018/LatteLoversMembersMug.d.ts +392 -0
  136. package/dist/resources/2018/LatteLoversMembersMug.js +303 -0
  137. package/dist/resources/2018/SongBoom.d.ts +33 -0
  138. package/dist/resources/2018/SongBoom.js +55 -0
  139. package/dist/resources/2019/BeachComb.d.ts +72 -0
  140. package/dist/resources/2019/BeachComb.js +118 -0
  141. package/dist/resources/2019/CampAway.d.ts +39 -0
  142. package/dist/resources/2019/CampAway.js +72 -0
  143. package/dist/resources/2019/Snapper.d.ts +33 -0
  144. package/dist/resources/2019/Snapper.js +73 -0
  145. package/dist/resources/2020/Cartography.d.ts +16 -0
  146. package/dist/resources/2020/Cartography.js +48 -0
  147. package/dist/resources/2020/Guzzlr.d.ts +160 -0
  148. package/dist/resources/2020/Guzzlr.js +275 -0
  149. package/dist/resources/2020/RetroCape.d.ts +51 -0
  150. package/dist/resources/2020/RetroCape.js +115 -0
  151. package/dist/resources/2021/CrystalBall.d.ts +14 -0
  152. package/dist/resources/2021/CrystalBall.js +41 -0
  153. package/dist/resources/2021/DaylightShavings.d.ts +40 -0
  154. package/dist/resources/2021/DaylightShavings.js +74 -0
  155. package/dist/resources/2022/AutumnAton.d.ts +78 -0
  156. package/dist/resources/2022/AutumnAton.js +182 -0
  157. package/dist/resources/2022/CombatLoversLocket.d.ts +44 -0
  158. package/dist/resources/2022/CombatLoversLocket.js +82 -0
  159. package/dist/resources/2022/GreyGoose.d.ts +59 -0
  160. package/dist/resources/2022/GreyGoose.js +90 -0
  161. package/dist/resources/2022/JuneCleaver.d.ts +47 -0
  162. package/dist/resources/2022/JuneCleaver.js +69 -0
  163. package/dist/resources/2022/TrainSet.d.ts +146 -0
  164. package/dist/resources/2022/TrainSet.js +228 -0
  165. package/dist/resources/2023/AugustScepter.d.ts +25 -0
  166. package/dist/resources/2023/AugustScepter.js +40 -0
  167. package/dist/resources/2023/BurningLeaves.d.ts +25 -0
  168. package/dist/resources/2023/BurningLeaves.js +74 -0
  169. package/dist/resources/2023/CinchoDeMayo.d.ts +25 -0
  170. package/dist/resources/2023/CinchoDeMayo.js +45 -0
  171. package/dist/resources/2023/ClosedCircuitPayphone.d.ts +80 -0
  172. package/dist/resources/2023/ClosedCircuitPayphone.js +129 -0
  173. package/dist/resources/2023/CursedMonkeyPaw.d.ts +46 -0
  174. package/dist/resources/2023/CursedMonkeyPaw.js +113 -0
  175. package/dist/resources/2024/AprilingBandHelmet.d.ts +57 -0
  176. package/dist/resources/2024/AprilingBandHelmet.js +118 -0
  177. package/dist/resources/2024/ChestMimic.d.ts +42 -0
  178. package/dist/resources/2024/ChestMimic.js +125 -0
  179. package/dist/resources/LibramSummon.d.ts +18 -0
  180. package/dist/resources/LibramSummon.js +74 -0
  181. package/dist/resources/index.d.ts +54 -0
  182. package/dist/resources/index.js +54 -0
  183. package/dist/resources/putty-likes.d.ts +21 -0
  184. package/dist/resources/putty-likes.js +33 -0
  185. package/dist/session.d.ts +169 -0
  186. package/dist/session.js +284 -0
  187. package/dist/since.d.ts +51 -0
  188. package/dist/since.js +108 -0
  189. package/dist/template-string.d.ts +324 -0
  190. package/dist/template-string.js +265 -0
  191. package/dist/url.d.ts +35 -0
  192. package/dist/url.js +67 -0
  193. package/dist/utils.d.ts +178 -0
  194. package/dist/utils.js +255 -0
  195. package/package.json +2 -2
package/dist/ascend.js ADDED
@@ -0,0 +1,268 @@
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";
7
+ export var Lifestyle;
8
+ (function (Lifestyle) {
9
+ Lifestyle[Lifestyle["casual"] = 1] = "casual";
10
+ Lifestyle[Lifestyle["softcore"] = 2] = "softcore";
11
+ Lifestyle[Lifestyle["normal"] = 2] = "normal";
12
+ Lifestyle[Lifestyle["hardcore"] = 3] = "hardcore";
13
+ })(Lifestyle || (Lifestyle = {}));
14
+ export var KolGender;
15
+ (function (KolGender) {
16
+ KolGender[KolGender["male"] = 1] = "male";
17
+ KolGender[KolGender["female"] = 2] = "female";
18
+ })(KolGender || (KolGender = {}));
19
+ /**
20
+ * Get a mapping of permed skills to the extent to which they're permed.
21
+ *
22
+ * If a skill is not permed at all, it will not appear in the mapping.
23
+ *
24
+ * @returns Permed skills mapping
25
+ */
26
+ export function permedSkills() {
27
+ return new Map(Array.from(Object.entries(getPermedSkills())).map(([skillName, isHardcore]) => [
28
+ toSkill(skillName),
29
+ isHardcore ? Lifestyle.hardcore : Lifestyle.softcore,
30
+ ]));
31
+ }
32
+ export class AscendError extends Error {
33
+ }
34
+ const gardens = [
35
+ "packet of pumpkin seeds",
36
+ "Peppermint Pip Packet",
37
+ "packet of dragon's teeth",
38
+ "packet of beer seeds",
39
+ "packet of winter seeds",
40
+ "packet of thanksgarden seeds",
41
+ "packet of tall grass seeds",
42
+ "packet of mushroom spores",
43
+ "packet of rock seeds",
44
+ ];
45
+ const eudorae = [
46
+ "My Own Pen Pal kit",
47
+ "GameInformPowerDailyPro subscription card",
48
+ "Xi Receiver Unit",
49
+ "New-You Club Membership Form",
50
+ "Our Daily Candles™ order form",
51
+ ];
52
+ const isGarden = (x) => arrayContains(x, gardens);
53
+ const isEudora = (x) => arrayContains(x, eudorae);
54
+ const isDesk = (x) => arrayContains(x, ChateauMantegna.desks);
55
+ const isNightstand = (x) => arrayContains(x, ChateauMantegna.nightstands);
56
+ const isCeiling = (x) => arrayContains(x, ChateauMantegna.ceilings);
57
+ export class AscensionPrepError extends Error {
58
+ cause;
59
+ constructor(cause, original) {
60
+ if (isGarden(cause)) {
61
+ super(`Unable to swap garden to ${cause}; garden is currently ${original}.`);
62
+ }
63
+ else if (isEudora(cause)) {
64
+ super(`Unable to swap eudora to ${cause}; eudora is currently ${original}.`);
65
+ }
66
+ else if (isDesk(cause)) {
67
+ super(`Unable to swap chateau desk to ${cause}; desk is currently ${original}.`);
68
+ }
69
+ else if (isNightstand(cause)) {
70
+ super(`Unable to swap chateau nightstand to ${cause}; nightstand is currently ${original}.`);
71
+ }
72
+ else if (isCeiling(cause)) {
73
+ super(`Unable to swap chateau ceiling to ${cause}; ceiling is currently ${original}.`);
74
+ }
75
+ else
76
+ super(cause);
77
+ this.cause = cause;
78
+ }
79
+ }
80
+ /**
81
+ * Determine the id of the appropriate moon sign.
82
+ *
83
+ * @param moon Either a moon sign or the desired unlocked zone name
84
+ * @param playerClass Class, required for working out a moon sign based on the desired zone
85
+ * @returns Moon sign id
86
+ */
87
+ function inputToMoonId(moon, playerClass) {
88
+ if (typeof moon === "number")
89
+ return moon;
90
+ const offset = () => {
91
+ switch (playerClass.primestat) {
92
+ case $stat `Muscle`:
93
+ return 0;
94
+ case $stat `Mysticality`:
95
+ return 1;
96
+ case $stat `Moxie`:
97
+ return 2;
98
+ default:
99
+ throw new AscendError(`unknown prime stat for ${playerClass}`);
100
+ }
101
+ };
102
+ const fromNormalInput = signNameToId(tc(moon));
103
+ if (fromNormalInput > 0)
104
+ return fromNormalInput;
105
+ switch (moon.toLowerCase()) {
106
+ case "degrassi":
107
+ case "degrassi knoll":
108
+ case "friendly degrassi knoll":
109
+ case "knoll":
110
+ return 1 + offset();
111
+ case "canada":
112
+ case "canadia":
113
+ case "little canadia":
114
+ return 4 + offset();
115
+ case "gnomads":
116
+ case "gnomish":
117
+ case "gnomish gnomads camp":
118
+ return 7 + offset();
119
+ default:
120
+ throw new AscendError("Invalid moon sign!");
121
+ }
122
+ }
123
+ /**
124
+ * Determine if player is currently in Valhalla
125
+ *
126
+ * @returns Whether player is in Valhalla
127
+ */
128
+ function isInValhalla() {
129
+ const charPaneText = visitUrl("charpane.php");
130
+ // Match the infinity images (inf_small.gif, inf_large.gif)
131
+ // At time of writing, the full img tag used is:
132
+ // <img src="https://d2uyhvukfffg5a.cloudfront.net/otherimages/inf_small.gif">
133
+ const matches = charPaneText.match(/<img src="[^"]*\/otherimages\/inf_\w+\.gif">/);
134
+ return matches !== null;
135
+ }
136
+ /**
137
+ * Hops the gash, perming no skills by default
138
+ *
139
+ * @param options Configuration for the ascension
140
+ * @param options.path Your path of choice for this ascension
141
+ * @param options.playerClass Your class of choice for this ascension
142
+ * @param options.lifestyle 1 for casual, 2 for softcore, 3 for hardcore. Alternately, use the Lifestyle enum
143
+ * @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')
144
+ * @param options.moon Your moon sign as a string, or the zone you're looking for as a string
145
+ * @param options.consumable From the astral deli. Pick the container item, not the product. Defaults to astral six-pack, provide $item`none` for nothing.
146
+ * @param options.pet From the astral pet store.
147
+ * @param options.permOptions Options for perming during a player's stay in Valhalla
148
+ * @param options.permOptions.permSkills A Map<Skill, Lifestyle> of skills you'd like to perm, ordered by priority.
149
+ * @param options.permOptions.neverAbort Whether the ascension should abort on failure
150
+ */
151
+ export function ascend(options) {
152
+ const DEFAULT_OPTIONS = {
153
+ kolGender: get("defaultGenderOverride", "female") === "male"
154
+ ? KolGender.male
155
+ : KolGender.female,
156
+ consumable: $item `astral six-pack`,
157
+ pet: $item `none`,
158
+ };
159
+ const prunedOptions = Object.fromEntries(Object.entries(options).filter(([, value]) => value));
160
+ const { path, playerClass, lifestyle, kolGender, moon, consumable, pet, permOptions, } = { ...DEFAULT_OPTIONS, ...prunedOptions };
161
+ if (playerClass.path !== (path.avatar ? path : Path.none)) {
162
+ throw new AscendError(`Invalid class ${playerClass} for this path!`);
163
+ }
164
+ if (path.id < 0)
165
+ throw new AscendError(`Invalid path: ${path}!`);
166
+ const moonId = inputToMoonId(moon, playerClass);
167
+ if (moonId < 1 || moonId > 9)
168
+ throw new Error(`Invalid moon ${moon}`);
169
+ if (!$items `none, astral six-pack, astral hot dog dinner, [10882]carton of astral energy drinks`.includes(consumable)) {
170
+ throw new AscendError(`Invalid astral consumable: ${consumable}`);
171
+ }
172
+ 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)) {
173
+ throw new AscendError(`Invalid astral pet: ${pet}`);
174
+ }
175
+ const unownedSkills = [...(permOptions?.permSkills.keys() ?? [])].filter((skill) => !haveSkill(skill));
176
+ if (unownedSkills.length) {
177
+ throw new AscendError(`You're trying to perm the following skills, but don't actually have them: ${unownedSkills.join(", ")}`);
178
+ }
179
+ const unpermableSkills = [...(permOptions?.permSkills.keys() ?? [])].filter((skill) => !skill.permable);
180
+ if (unpermableSkills.length) {
181
+ throw new AscendError(`You're trying to perm the following skills, but they're unpermable: ${unownedSkills.join(", ")}`);
182
+ }
183
+ if (!isInValhalla()) {
184
+ visitUrl("ascend.php?action=ascend&confirm=on&confirm2=on");
185
+ }
186
+ if (!isInValhalla()) {
187
+ throw new AscendError("Failed to ascend--do you have a pending trade offer?");
188
+ }
189
+ visitUrl("afterlife.php?action=pearlygates");
190
+ if (consumable !== $item `none`) {
191
+ visitUrl(`afterlife.php?action=buydeli&whichitem=${consumable.id}`);
192
+ }
193
+ if (pet !== $item `none`) {
194
+ visitUrl(`afterlife.php?action=buyarmory&whichitem=${pet.id}`);
195
+ }
196
+ if (permOptions) {
197
+ const currentPerms = permedSkills();
198
+ let karma = get("bankedKarma");
199
+ for (const [skill, prospectivePermLevel,] of permOptions.permSkills.entries()) {
200
+ const currentPermLevel = currentPerms.get(skill) ?? Lifestyle.casual;
201
+ if (prospectivePermLevel > currentPermLevel) {
202
+ const expectedKarma = 100 * (prospectivePermLevel - currentPermLevel);
203
+ if (karma < expectedKarma) {
204
+ if (!permOptions.neverAbort)
205
+ throw new AscendError(`Skill ${skill} is too karmaically expensive!`);
206
+ continue;
207
+ }
208
+ karma -= expectedKarma;
209
+ const permText = prospectivePermLevel === Lifestyle.hardcore ? "hcperm" : "scperm";
210
+ visitUrl(`afterlife.php?action=${permText}&whichskill=${skill.id}`);
211
+ }
212
+ }
213
+ }
214
+ 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);
215
+ }
216
+ /**
217
+ * Sets up various iotms you may want to use in the coming ascension
218
+ *
219
+ * @param ascensionPrep Configuration for various ascension prep settings. Any ommitted key will be kept as-is
220
+ * @param ascensionPrep.garden Garden to which to switch
221
+ * @param ascensionPrep.eudora Eudora to which to switch
222
+ * @param ascensionPrep.chateau Chateau configuration
223
+ * @param ascensionPrep.chateau.desk Chateau desk configuration
224
+ * @param ascensionPrep.chateau.ceiling Chateau ceiling configuration
225
+ * @param ascensionPrep.chateau.nightstand Chateau nightstand configuration
226
+ * @param ascensionPrep.throwOnFail If true, this will throw an error when it fails to switch something
227
+ */
228
+ export function prepareAscension({ garden, eudora, chateau, throwOnFail, } = {}) {
229
+ throwOnFail = throwOnFail ?? true;
230
+ if (garden && !Object.getOwnPropertyNames(getCampground()).includes(garden)) {
231
+ use(Item.get(garden));
232
+ const gardenName = Object.getOwnPropertyNames(getCampground()).find(isGarden);
233
+ if (gardenName !== garden && throwOnFail) {
234
+ throw new AscensionPrepError(garden, gardenName);
235
+ }
236
+ }
237
+ if (eudora && eudoraItem().name !== eudora) {
238
+ const eudoraNumber = 1 + eudorae.indexOf(eudora);
239
+ if (!xpath(visitUrl("account.php?tab=correspondence"), `//select[@name="whichpenpal"]/option/@value`).includes(eudoraNumber.toString()) &&
240
+ throwOnFail) {
241
+ throw new AscensionPrepError(`Unable to swap eudora to ${eudora} because you are not subscribed to it.`);
242
+ }
243
+ else {
244
+ visitUrl(`account.php?actions[]=whichpenpal&whichpenpal=${eudoraNumber}&action=Update`, true);
245
+ }
246
+ if (eudoraItem() !== Item.get(eudora) && throwOnFail) {
247
+ throw new AscensionPrepError(eudora, eudoraItem());
248
+ }
249
+ }
250
+ if (chateau && ChateauMantegna.have()) {
251
+ const { desk, ceiling, nightstand } = chateau;
252
+ if (ceiling && ChateauMantegna.getCeiling() !== ceiling) {
253
+ if (!ChateauMantegna.changeCeiling(ceiling) && throwOnFail) {
254
+ throw new AscensionPrepError(ceiling, ChateauMantegna.getCeiling() ?? "unknown");
255
+ }
256
+ }
257
+ if (desk && ChateauMantegna.getDesk() !== desk) {
258
+ if (!ChateauMantegna.changeDesk(desk) && throwOnFail) {
259
+ throw new AscensionPrepError(desk, ChateauMantegna.getDesk() ?? "unknown");
260
+ }
261
+ }
262
+ if (nightstand && ChateauMantegna.getNightstand() !== nightstand) {
263
+ if (!ChateauMantegna.changeNightstand(nightstand) && throwOnFail) {
264
+ throw new AscensionPrepError(nightstand, ChateauMantegna.getNightstand() ?? "unknown");
265
+ }
266
+ }
267
+ }
268
+ }
@@ -0,0 +1,22 @@
1
+ import { Location, Monster } from "kolmafia";
2
+ /**
3
+ * Cast Rain Man and fight the target monster
4
+ * @param target the monster to fight
5
+ */
6
+ export declare function rainMan(target: Monster): void;
7
+ /**
8
+ * Check if you can summon this monster using Rain Man
9
+ * @param target the monster to attempt to summon
10
+ * @returns true if you can summon the target monster, false otherwise
11
+ */
12
+ export declare function canRainMan(target: Monster): boolean;
13
+ export declare const RAIN_MONSTER_WINDOW_BEGIN = "Rain Monster window begin";
14
+ export declare const RAIN_MONSTER_WINDOW_END = "Rain Monster window end";
15
+ export declare const wanderers: readonly Monster[];
16
+ /**
17
+ * Calculate the expected wandering monster based on current water level
18
+ * @param location the location to check for wanderers
19
+ * @returns The monster for this location given the current waterlevel
20
+ */
21
+ export declare function expectedWanderer(location: Location): Monster;
22
+ export declare const path: import("kolmafia").Path;
@@ -0,0 +1,75 @@
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";
5
+ /**
6
+ * Cast Rain Man and fight the target monster
7
+ * @param target the monster to fight
8
+ */
9
+ export function rainMan(target) {
10
+ if (canRainMan(target)) {
11
+ withChoice(970, `1&whichmonster=${target.id}`, () => useSkill($skill `Rain Man`));
12
+ }
13
+ }
14
+ /**
15
+ * Check if you can summon this monster using Rain Man
16
+ * @param target the monster to attempt to summon
17
+ * @returns true if you can summon the target monster, false otherwise
18
+ */
19
+ export function canRainMan(target) {
20
+ if (!have($skill `Rain Man`) || // having the skill implies you are in heavy rains path
21
+ myRain() < 50 ||
22
+ !target.copyable ||
23
+ target.id < 0) {
24
+ return false;
25
+ }
26
+ if (monsterFactoidsAvailable(target, false) > 0) {
27
+ return true;
28
+ }
29
+ const page = withChoice(970, 2, () => visitUrl(`runskillz.php?pwd&action=Skillz&whichskill=${$skill `Rain Man`.id}&quantity=1`));
30
+ return page.indexOf(`<option value=${target.id}>`) > 0;
31
+ }
32
+ export const RAIN_MONSTER_WINDOW_BEGIN = "Rain Monster window begin";
33
+ export const RAIN_MONSTER_WINDOW_END = "Rain Monster window end";
34
+ export const wanderers = Object.freeze(Monster.get([
35
+ "giant isopod",
36
+ "gourmet gourami",
37
+ "freshwater bonefish",
38
+ "alley catfish",
39
+ "piranhadon",
40
+ "giant tardigrade",
41
+ "aquaconda",
42
+ "storm cow",
43
+ ]));
44
+ /**
45
+ * Calculate the expected wandering monster based on current water level
46
+ * @param location the location to check for wanderers
47
+ * @returns The monster for this location given the current waterlevel
48
+ */
49
+ export function expectedWanderer(location) {
50
+ const difficultyWaterLevel = location.difficultyLevel === "low" ? 1 : 2;
51
+ const environmentWaterLevel = location.environment === "underground"
52
+ ? 4
53
+ : location.environment === "indoor"
54
+ ? 2
55
+ : 1; // location.environment === "unknown" || "outdoors"
56
+ const waterLevel = numericModifier(Modifier.get("Water Level")) +
57
+ difficultyWaterLevel +
58
+ environmentWaterLevel;
59
+ if (waterLevel > 1 && waterLevel < 6) {
60
+ return wanderers[waterLevel - 1];
61
+ }
62
+ else if (waterLevel === 6 && location.environment === "underground") {
63
+ return $monster `giant tardigrade`;
64
+ }
65
+ else if (waterLevel === 6 && location.environment === "indoor") {
66
+ return $monster `aquaconda`;
67
+ }
68
+ else if (waterLevel === 6 && location.environment === "outdoor") {
69
+ return $monster `storm cow`;
70
+ }
71
+ else {
72
+ return $monster `giant isopod`;
73
+ }
74
+ }
75
+ export const path = $path `Heavy Rains`;
@@ -0,0 +1,125 @@
1
+ import { Effect } from "kolmafia";
2
+ import { Requirement } from "../../maximize";
3
+ export default class CommunityService {
4
+ private choice;
5
+ private stat;
6
+ private property;
7
+ private predictor;
8
+ private maximizeRequirements;
9
+ private timer;
10
+ /**
11
+ * Class to store properties of various CS tests.
12
+ *
13
+ * @param id The id the game HTML uses to identify the test; this is used primarily in runChoice.
14
+ * @param stat The principle stat the test measures, often used as more easily memorable shorthand for the specific tests
15
+ * @param property The name of the test as a string, often used as part of the string property "csServicesPerformed".
16
+ * @param predictor A function that returns an estimate for the number of turns that the test will take given your character's current state.
17
+ * @param maximizeRequirements A Requirement object, if applicable, that aligns with the things needed to maximize for this particular test.
18
+ */
19
+ private constructor();
20
+ /**
21
+ * @returns The id number of the test, used primarily in runChoice.
22
+ */
23
+ get id(): number;
24
+ /**
25
+ * @returns The primary stat the test measures, used primarily as memorable shorthand in place of test names.
26
+ */
27
+ get statName(): string;
28
+ /**
29
+ * @returns The name of the test, used primarily as part of the string property "csServicesPerformed"
30
+ */
31
+ get name(): string;
32
+ /**
33
+ * @returns The predicted number of turns this test will take given your character's current state.
34
+ */
35
+ get prediction(): number;
36
+ /**
37
+ * @returns A Requirement object, if applicable, that aligns with the things needed to maximize for this particular test.
38
+ */
39
+ get requirement(): Requirement | null;
40
+ /**
41
+ * Start the time & turn counter for the Test in question.
42
+ */
43
+ startTimer(): void;
44
+ private static taskTimers;
45
+ /**
46
+ * Start the time & turn counter for the given task
47
+ *
48
+ * @param name The name of the task to start the counter of
49
+ */
50
+ static startTimer(name: string): void;
51
+ static logTask(name: string, action: () => number | void): void;
52
+ /**
53
+ * Checks the "csServicesPerformed" property to see whether mafia currently believes this test is complete.
54
+ *
55
+ * @returns Whether mafia currently believes this test is complete.
56
+ */
57
+ isDone(): boolean;
58
+ /**
59
+ * Maximizes based on the Requirement associated with this particular test.
60
+ */
61
+ maximize(): void;
62
+ /**
63
+ * Attempts to turn in the test to the Council of Loathing.
64
+ *
65
+ * @returns Whether mafia believes the test is complete at the end of this function.
66
+ */
67
+ do(): boolean;
68
+ /**
69
+ * Wrapper function that prepares for a test and then completes it, adding time and turn details to the log.
70
+ *
71
+ * @param prepare A function that does all necessary preparations for this CS test, including choosing your outfit. Optionally returns the number of turns you expect to spend preparing for the test.
72
+ * @param maxTurns We will run the test iff the predicted/actual turns is less than or equal to this parameter.
73
+ * @returns "completed", "failed", or "already completed".
74
+ */
75
+ run(prepare: () => void | number, maxTurns?: number): "completed" | "failed" | "already completed";
76
+ private _verifyIsDone;
77
+ /**
78
+ * Checks council.php to verify that a test is complete; more reliable than isDone, but requires an additional pagehit.
79
+ *
80
+ * @returns Whether council.php suggests that the test is complete.
81
+ */
82
+ verifyIsDone(): boolean;
83
+ private _actualCost;
84
+ /**
85
+ * Checks council.php for the number of turns this test will take; more reliable than prediction, but requires an additional pagehit.
86
+ *
87
+ * @returns The number of turns to complete this test according to council.php.
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;
95
+ /**
96
+ * A log of the predicted turns, actual turns, and duration of each CS test performed.
97
+ */
98
+ static log: {
99
+ [index: string]: {
100
+ predictedTurns: number;
101
+ turnCost: number;
102
+ seconds: number;
103
+ type: "test" | "task";
104
+ };
105
+ };
106
+ /**
107
+ * Prints turncount and time details of the test in question.
108
+ *
109
+ * @param colour The colour (or color) you'd like the log to be printed in.
110
+ */
111
+ static printLog(colour?: string): void;
112
+ static HP: CommunityService;
113
+ static Muscle: CommunityService;
114
+ static Mysticality: CommunityService;
115
+ static Moxie: CommunityService;
116
+ static FamiliarWeight: CommunityService;
117
+ static WeaponDamage: CommunityService;
118
+ static SpellDamage: CommunityService;
119
+ static Noncombat: CommunityService;
120
+ static BoozeDrop: CommunityService;
121
+ static HotRes: CommunityService;
122
+ static CoilWire: CommunityService;
123
+ static donate: () => void;
124
+ static path: import("kolmafia").Path;
125
+ }