libram 0.3.2 → 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 (99) 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 +13 -7
  5. package/dist/Kmail.js +92 -233
  6. package/dist/Path.js +68 -120
  7. package/dist/ascend.js +153 -172
  8. package/dist/combat.d.ts +86 -1
  9. package/dist/combat.js +295 -387
  10. package/dist/console.js +13 -36
  11. package/dist/diet/index.d.ts +31 -0
  12. package/dist/diet/index.js +333 -0
  13. package/dist/diet/knapsack.d.ts +7 -0
  14. package/dist/diet/knapsack.js +106 -0
  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 +23 -0
  24. package/dist/freerun.js +92 -0
  25. package/dist/index.d.ts +6 -1
  26. package/dist/index.js +21 -263
  27. package/dist/lib.d.ts +43 -0
  28. package/dist/lib.js +296 -405
  29. package/dist/logger.js +23 -63
  30. package/dist/maximize.d.ts +29 -12
  31. package/dist/maximize.js +318 -421
  32. package/dist/modifier.d.ts +13 -0
  33. package/dist/modifier.js +35 -0
  34. package/dist/modifierTypes.d.ts +16 -0
  35. package/dist/modifierTypes.js +9 -0
  36. package/dist/mood.js +220 -531
  37. package/dist/property.d.ts +2 -0
  38. package/dist/property.js +96 -242
  39. package/dist/propertyTypes.d.ts +9 -0
  40. package/dist/propertyTypes.js +1 -0
  41. package/dist/propertyTyping.d.ts +2 -9
  42. package/dist/propertyTyping.js +42 -53
  43. package/dist/resources/2007/CandyHearts.d.ts +9 -0
  44. package/dist/resources/2007/CandyHearts.js +24 -0
  45. package/dist/resources/2008/DivineFavors.d.ts +9 -0
  46. package/dist/resources/2008/DivineFavors.js +27 -0
  47. package/dist/resources/2009/Bandersnatch.js +37 -112
  48. package/dist/resources/2009/LoveSongs.d.ts +9 -0
  49. package/dist/resources/2009/LoveSongs.js +24 -0
  50. package/dist/resources/2009/SpookyPutty.js +20 -46
  51. package/dist/resources/2010/Brickos.d.ts +9 -0
  52. package/dist/resources/2010/Brickos.js +21 -0
  53. package/dist/resources/2010/CrownOfThrones.d.ts +18 -0
  54. package/dist/resources/2010/CrownOfThrones.js +550 -0
  55. package/dist/resources/2011/Gygaxian.d.ts +9 -0
  56. package/dist/resources/2011/Gygaxian.js +24 -0
  57. package/dist/resources/2011/ObtuseAngel.js +21 -63
  58. package/dist/resources/2012/RainDoh.js +14 -40
  59. package/dist/resources/2012/Resolutions.d.ts +9 -0
  60. package/dist/resources/2012/Resolutions.js +28 -0
  61. package/dist/resources/2013/Florist.d.ts +61 -0
  62. package/dist/resources/2013/Florist.js +149 -0
  63. package/dist/resources/2013/PulledTaffy.d.ts +9 -0
  64. package/dist/resources/2013/PulledTaffy.js +33 -0
  65. package/dist/resources/2014/WinterGarden.js +15 -43
  66. package/dist/resources/2015/ChateauMantegna.js +52 -86
  67. package/dist/resources/2015/MayoClinic.d.ts +13 -0
  68. package/dist/resources/2015/MayoClinic.js +36 -0
  69. package/dist/resources/2016/SourceTerminal.d.ts +1 -0
  70. package/dist/resources/2016/SourceTerminal.js +114 -237
  71. package/dist/resources/2016/Witchess.js +33 -59
  72. package/dist/resources/2017/TunnelOfLove.js +62 -111
  73. package/dist/resources/2018/SongBoom.js +32 -68
  74. package/dist/resources/2019/BeachComb.d.ts +2 -0
  75. package/dist/resources/2019/BeachComb.js +26 -0
  76. package/dist/resources/2019/Snapper.d.ts +28 -0
  77. package/dist/resources/2019/Snapper.js +70 -0
  78. package/dist/resources/2020/Guzzlr.js +79 -163
  79. package/dist/resources/LibramSummon.d.ts +12 -0
  80. package/dist/resources/LibramSummon.js +66 -0
  81. package/dist/resources/index.d.ts +18 -11
  82. package/dist/resources/index.js +19 -85
  83. package/dist/resources/putty-likes.js +15 -30
  84. package/dist/ring-buffer.d.ts +24 -0
  85. package/dist/ring-buffer.js +135 -0
  86. package/dist/since.d.ts +1 -0
  87. package/dist/since.js +56 -112
  88. package/dist/template-string.js +40 -132
  89. package/dist/utils.d.ts +14 -0
  90. package/dist/utils.js +50 -114
  91. package/package.json +5 -3
  92. package/dist/libram-example-briefcase.js +0 -16073
  93. package/dist/libram-example-clan.js +0 -8898
  94. package/dist/libram-example-consult.js +0 -6179
  95. package/dist/libram-example-item.js +0 -3248
  96. package/dist/libram-example-kmail.js +0 -2065
  97. package/dist/libram-example-lib.js +0 -7608
  98. package/dist/libram-example-props.js +0 -4770
  99. package/dist/libram-example-resources.js +0 -12226
@@ -1,61 +1,35 @@
1
- "use strict";
2
-
3
- require("core-js/modules/es.array.slice.js");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.have = have;
9
- exports.fightsDone = fightsDone;
10
- exports.fightPiece = fightPiece;
11
- exports.pieces = exports.item = void 0;
12
-
13
- require("core-js/modules/es.array.includes.js");
14
-
15
- require("core-js/modules/es.string.includes.js");
16
-
17
- require("core-js/modules/es.array.concat.js");
18
-
19
- var _kolmafia = require("kolmafia");
20
-
21
- var _lib = require("../../lib");
22
-
23
- var _property = require("../../property");
24
-
25
- var _templateString = require("../../template-string");
26
-
27
- var _templateObject;
28
-
29
- function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
30
-
31
- var item = (0, _templateString.$item)(_templateObject || (_templateObject = _taggedTemplateLiteral(["Witchess Set"])));
32
- exports.item = item;
33
-
34
- function have() {
35
- return (0, _lib.haveInCampground)(item);
1
+ import { myHash, runChoice, runCombat, toInt, visitUrl } from "kolmafia";
2
+ import { haveInCampground } from "../../lib";
3
+ import { get } from "../../property";
4
+ import { $item } from "../../template-string";
5
+ export const item = $item `Witchess Set`;
6
+ export function have() {
7
+ return haveInCampground(item);
36
8
  }
37
-
38
- function fightsDone() {
39
- return (0, _property.get)("_witchessFights");
9
+ export function fightsDone() {
10
+ return get("_witchessFights");
11
+ }
12
+ export const pieces = Monster.get([
13
+ "Witchess Pawn",
14
+ "Witchess Knight",
15
+ "Witchess Bishop",
16
+ "Witchess Rook",
17
+ "Witchess Queen",
18
+ "Witchess King",
19
+ "Witchess Witch",
20
+ "Witchess Ox",
21
+ ]);
22
+ export function fightPiece(piece) {
23
+ if (!pieces.includes(piece))
24
+ throw new Error("That is not a valid piece.");
25
+ if (!visitUrl("campground.php?action=witchess").includes("whichchoice value=1181")) {
26
+ throw new Error("Failed to open Witchess.");
27
+ }
28
+ if (!runChoice(1).includes("whichchoice=1182")) {
29
+ throw new Error("Failed to visit shrink ray.");
30
+ }
31
+ if (!visitUrl(`choice.php?option=1&pwd=${myHash()}&whichchoice=1182&piece=${toInt(piece)}`, false).includes(piece.name)) {
32
+ throw new Error("Failed to start fight.");
33
+ }
34
+ return runCombat();
40
35
  }
41
-
42
- var pieces = Monster.get(["Witchess Pawn", "Witchess Knight", "Witchess Bishop", "Witchess Rook", "Witchess Queen", "Witchess King", "Witchess Witch", "Witchess Ox"]);
43
- exports.pieces = pieces;
44
-
45
- function fightPiece(piece) {
46
- if (!pieces.includes(piece)) throw new Error("That is not a valid piece.");
47
-
48
- if (!(0, _kolmafia.visitUrl)("campground.php?action=witchess").includes("whichchoice value=1181")) {
49
- throw new Error("Failed to open Witchess.");
50
- }
51
-
52
- if (!(0, _kolmafia.runChoice)(1).includes("whichchoice=1182")) {
53
- throw new Error("Failed to visit shrink ray.");
54
- }
55
-
56
- if (!(0, _kolmafia.visitUrl)("choice.php?option=1&pwd=".concat((0, _kolmafia.myHash)(), "&whichchoice=1182&piece=").concat((0, _kolmafia.toInt)(piece)), false).includes(piece.name)) {
57
- throw new Error("Failed to start fight.");
58
- }
59
-
60
- return (0, _kolmafia.runCombat)();
61
- }
@@ -1,109 +1,66 @@
1
- "use strict";
2
-
3
- require("core-js/modules/es.array.slice.js");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.have = have;
9
- exports.isUsed = isUsed;
10
- exports.haveLovEnamorang = haveLovEnamorang;
11
- exports.getLovEnamorangUses = getLovEnamorangUses;
12
- exports.couldUseLoveEnamorang = couldUseLoveEnamorang;
13
- exports.getLovEnamorangMonster = getLovEnamorangMonster;
14
- exports.fightAll = fightAll;
15
- exports.LovEnamorang = void 0;
16
-
17
- var _kolmafia = require("kolmafia");
18
-
19
- var _Copier = require("../../Copier");
20
-
21
- var _lib = require("../../lib");
22
-
23
- var _property = require("../../property");
24
-
25
- var _templateString = require("../../template-string");
26
-
27
- var _templateObject, _templateObject2;
28
-
29
- function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
30
-
31
- function have() {
32
- return (0, _property.get)("loveTunnelAvailable");
1
+ import { adv1 } from "kolmafia";
2
+ import { Copier } from "../../Copier";
3
+ import { have as haveItem, haveWandererCounter, Wanderer } from "../../lib";
4
+ import { get, set } from "../../property";
5
+ import { $item, $location } from "../../template-string";
6
+ export function have() {
7
+ return get("loveTunnelAvailable");
33
8
  }
34
-
35
- function isUsed() {
36
- return (0, _property.get)("_loveTunnelUsed");
9
+ export function isUsed() {
10
+ return get("_loveTunnelUsed");
37
11
  }
38
-
39
- function haveLovEnamorang() {
40
- return (0, _lib.have)((0, _templateString.$item)(_templateObject || (_templateObject = _taggedTemplateLiteral(["LOV Enamorang"]))));
12
+ export function haveLovEnamorang() {
13
+ return haveItem($item `LOV Enamorang`);
41
14
  }
42
-
43
- function getLovEnamorangUses() {
44
- return (0, _property.get)("_enamorangs");
15
+ export function getLovEnamorangUses() {
16
+ return get("_enamorangs");
45
17
  }
46
-
47
- function couldUseLoveEnamorang() {
48
- return !(0, _lib.haveWandererCounter)(_lib.Wanderer.Enamorang) && getLovEnamorangUses() < 3 && haveLovEnamorang();
18
+ export function couldUseLoveEnamorang() {
19
+ return (!haveWandererCounter(Wanderer.Enamorang) &&
20
+ getLovEnamorangUses() < 3 &&
21
+ haveLovEnamorang());
49
22
  }
50
-
51
- function getLovEnamorangMonster() {
52
- return (0, _property.get)("enamorangMonster");
23
+ export function getLovEnamorangMonster() {
24
+ return get("enamorangMonster");
53
25
  }
54
-
55
- var LovEnamorang = new _Copier.Copier(() => couldUseLoveEnamorang(), null, () => couldUseLoveEnamorang(), () => getLovEnamorangMonster());
56
- exports.LovEnamorang = LovEnamorang;
57
-
26
+ export const LovEnamorang = new Copier(() => couldUseLoveEnamorang(), null, () => couldUseLoveEnamorang(), () => getLovEnamorangMonster());
58
27
  function equipmentChoice(equipment) {
59
- switch (equipment) {
60
- case "LOV Eardigan":
61
- return 1;
62
-
63
- case "LOV Epaulettes":
64
- return 2;
65
-
66
- case "LOV Earring":
67
- return 3;
68
- }
28
+ switch (equipment) {
29
+ case "LOV Eardigan":
30
+ return 1;
31
+ case "LOV Epaulettes":
32
+ return 2;
33
+ case "LOV Earring":
34
+ return 3;
35
+ }
69
36
  }
70
-
71
37
  function effectChoice(effect) {
72
- switch (effect) {
73
- case "Lovebotamy":
74
- return 1;
75
-
76
- case "Open Heart Surgery":
77
- return 2;
78
-
79
- case "Wandering Eye Surgery":
80
- return 3;
81
- }
38
+ switch (effect) {
39
+ case "Lovebotamy":
40
+ return 1;
41
+ case "Open Heart Surgery":
42
+ return 2;
43
+ case "Wandering Eye Surgery":
44
+ return 3;
45
+ }
82
46
  }
83
-
84
47
  function extraChoice(extra) {
85
- switch (extra) {
86
- case "LOV Enamorang":
87
- return 1;
88
-
89
- case "LOV Emotionizer":
90
- return 2;
91
-
92
- case "LOV Extraterrestrial Chocolate":
93
- return 3;
94
-
95
- case "LOV Echinacea Bouquet":
96
- return 4;
97
-
98
- case "LOV Elephant":
99
- return 5;
100
-
101
- case "toast":
102
- return 6;
103
-
104
- case null:
105
- return 7;
106
- }
48
+ switch (extra) {
49
+ case "LOV Enamorang":
50
+ return 1;
51
+ case "LOV Emotionizer":
52
+ return 2;
53
+ case "LOV Extraterrestrial Chocolate":
54
+ return 3;
55
+ case "LOV Echinacea Bouquet":
56
+ return 4;
57
+ case "LOV Elephant":
58
+ return 5;
59
+ case "toast":
60
+ return 6;
61
+ case null:
62
+ return 7;
63
+ }
107
64
  }
108
65
  /**
109
66
  * Fight all LOV monsters and get buffs/equipment.
@@ -111,19 +68,13 @@ function extraChoice(extra) {
111
68
  * @param effect Effect to take from LOV.
112
69
  * @param extra Extra item to take from LOV.
113
70
  */
114
-
115
-
116
- function fightAll(equipment, effect, extra) {
117
- (0, _property.set)("choiceAdventure1222", 1); // Entrance
118
-
119
- (0, _property.set)("choiceAdventure1223", 1); // Fight LOV Enforcer
120
-
121
- (0, _property.set)("choiceAdventure1224", equipmentChoice(equipment));
122
- (0, _property.set)("choiceAdventure1225", 1); // Fight LOV Engineer
123
-
124
- (0, _property.set)("choiceAdventure1226", effectChoice(effect));
125
- (0, _property.set)("choiceAdventure1227", 1); // Fight LOV Equivocator
126
-
127
- (0, _property.set)("choiceAdventure1228", extraChoice(extra));
128
- (0, _kolmafia.adv1)((0, _templateString.$location)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["The Tunnel of L.O.V.E."]))), 0, "");
129
- }
71
+ export function fightAll(equipment, effect, extra) {
72
+ set("choiceAdventure1222", 1); // Entrance
73
+ set("choiceAdventure1223", 1); // Fight LOV Enforcer
74
+ set("choiceAdventure1224", equipmentChoice(equipment));
75
+ set("choiceAdventure1225", 1); // Fight LOV Engineer
76
+ set("choiceAdventure1226", effectChoice(effect));
77
+ set("choiceAdventure1227", 1); // Fight LOV Equivocator
78
+ set("choiceAdventure1228", extraChoice(extra));
79
+ adv1($location `The Tunnel of L.O.V.E.`, 0, "");
80
+ }
@@ -1,86 +1,50 @@
1
- "use strict";
2
-
3
- require("core-js/modules/es.array.slice.js");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.have = have;
9
- exports.song = song;
10
- exports.songChangesLeft = songChangesLeft;
11
- exports.setSong = setSong;
12
- exports.dropProgress = dropProgress;
13
- exports.songBoomSongs = exports.item = void 0;
14
-
15
- require("core-js/modules/es.array.iterator.js");
16
-
17
- require("core-js/modules/es.object.to-string.js");
18
-
19
- var _kolmafia = require("kolmafia");
20
-
21
- var _lib = require("../../lib");
22
-
23
- var _property = require("../../property");
24
-
25
- var _templateString = require("../../template-string");
26
-
27
- var _templateObject;
28
-
29
- function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
30
-
31
- var item = (0, _templateString.$item)(_templateObject || (_templateObject = _taggedTemplateLiteral(["SongBoom\u2122 BoomBox"])));
32
- exports.item = item;
33
-
34
- function have() {
35
- return (0, _lib.have)(item);
1
+ import { cliExecute } from "kolmafia";
2
+ import { have as haveItem } from "../../lib";
3
+ import { get } from "../../property";
4
+ import { $item } from "../../template-string";
5
+ export const item = $item `SongBoom™ BoomBox`;
6
+ export function have() {
7
+ return haveItem(item);
36
8
  }
37
-
38
- var keywords = {
39
- "Eye of the Giger": "spooky",
40
- "Food Vibrations": "food",
41
- "Remainin' Alive": "dr",
42
- "These Fists Were Made for Punchin'": "damage",
43
- "Total Eclipse of Your Meat": "meat"
9
+ const keywords = {
10
+ "Eye of the Giger": "spooky",
11
+ "Food Vibrations": "food",
12
+ "Remainin' Alive": "dr",
13
+ "These Fists Were Made for Punchin'": "damage",
14
+ "Total Eclipse of Your Meat": "meat",
44
15
  };
45
- var songBoomSongs = new Set(Object.keys(keywords));
16
+ export const songBoomSongs = new Set(Object.keys(keywords));
46
17
  /**
47
18
  * Current song.
48
19
  */
49
-
50
- exports.songBoomSongs = songBoomSongs;
51
-
52
- function song() {
53
- var stored = (0, _property.get)("boomBoxSong");
54
- return songBoomSongs.has(stored) ? stored : null;
20
+ export function song() {
21
+ const stored = get("boomBoxSong");
22
+ return songBoomSongs.has(stored) ? stored : null;
55
23
  }
56
24
  /**
57
25
  * Song changes left today.
58
26
  */
59
-
60
-
61
- function songChangesLeft() {
62
- return (0, _property.get)("_boomBoxSongsLeft");
27
+ export function songChangesLeft() {
28
+ return get("_boomBoxSongsLeft");
63
29
  }
64
30
  /**
65
31
  * Change the song.
66
32
  * @param newSong Song to change to.
67
33
  */
68
-
69
-
70
- function setSong(newSong) {
71
- if (song() !== newSong) {
72
- if (songChangesLeft() === 0) throw new Error("Out of song changes!");
73
- (0, _kolmafia.cliExecute)("boombox ".concat(newSong ? keywords[newSong] : "none"));
74
- return true;
75
- } else {
76
- return false;
77
- }
34
+ export function setSong(newSong) {
35
+ if (song() !== newSong) {
36
+ if (songChangesLeft() === 0)
37
+ throw new Error("Out of song changes!");
38
+ cliExecute(`boombox ${newSong ? keywords[newSong] : "none"}`);
39
+ return true;
40
+ }
41
+ else {
42
+ return false;
43
+ }
78
44
  }
79
45
  /**
80
46
  * Progress to next song drop (e.g. gathered meat-clip).
81
47
  */
82
-
83
-
84
- function dropProgress() {
85
- return (0, _property.get)("_boomBoxFights");
86
- }
48
+ export function dropProgress() {
49
+ return get("_boomBoxFights");
50
+ }
@@ -0,0 +1,2 @@
1
+ export declare const headBuffs: readonly [Effect, Effect, Effect, Effect, Effect, Effect, Effect, Effect, Effect, Effect, Effect];
2
+ export declare function tryHead(effect: Effect): boolean;
@@ -0,0 +1,26 @@
1
+ import { cliExecute } from "kolmafia";
2
+ import { have } from "../../lib";
3
+ import { getString } from "../../property";
4
+ import { $effect } from "../../template-string";
5
+ export const headBuffs = [
6
+ $effect `Hot-Headed`,
7
+ $effect `Cold as Nice`,
8
+ $effect `A Brush with Grossness`,
9
+ $effect `Does It Have a Skull In There??`,
10
+ $effect `Oiled, Slick`,
11
+ $effect `Lack of Body-Building`,
12
+ $effect `We're All Made of Starfish`,
13
+ $effect `Pomp & Circumsands`,
14
+ $effect `Resting Beach Face`,
15
+ $effect `Do I Know You From Somewhere?`,
16
+ $effect `You Learned Something Maybe!`,
17
+ ];
18
+ export function tryHead(effect) {
19
+ if (!headBuffs.includes(effect))
20
+ return false;
21
+ const headNumber = 1 + headBuffs.indexOf(effect);
22
+ if (getString("_beachHeadsUsed").split(",").includes(headNumber.toString()))
23
+ return false;
24
+ cliExecute(effect.default);
25
+ return have(effect);
26
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Map of phylum to item that phylum drops.
3
+ */
4
+ export declare const phylumItem: Map<Phylum, Item>;
5
+ /**
6
+ * Map of drop item to phylum it drops from.
7
+ */
8
+ export declare const itemPhylum: Map<Item, Phylum>;
9
+ /**
10
+ * Return whether you have a Red-Nosed Snapper.
11
+ * @returns True if you have a Red-Nosed Snapper, false otherwise.
12
+ */
13
+ export declare function have(): boolean;
14
+ /**
15
+ * Get the phylum currently being tracked by the snapper.
16
+ * @returns Tracked phylum, or null if no phylum tracked.
17
+ */
18
+ export declare function getTrackedPhylum(): Phylum | null;
19
+ /**
20
+ * Set snapper tracking to a certain phylum.
21
+ * @param phylum Phylum to track.
22
+ */
23
+ export declare function trackPhylum(phylum: Phylum): void;
24
+ /**
25
+ * Get progress to next snapper drop.
26
+ * @returns Number of fights completed (out of 11) to reach next drop.
27
+ */
28
+ export declare function getProgress(): number;
@@ -0,0 +1,70 @@
1
+ import { cliExecute, haveFamiliar, myFamiliar, toPhylum, useFamiliar, } from "kolmafia";
2
+ import { get } from "../../property";
3
+ const familiar = Familiar.get("Red-Nosed Snapper");
4
+ /**
5
+ * Map of phylum to item that phylum drops.
6
+ */
7
+ export const phylumItem = new Map([
8
+ [Phylum.get("Beast"), Item.get("patch of extra-warm fur")],
9
+ [Phylum.get("Bug"), Item.get("a bug's lymph")],
10
+ [Phylum.get("Constellation"), Item.get("micronova")],
11
+ [Phylum.get("Construct"), Item.get("industrial lubricant")],
12
+ [Phylum.get("Demon"), Item.get("infernal snowball")],
13
+ [Phylum.get("Dude"), Item.get("human musk")],
14
+ [Phylum.get("Elemental"), Item.get("livid energy")],
15
+ [Phylum.get("Elf"), Item.get("peppermint syrup")],
16
+ [Phylum.get("Fish"), Item.get("fish sauce")],
17
+ [Phylum.get("Goblin"), Item.get("guffin")],
18
+ [Phylum.get("Hippy"), Item.get("organic potpourri")],
19
+ [Phylum.get("Hobo"), Item.get("beggin' cologne")],
20
+ [Phylum.get("Horror"), Item.get("powdered madness")],
21
+ [Phylum.get("Humanoid"), Item.get("vial of humanoid growth hormone")],
22
+ [Phylum.get("Mer-kin"), Item.get("Mer-kin eyedrops")],
23
+ [Phylum.get("Orc"), Item.get("boot flask")],
24
+ [Phylum.get("Penguin"), Item.get("envelope full of Meat")],
25
+ [Phylum.get("Pirate"), Item.get("Shantix™")],
26
+ [Phylum.get("Plant"), Item.get("goodberry")],
27
+ [Phylum.get("Slime"), Item.get("extra-strength goo")],
28
+ [Phylum.get("Undead"), Item.get("unfinished pleasure")],
29
+ [Phylum.get("Weird"), Item.get("non-Euclidean angle]")],
30
+ ]);
31
+ /**
32
+ * Map of drop item to phylum it drops from.
33
+ */
34
+ export const itemPhylum = new Map([...phylumItem].map(([phylum, item]) => [item, phylum]));
35
+ /**
36
+ * Return whether you have a Red-Nosed Snapper.
37
+ * @returns True if you have a Red-Nosed Snapper, false otherwise.
38
+ */
39
+ export function have() {
40
+ return haveFamiliar(familiar);
41
+ }
42
+ /**
43
+ * Get the phylum currently being tracked by the snapper.
44
+ * @returns Tracked phylum, or null if no phylum tracked.
45
+ */
46
+ export function getTrackedPhylum() {
47
+ const phylum = toPhylum(get("redSnapperPhylum"));
48
+ return phylum === Phylum.get("none") ? null : phylum;
49
+ }
50
+ /**
51
+ * Set snapper tracking to a certain phylum.
52
+ * @param phylum Phylum to track.
53
+ */
54
+ export function trackPhylum(phylum) {
55
+ const currentFamiliar = myFamiliar();
56
+ try {
57
+ useFamiliar(familiar);
58
+ cliExecute(`snapper ${phylum}`);
59
+ }
60
+ finally {
61
+ useFamiliar(currentFamiliar);
62
+ }
63
+ }
64
+ /**
65
+ * Get progress to next snapper drop.
66
+ * @returns Number of fights completed (out of 11) to reach next drop.
67
+ */
68
+ export function getProgress() {
69
+ return get("redSnapperProgress");
70
+ }