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.
- package/dist/Clan.js +268 -485
- package/dist/Copier.js +11 -48
- package/dist/Dungeon.js +77 -157
- package/dist/Kmail.d.ts +3 -1
- package/dist/Kmail.js +92 -243
- package/dist/Path.js +68 -120
- package/dist/ascend.js +153 -172
- package/dist/combat.d.ts +84 -0
- package/dist/combat.js +294 -387
- package/dist/console.js +13 -36
- package/dist/diet/index.d.ts +23 -8
- package/dist/diet/index.js +320 -426
- package/dist/diet/knapsack.d.ts +1 -1
- package/dist/diet/knapsack.js +90 -100
- package/dist/dungeons/Dreadsylvania.d.ts +4 -0
- package/dist/dungeons/Dreadsylvania.js +14 -0
- package/dist/dungeons/Dungeon.d.ts +28 -0
- package/dist/dungeons/Dungeon.js +99 -0
- package/dist/dungeons/Hobopolis.d.ts +4 -0
- package/dist/dungeons/Hobopolis.js +14 -0
- package/dist/dungeons/SlimeTube.d.ts +4 -0
- package/dist/dungeons/SlimeTube.js +14 -0
- package/dist/freerun.d.ts +16 -4
- package/dist/freerun.js +88 -99
- package/dist/index.d.ts +3 -1
- package/dist/index.js +21 -300
- package/dist/lib.d.ts +2 -0
- package/dist/lib.js +264 -515
- package/dist/logger.js +23 -63
- package/dist/maximize.js +289 -562
- package/dist/modifier.js +35 -46
- package/dist/modifierTypes.js +8 -22
- package/dist/mood.js +220 -531
- package/dist/property.d.ts +2 -0
- package/dist/property.js +96 -242
- package/dist/propertyTypes.d.ts +2 -2
- package/dist/propertyTypes.js +1 -0
- package/dist/propertyTyping.js +42 -53
- package/dist/resources/2007/CandyHearts.d.ts +9 -0
- package/dist/resources/2007/CandyHearts.js +24 -0
- package/dist/resources/2008/DivineFavors.d.ts +9 -0
- package/dist/resources/2008/DivineFavors.js +27 -0
- package/dist/resources/2009/Bandersnatch.js +37 -112
- package/dist/resources/2009/LoveSongs.d.ts +9 -0
- package/dist/resources/2009/LoveSongs.js +24 -0
- package/dist/resources/2009/SpookyPutty.js +20 -46
- package/dist/resources/2010/Brickos.d.ts +9 -0
- package/dist/resources/2010/Brickos.js +21 -0
- package/dist/resources/2010/CrownOfThrones.d.ts +9 -0
- package/dist/resources/2010/CrownOfThrones.js +550 -374
- package/dist/resources/2011/Gygaxian.d.ts +9 -0
- package/dist/resources/2011/Gygaxian.js +24 -0
- package/dist/resources/2011/ObtuseAngel.js +21 -63
- package/dist/resources/2012/RainDoh.js +14 -40
- package/dist/resources/2012/Resolutions.d.ts +9 -0
- package/dist/resources/2012/Resolutions.js +28 -0
- package/dist/resources/2013/Florist.d.ts +1 -0
- package/dist/resources/2013/Florist.js +137 -207
- package/dist/resources/2013/PulledTaffy.d.ts +9 -0
- package/dist/resources/2013/PulledTaffy.js +33 -0
- package/dist/resources/2014/WinterGarden.js +15 -43
- package/dist/resources/2015/ChateauMantegna.js +52 -86
- package/dist/resources/2015/MayoClinic.d.ts +1 -0
- package/dist/resources/2015/MayoClinic.js +30 -65
- package/dist/resources/2016/SourceTerminal.d.ts +1 -0
- package/dist/resources/2016/SourceTerminal.js +114 -237
- package/dist/resources/2016/Witchess.js +33 -59
- package/dist/resources/2017/TunnelOfLove.js +62 -111
- package/dist/resources/2018/SongBoom.js +32 -68
- package/dist/resources/2019/BeachComb.js +26 -44
- package/dist/resources/2019/Snapper.d.ts +28 -0
- package/dist/resources/2019/Snapper.js +70 -0
- package/dist/resources/2020/Guzzlr.js +79 -163
- package/dist/resources/LibramSummon.d.ts +12 -0
- package/dist/resources/LibramSummon.js +66 -0
- package/dist/resources/index.d.ts +3 -1
- package/dist/resources/index.js +19 -105
- package/dist/resources/putty-likes.js +15 -30
- package/dist/since.d.ts +1 -0
- package/dist/since.js +56 -112
- package/dist/template-string.js +40 -132
- package/dist/utils.js +36 -134
- package/package.json +2 -2
package/dist/diet/knapsack.d.ts
CHANGED
|
@@ -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][]];
|
package/dist/diet/knapsack.js
CHANGED
|
@@ -1,79 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
8
|
-
|
|
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
|
|
23
|
+
export declare function findFreeRun(useFamiliar?: boolean, buyStuff?: boolean): FreeRun | undefined;
|