libram 0.4.1 → 0.4.2

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 (83) hide show
  1. package/dist/Clan.js +268 -485
  2. package/dist/Copier.js +11 -48
  3. package/dist/Dungeon.js +77 -157
  4. package/dist/Kmail.d.ts +3 -1
  5. package/dist/Kmail.js +92 -243
  6. package/dist/Path.js +68 -120
  7. package/dist/ascend.js +153 -172
  8. package/dist/combat.d.ts +84 -0
  9. package/dist/combat.js +294 -387
  10. package/dist/console.js +13 -36
  11. package/dist/diet/index.d.ts +23 -8
  12. package/dist/diet/index.js +320 -426
  13. package/dist/diet/knapsack.d.ts +1 -1
  14. package/dist/diet/knapsack.js +90 -100
  15. package/dist/dungeons/Dreadsylvania.d.ts +4 -0
  16. package/dist/dungeons/Dreadsylvania.js +14 -0
  17. package/dist/dungeons/Dungeon.d.ts +28 -0
  18. package/dist/dungeons/Dungeon.js +99 -0
  19. package/dist/dungeons/Hobopolis.d.ts +4 -0
  20. package/dist/dungeons/Hobopolis.js +14 -0
  21. package/dist/dungeons/SlimeTube.d.ts +4 -0
  22. package/dist/dungeons/SlimeTube.js +14 -0
  23. package/dist/freerun.d.ts +16 -4
  24. package/dist/freerun.js +88 -99
  25. package/dist/index.d.ts +3 -1
  26. package/dist/index.js +21 -300
  27. package/dist/lib.d.ts +2 -0
  28. package/dist/lib.js +264 -515
  29. package/dist/logger.js +23 -63
  30. package/dist/maximize.js +289 -562
  31. package/dist/modifier.js +35 -46
  32. package/dist/modifierTypes.js +8 -22
  33. package/dist/mood.js +220 -531
  34. package/dist/property.d.ts +2 -0
  35. package/dist/property.js +96 -242
  36. package/dist/propertyTypes.d.ts +2 -2
  37. package/dist/propertyTypes.js +1 -0
  38. package/dist/propertyTyping.js +42 -53
  39. package/dist/resources/2007/CandyHearts.d.ts +9 -0
  40. package/dist/resources/2007/CandyHearts.js +24 -0
  41. package/dist/resources/2008/DivineFavors.d.ts +9 -0
  42. package/dist/resources/2008/DivineFavors.js +27 -0
  43. package/dist/resources/2009/Bandersnatch.js +37 -112
  44. package/dist/resources/2009/LoveSongs.d.ts +9 -0
  45. package/dist/resources/2009/LoveSongs.js +24 -0
  46. package/dist/resources/2009/SpookyPutty.js +20 -46
  47. package/dist/resources/2010/Brickos.d.ts +9 -0
  48. package/dist/resources/2010/Brickos.js +21 -0
  49. package/dist/resources/2010/CrownOfThrones.d.ts +9 -0
  50. package/dist/resources/2010/CrownOfThrones.js +550 -374
  51. package/dist/resources/2011/Gygaxian.d.ts +9 -0
  52. package/dist/resources/2011/Gygaxian.js +24 -0
  53. package/dist/resources/2011/ObtuseAngel.js +21 -63
  54. package/dist/resources/2012/RainDoh.js +14 -40
  55. package/dist/resources/2012/Resolutions.d.ts +9 -0
  56. package/dist/resources/2012/Resolutions.js +28 -0
  57. package/dist/resources/2013/Florist.d.ts +1 -0
  58. package/dist/resources/2013/Florist.js +137 -207
  59. package/dist/resources/2013/PulledTaffy.d.ts +9 -0
  60. package/dist/resources/2013/PulledTaffy.js +33 -0
  61. package/dist/resources/2014/WinterGarden.js +15 -43
  62. package/dist/resources/2015/ChateauMantegna.js +52 -86
  63. package/dist/resources/2015/MayoClinic.d.ts +1 -0
  64. package/dist/resources/2015/MayoClinic.js +30 -65
  65. package/dist/resources/2016/SourceTerminal.d.ts +1 -0
  66. package/dist/resources/2016/SourceTerminal.js +114 -237
  67. package/dist/resources/2016/Witchess.js +33 -59
  68. package/dist/resources/2017/TunnelOfLove.js +62 -111
  69. package/dist/resources/2018/SongBoom.js +32 -68
  70. package/dist/resources/2019/BeachComb.js +26 -44
  71. package/dist/resources/2019/Snapper.d.ts +28 -0
  72. package/dist/resources/2019/Snapper.js +70 -0
  73. package/dist/resources/2020/Guzzlr.js +79 -163
  74. package/dist/resources/LibramSummon.d.ts +12 -0
  75. package/dist/resources/LibramSummon.js +66 -0
  76. package/dist/resources/index.d.ts +3 -1
  77. package/dist/resources/index.js +19 -105
  78. package/dist/resources/putty-likes.js +15 -30
  79. package/dist/since.d.ts +1 -0
  80. package/dist/since.js +56 -112
  81. package/dist/template-string.js +40 -132
  82. package/dist/utils.js +36 -134
  83. package/package.json +2 -2
@@ -4,4 +4,4 @@
4
4
  * @param capacity Capacity of knapsack.
5
5
  * @returns Tuple {[totalValue, items]} of selected items and total value of those items.
6
6
  */
7
- export declare function knapsack<T>(values: [T, number, number, number?][], capacity: number): [number, T[]];
7
+ export declare function knapsack<T>(values: [T, number, number, number?][], capacity: number): [number, [T, number][]];
@@ -1,79 +1,80 @@
1
- "use strict";
2
-
3
- require("core-js/modules/es.symbol.js");
4
-
5
- require("core-js/modules/es.symbol.description.js");
6
-
7
- require("core-js/modules/es.object.to-string.js");
8
-
9
- require("core-js/modules/es.array.iterator.js");
10
-
11
- require("core-js/modules/es.array.slice.js");
12
-
13
- Object.defineProperty(exports, "__esModule", {
14
- value: true
15
- });
16
- exports.knapsack = knapsack;
17
-
18
- require("core-js/modules/es.array.sort.js");
19
-
20
- require("core-js/modules/es.array.concat.js");
21
-
22
- require("core-js/modules/es.array.map.js");
23
-
24
- require("core-js/modules/es.array.fill.js");
25
-
26
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
27
-
28
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
29
-
30
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
31
-
32
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
33
-
34
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
35
-
36
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
37
-
38
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
39
-
40
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
41
-
42
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
43
-
44
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
45
-
1
+ import { sum } from "../utils";
2
+ class Not {
3
+ constructor(thing) {
4
+ this.thing = thing;
5
+ }
6
+ }
7
+ // Assuming list is already sorted, count adjacent items.
8
+ // Effectively run-length encoding.
9
+ function aggregate(list, isEqual) {
10
+ const aggregatedList = [];
11
+ for (const item of list) {
12
+ if (aggregatedList.length === 0) {
13
+ aggregatedList.push([item, 1]);
14
+ }
15
+ else {
16
+ const last = aggregatedList[aggregatedList.length - 1];
17
+ const [lastItem] = last;
18
+ if (isEqual ? isEqual(item, lastItem) : item === lastItem) {
19
+ last[1]++;
20
+ }
21
+ else {
22
+ aggregatedList.push([item, 1]);
23
+ }
24
+ }
25
+ }
26
+ return aggregatedList;
27
+ }
46
28
  /**
47
29
  * Solve the knapsack problem.
48
30
  * @param values Array of {[item, value, weight, maximum]} tuples for knapsack parameter.
49
31
  * @param capacity Capacity of knapsack.
50
32
  * @returns Tuple {[totalValue, items]} of selected items and total value of those items.
51
33
  */
52
- function knapsack(values, capacity) {
53
- var _ref;
54
-
55
- // Sort values by weight.
56
- var valuesSorted = _toConsumableArray(values).sort((x, y) => x[2] - y[2]); // Convert the problem into 0/1 knapsack - just include as many copies as possible of each item.
57
-
58
-
59
- var values01 = (_ref = []).concat.apply(_ref, _toConsumableArray(valuesSorted.map(_ref2 => {
60
- var _ref3 = _slicedToArray(_ref2, 4),
61
- thing = _ref3[0],
62
- value = _ref3[1],
63
- weight = _ref3[2],
64
- maximum = _ref3[3];
65
-
66
- var maxQuantity = maximum !== null && maximum !== void 0 ? maximum : Math.floor(capacity / weight);
67
- return new Array(maxQuantity).fill([thing, value, weight]);
68
- })));
69
-
70
- var memoizationTable = new Array(values01.length);
71
-
72
- for (var i = 0; i < values01.length; i++) {
73
- memoizationTable[i] = new Array(capacity).fill(null);
74
- }
75
-
76
- return bestSolution(memoizationTable, values01, values01.length - 1, capacity);
34
+ export function knapsack(values, capacity) {
35
+ // Invert negative values into a fake value for not using it.
36
+ const valuesInverted = values.map(([thing, value, weight, maximum]) => (weight < 0 && maximum
37
+ ? [new Not(thing), -value, -weight, maximum]
38
+ : [thing, value, weight, maximum]));
39
+ const capacityAdjustment = sum(values, ([, , weight, maximum]) => weight < 0 && maximum ? -weight * maximum : 0);
40
+ const adjustedCapacity = capacity + capacityAdjustment;
41
+ // Sort values by weight.
42
+ const valuesSorted = [...valuesInverted].sort((x, y) => x[2] - y[2]);
43
+ // Convert the problem into 0/1 knapsack - just include as many copies as possible of each item.
44
+ const values01 = [].concat(...valuesSorted.map(([thing, value, weight, maximum]) => {
45
+ const maxQuantity = maximum ?? Math.floor(adjustedCapacity / weight);
46
+ return new Array(maxQuantity).fill([
47
+ thing,
48
+ value,
49
+ weight,
50
+ ]);
51
+ }));
52
+ const memoizationTable = new Array(values01.length);
53
+ for (let i = 0; i < values01.length; i++) {
54
+ memoizationTable[i] = new Array(adjustedCapacity).fill(null);
55
+ }
56
+ const [value, invertedSolution] = bestSolution(memoizationTable, values01, values01.length - 1, adjustedCapacity);
57
+ // Still need to replace Not<T>s with right quantity of T's.
58
+ const aggregatedSolution = aggregate(invertedSolution);
59
+ const countMap = new Map(aggregatedSolution);
60
+ let valueAdjustment = 0;
61
+ const solution = aggregatedSolution.filter(([thingOrNot]) => !(thingOrNot instanceof Not));
62
+ for (const [thingOrNot, value, , maximum] of valuesSorted) {
63
+ if (thingOrNot instanceof Not) {
64
+ const notCount = countMap.get(thingOrNot) ?? 0;
65
+ if (maximum === undefined) {
66
+ throw new Error(`Cannot find maximum for item ${thingOrNot.thing}.`);
67
+ }
68
+ if (notCount > maximum) {
69
+ throw new Error(`Somehow picked ${notCount} more than the maximum ${notCount} for item ${thingOrNot.thing}.`);
70
+ }
71
+ if (notCount < maximum) {
72
+ solution.push([thingOrNot.thing, maximum - notCount]);
73
+ }
74
+ valueAdjustment -= maximum * value;
75
+ }
76
+ }
77
+ return [value + valueAdjustment, solution];
77
78
  }
78
79
  /**
79
80
  * Find the best solution to a knapsack subproblem.
@@ -83,34 +84,23 @@ function knapsack(values, capacity) {
83
84
  * @param remainingCapacity Remaining capacity of knapsack.
84
85
  * @returns
85
86
  */
86
-
87
-
88
87
  function bestSolution(memoizationTable, values, currentIndex, remainingCapacity) {
89
- // If we've used all our capacity, this solution is no good.
90
- if (remainingCapacity < 0) return [-Infinity, []];
91
- if (remainingCapacity === 0 || currentIndex < 0) return [0, []];
92
- var memoized = memoizationTable[currentIndex][remainingCapacity - 1];
93
- if (memoized !== null) return memoized;
94
-
95
- var _values$currentIndex = _slicedToArray(values[currentIndex], 3),
96
- item = _values$currentIndex[0],
97
- value = _values$currentIndex[1],
98
- weight = _values$currentIndex[2];
99
-
100
- var _bestSolution = bestSolution(memoizationTable, values, currentIndex - 1, remainingCapacity - weight),
101
- _bestSolution2 = _slicedToArray(_bestSolution, 2),
102
- valueIncludeRest = _bestSolution2[0],
103
- itemsInclude = _bestSolution2[1];
104
-
105
- var valueInclude = valueIncludeRest + value;
106
-
107
- var _bestSolution3 = bestSolution(memoizationTable, values, currentIndex - 1, remainingCapacity),
108
- _bestSolution4 = _slicedToArray(_bestSolution3, 2),
109
- valueExclude = _bestSolution4[0],
110
- itemsExclude = _bestSolution4[1]; // Pick the better of the two options between including/excluding.
111
-
112
-
113
- var result = valueInclude > valueExclude ? [valueInclude, [].concat(_toConsumableArray(itemsInclude), [item])] : [valueExclude, itemsExclude];
114
- memoizationTable[currentIndex][remainingCapacity - 1] = result;
115
- return result;
116
- }
88
+ // If we've used all our capacity, this solution is no good.
89
+ if (remainingCapacity < 0)
90
+ return [-Infinity, []];
91
+ if (remainingCapacity === 0 || currentIndex < 0)
92
+ return [0, []];
93
+ const memoized = memoizationTable[currentIndex][remainingCapacity - 1];
94
+ if (memoized !== null)
95
+ return memoized;
96
+ const [item, value, weight] = values[currentIndex];
97
+ const [valueIncludeRest, itemsInclude] = bestSolution(memoizationTable, values, currentIndex - 1, remainingCapacity - weight);
98
+ const valueInclude = valueIncludeRest + value;
99
+ const [valueExclude, itemsExclude] = bestSolution(memoizationTable, values, currentIndex - 1, remainingCapacity);
100
+ // Pick the better of the two options between including/excluding.
101
+ const result = valueInclude > valueExclude
102
+ ? [valueInclude, [...itemsInclude, item]]
103
+ : [valueExclude, itemsExclude];
104
+ memoizationTable[currentIndex][remainingCapacity - 1] = result;
105
+ return result;
106
+ }
@@ -0,0 +1,4 @@
1
+ export declare function close(): boolean;
2
+ export declare function open(paymentPolicy?: "None" | "All" | "Difference"): boolean;
3
+ export declare function distribute(idOrName?: number | string, loot?: Item | Item[] | Map<Item, number>, distributeAllOfAGivenItem?: boolean): void;
4
+ export declare function findLoot(): Map<Item, number>;
@@ -0,0 +1,14 @@
1
+ import { myId } from "kolmafia";
2
+ import { close as closeDungeon, distribute as distributeDungeon, Dreadsylvania, findLoot as findLootDungeon, open as openDungeon, } from "./Dungeon";
3
+ export function close() {
4
+ return closeDungeon(Dreadsylvania);
5
+ }
6
+ export function open(paymentPolicy = "Difference") {
7
+ return openDungeon(Dreadsylvania, paymentPolicy);
8
+ }
9
+ export function distribute(idOrName = myId(), loot = Dreadsylvania.loot, distributeAllOfAGivenItem = true) {
10
+ distributeDungeon(Dreadsylvania, idOrName, loot, distributeAllOfAGivenItem);
11
+ }
12
+ export function findLoot() {
13
+ return findLootDungeon(Dreadsylvania);
14
+ }
@@ -0,0 +1,28 @@
1
+ export declare type Dungeon = {
2
+ name: string;
3
+ loot: Item[];
4
+ openAction: string;
5
+ closeAction: string;
6
+ openCost: number;
7
+ openImage: string;
8
+ closedImage: string;
9
+ };
10
+ /**
11
+ * Distributes loot from given dungeon
12
+ * @param dungeon The dungeon to distribute loot from
13
+ * @param idOrName The player you're trying to distribute to, either as a username or a player ID. Defaults to self.
14
+ * @param loot The loot you're looking to distribute, specific to this dungeon
15
+ * @param distributeAllOfAGivenItem For items that you can get multiple of in a dungeon. When true, this will give everything of that ilk to your chosen player.
16
+ */
17
+ export declare function distribute(dungeon: Dungeon, idOrName?: number | string, loot?: Item | Item[] | Map<Item, number>, distributeAllOfAGivenItem?: boolean): void;
18
+ export declare function close(dungeon: Dungeon): boolean;
19
+ /**
20
+ * Opens clan dungeon and, if relevant, pays meat to do so
21
+ * @param dungeon The Dungeon to open
22
+ * @param paymentPolicy "None", "All", or "Difference". Difference pays into the stash the exact amount needed to open the dungeon.
23
+ */
24
+ export declare function open(dungeon: Dungeon, paymentPolicy?: "None" | "All" | "Difference"): boolean;
25
+ export declare const Dreadsylvania: Dungeon;
26
+ export declare const Hobopolis: Dungeon;
27
+ export declare const SlimeTube: Dungeon;
28
+ export declare function findLoot(dungeon: Dungeon): Map<Item, number>;
@@ -0,0 +1,99 @@
1
+ import { getClanName, myId, toItem, visitUrl, xpath } from "kolmafia";
2
+ import { $items } from "../template-string";
3
+ import { Clan } from "../Clan";
4
+ import { getPlayerFromIdOrName } from "../lib";
5
+ import { countedMapToArray } from "../utils";
6
+ /**
7
+ * Distributes loot from given dungeon
8
+ * @param dungeon The dungeon to distribute loot from
9
+ * @param idOrName The player you're trying to distribute to, either as a username or a player ID. Defaults to self.
10
+ * @param loot The loot you're looking to distribute, specific to this dungeon
11
+ * @param distributeAllOfAGivenItem For items that you can get multiple of in a dungeon. When true, this will give everything of that ilk to your chosen player.
12
+ */
13
+ export function distribute(dungeon, idOrName = myId(), loot = dungeon.loot, distributeAllOfAGivenItem = true) {
14
+ const player = getPlayerFromIdOrName(idOrName);
15
+ const lootList = loot instanceof Map
16
+ ? countedMapToArray(loot)
17
+ : Array.isArray(loot)
18
+ ? loot
19
+ : [loot];
20
+ const badLoot = lootList.find((lootItem) => !dungeon.loot.includes(lootItem));
21
+ if (badLoot) {
22
+ throw new Error(`${badLoot} is not a valid piece of dungeon loot`);
23
+ }
24
+ const pageText = visitUrl("clan_basement.php");
25
+ if (!pageText.match(new RegExp(player.name, "i"))) {
26
+ throw new Error(`${player.name} cannot be distributed loot from ${getClanName()}`);
27
+ }
28
+ const itemNames = xpath(pageText, "//tr/td[2]/b/text()");
29
+ const whichLoots = xpath(pageText, '//form[@action="clan_basement.php"]//input[@type="hidden"][@name="whichloot"]/@value');
30
+ itemNames.forEach((itemName, index) => {
31
+ if (lootList.includes(toItem(itemName))) {
32
+ visitUrl(`clan_basement.php?whichloot=${whichLoots[index]}&recipient=${player.id}`);
33
+ if (!distributeAllOfAGivenItem)
34
+ lootList.splice(lootList.indexOf(toItem(itemName)));
35
+ }
36
+ });
37
+ }
38
+ export function close(dungeon) {
39
+ visitUrl(`clan_basement.php?action=${dungeon.closeAction}&confirm=true`, true);
40
+ const pageText = visitUrl("clan_basement.php");
41
+ return pageText.includes(dungeon.closedImage);
42
+ }
43
+ /**
44
+ * Opens clan dungeon and, if relevant, pays meat to do so
45
+ * @param dungeon The Dungeon to open
46
+ * @param paymentPolicy "None", "All", or "Difference". Difference pays into the stash the exact amount needed to open the dungeon.
47
+ */
48
+ export function open(dungeon, paymentPolicy = "Difference") {
49
+ const pageText = visitUrl("clan_basement.php");
50
+ if (pageText.includes(dungeon.openImage))
51
+ return true;
52
+ const clan = Clan.get();
53
+ if (paymentPolicy === "All") {
54
+ clan.putMeatInCoffer(dungeon.openCost);
55
+ }
56
+ else {
57
+ const stashMeat = clan.getMeatInCoffer();
58
+ const payDifference = dungeon.openCost - stashMeat;
59
+ if (payDifference > 0) {
60
+ if (paymentPolicy === "None")
61
+ return false;
62
+ clan.putMeatInCoffer(payDifference);
63
+ }
64
+ }
65
+ visitUrl(`clan_basement.php?action=${dungeon.openAction}`, true);
66
+ return visitUrl("clan_basement.php").includes(dungeon.openImage);
67
+ }
68
+ /**
69
+ * Creates dungeon object for managing clan dungeons
70
+ * @param name Name of the dungeon in question
71
+ * @param loot Distributable loot dropped by bosses in dungeon
72
+ * @param openAction String action used in form submission to open dungeon
73
+ * @param closeAction String action used in form submission to close dungeon
74
+ * @param openCost Meat cost of opening dungeon
75
+ * @param openImage Image text to search clan_basement.php for to check if dungeon is open
76
+ * @param closedImage Image text to search clan_basement.php for to check if dungeon is closed
77
+ */
78
+ function createDungeon(name, loot, openAction, closeAction, openCost, openImage, closedImage) {
79
+ return {
80
+ name: name,
81
+ loot: loot,
82
+ openAction: openAction,
83
+ closeAction: closeAction,
84
+ openCost: openCost,
85
+ openImage: openImage,
86
+ closedImage: closedImage,
87
+ };
88
+ }
89
+ export const Dreadsylvania = createDungeon("Dreadsylvania", $items `Great Wolf's headband, Great Wolf's right paw, Great Wolf's left paw, Great Wolf's lice, Great Wolf's rocket launcher, Great Wolf's beastly trousers, Drapes-You-Regally, Warms-Your-Tush, Covers-Your-Head, Protects-Your-Junk, Quiets-Your-Steps, Helps-You-Sleep, Mayor Ghost's khakis, Mayor Ghost's cloak, Mayor Ghost's toupee, Mayor Ghost's scissors, Mayor Ghost's sash, Mayor Ghost's gavel, zombie mariachi hat, zombie accordion, zombie mariachi pants, HOA regulation book, HOA zombie eyes, HOA citation pad, Unkillable Skeleton's skullcap, Unkillable Skeleton's shinguards, Unkillable Skeleton's breastplate, Unkillable Skeleton's shield, Unkillable Skeleton's sawsword, Unkillable Skeleton's restless leg, skull capacitor, Thunkula's drinking cap, Drunkula's silky pants, Drunkula's cape, Drunkula's ring of haze, Drunkula's wineglass, Drunkula's bell, bottle of Bloodweiser, bottle of Bloodweiser, bottle of Bloodweiser, bottle of Bloodweiser, electric Kool-Aid, electric Kool-Aid, electric Kool-Aid, electric Kool-Aid, ghost pepper, ghost pepper, ghost pepper, ghost pepper, Gets-You-Drunk, Gets-You-Drunk, Gets-You-Drunk, Gets-You-Drunk, wriggling severed nose, wriggling severed nose, wriggling severed nose, wriggling severed nose, Hunger™ Sauce, Hunger™ Sauce, Hunger™ Sauce, Hunger™ Sauce`, "translatemap", "foldmap", 1000000, "dvmap.gif", "foldmap.gif");
90
+ export const Hobopolis = createDungeon("Hobopolis", $items `Ol' Scratch's ash can, Ol' Scratch's ol' britches, Ol' Scratch's stovepipe hat, Ol' Scratch's infernal pitchfork, Ol' Scratch's manacles, Ol' Scratch's stove door, Frosty's carrot, Frosty's nailbat, Frosty's old silk hat, Frosty's arm, Frosty's iceball, Frosty's snowball sack, Oscus's dumpster waders, Oscus's pelt, Wand of Oscus, Oscus's flypaper pants, Oscus's garbage can lid, Oscus's neverending soda, Zombo's grievous greaves, Zombo's shield, Zombo's skullcap, Zombo's empty eye, Zombo's shoulder blade, Zombo's skull ring, Chester's bag of candy, Chester's cutoffs, Chester's moustache, Chester's Aquarius medallion, Chester's muscle shirt, Chester's sunglasses, Hodgman's bow tie, Hodgman's porkpie hat, Hodgman's lobsterskin pants, Hodgman's almanac, Hodgman's lucky sock, Hodgman's metal detector, Hodgman's varcolac paw, Hodgman's harmonica, Hodgman's garbage sticker, Hodgman's cane, Hodgman's whackin' stick, Hodgman's disgusting technicolor overcoat, Hodgman's imaginary hamster`, "cleansewer", "floodsewer", 1000000, "opengrate.gif", "sewergrate.gif");
91
+ export const SlimeTube = createDungeon("The Slime Tube", $items `slime-soaked brain, slime-soaked hypophysis, slime-soaked sweat gland, squirming Slime larva, caustic slime nodule, caustic slime nodule, hardened slime belt, hardened slime hat, hardened slime pants`, "cleanspot", "sealtube", 250000, "slimehole.gif", "greasespot.gif");
92
+ export function findLoot(dungeon) {
93
+ const returnValue = new Map();
94
+ const pageText = visitUrl("clan_basement.php");
95
+ for (const lootItem of dungeon.loot) {
96
+ returnValue.set(lootItem, pageText.match(new RegExp(lootItem.name, "g"))?.length ?? 0);
97
+ }
98
+ return returnValue;
99
+ }
@@ -0,0 +1,4 @@
1
+ export declare function close(): boolean;
2
+ export declare function open(paymentPolicy?: "None" | "All" | "Difference"): boolean;
3
+ export declare function distribute(idOrName?: number | string, loot?: Item | Item[] | Map<Item, number>, distributeAllOfAGivenItem?: boolean): void;
4
+ export declare function findLoot(): Map<Item, number>;
@@ -0,0 +1,14 @@
1
+ import { myId } from "kolmafia";
2
+ import { close as closeDungeon, distribute as distributeDungeon, findLoot as findLootDungeon, Hobopolis, open as openDungeon, } from "./Dungeon";
3
+ export function close() {
4
+ return closeDungeon(Hobopolis);
5
+ }
6
+ export function open(paymentPolicy = "Difference") {
7
+ return openDungeon(Hobopolis, paymentPolicy);
8
+ }
9
+ export function distribute(idOrName = myId(), loot = Hobopolis.loot, distributeAllOfAGivenItem = true) {
10
+ distributeDungeon(Hobopolis, idOrName, loot, distributeAllOfAGivenItem);
11
+ }
12
+ export function findLoot() {
13
+ return findLootDungeon(Hobopolis);
14
+ }
@@ -0,0 +1,4 @@
1
+ export declare function close(): boolean;
2
+ export declare function open(paymentPolicy?: "None" | "All" | "Difference"): boolean;
3
+ export declare function distribute(idOrName?: number | string, loot?: Item | Item[] | Map<Item, number>, distributeAllOfAGivenItem?: boolean): void;
4
+ export declare function findLoot(): Map<Item, number>;
@@ -0,0 +1,14 @@
1
+ import { myId } from "kolmafia";
2
+ import { close as closeDungeon, distribute as distributeDungeon, findLoot as findLootDungeon, open as openDungeon, SlimeTube, } from "./Dungeon";
3
+ export function close() {
4
+ return closeDungeon(SlimeTube);
5
+ }
6
+ export function open(paymentPolicy = "Difference") {
7
+ return openDungeon(SlimeTube, paymentPolicy);
8
+ }
9
+ export function distribute(idOrName = myId(), loot = SlimeTube.loot, distributeAllOfAGivenItem = true) {
10
+ distributeDungeon(SlimeTube, idOrName, loot, distributeAllOfAGivenItem);
11
+ }
12
+ export function findLoot() {
13
+ return findLootDungeon(SlimeTube);
14
+ }
package/dist/freerun.d.ts CHANGED
@@ -1,11 +1,23 @@
1
1
  import { Macro } from "./combat";
2
2
  import { Requirement } from "./maximize";
3
+ export declare type AdventureOptions = {
4
+ equipmentRequirements?: () => Requirement;
5
+ preparation?: () => boolean;
6
+ location?: () => Location;
7
+ macro?: () => Macro;
8
+ familiar?: () => Familiar;
9
+ available?: () => boolean;
10
+ };
11
+ export declare type FreeRunOptions = {
12
+ equipmentRequirements?: () => Requirement;
13
+ preparation?: () => boolean;
14
+ familiar?: () => Familiar;
15
+ };
3
16
  export declare class FreeRun {
4
17
  name: string;
5
18
  available: () => boolean;
6
19
  macro: Macro;
7
- requirement?: Requirement;
8
- prepare?: () => void;
9
- constructor(name: string, available: () => boolean, macro: Macro, requirement?: Requirement, prepare?: () => void);
20
+ options?: FreeRunOptions;
21
+ constructor(name: string, available: () => boolean, macro: Macro, options?: FreeRunOptions);
10
22
  }
11
- export default function findFreeRun(useFamiliar?: boolean, buyStuff?: boolean): FreeRun | undefined;
23
+ export declare function findFreeRun(useFamiliar?: boolean, buyStuff?: boolean): FreeRun | undefined;