libram 0.6.11 → 0.6.14

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.
@@ -0,0 +1,84 @@
1
+ import { haveFamiliar, Item, itemAmount, Monster, toInt, toItem, visitUrl, } from "kolmafia";
2
+ import { get } from "../../property";
3
+ import { $familiar, $item, $items, $phylum } from "../../template-string";
4
+ /**
5
+ * The Robortender itself
6
+ */
7
+ export const familiar = $familiar `Robortender`;
8
+ /**
9
+ * @returns Whether you have the Robortender in your terrarium/available
10
+ */
11
+ export function have() {
12
+ return haveFamiliar(familiar);
13
+ }
14
+ const phylumDrops = new Map([
15
+ [$phylum `Bug`, $item `pickled grasshopper`],
16
+ // bottle of anís
17
+ [$phylum `Constellation`, Item.get(9348)],
18
+ [$phylum `Demon`, $item `bottle of novelty hot sauce`],
19
+ [$phylum `Elemental`, $item `elemental sugarcube`],
20
+ [$phylum `Elf`, $item `peppermint sprig`],
21
+ [$phylum `Fish`, $item `bottle of clam juice`],
22
+ [$phylum `Goblin`, $item `cocktail mushroom`],
23
+ [$phylum `Hippy`, $item `shot of granola liqueur`],
24
+ [$phylum `Hobo`, $item `can of cherry-flavored sterno`],
25
+ [$phylum `Horror`, $item `lump of black ichor`],
26
+ [$phylum `Humanoid`, $item `bottle of gregnadigne`],
27
+ // bottle of Crème de Fugu
28
+ [$phylum `Mer-kin`, Item.get(9358)],
29
+ [$phylum `Orc`, $item `baby oil shooter`],
30
+ [$phylum `Penguin`, $item `fish head`],
31
+ [$phylum `Pirate`, $item `limepatch`],
32
+ [$phylum `Plant`, $item `pile of dirt`],
33
+ [$phylum `Slime`, $item `slime shooter`],
34
+ [$phylum `Weird`, $item `imaginary lemon`],
35
+ ]);
36
+ /**
37
+ *
38
+ * @param target The phylum or monster you want to know the robortender drop of
39
+ * @returns The robortender drop associated with that phylum or monster
40
+ */
41
+ export function dropFrom(target) {
42
+ const phylum = target instanceof Monster ? target.phylum : target;
43
+ return phylumDrops.get(phylum) ?? $item `none`;
44
+ }
45
+ /**
46
+ * Determines the probability of getting a robortender drop based on number of drops received
47
+ * @param dropNumber The number of drops to assume you've already received; defaults to mafia's tracked amount
48
+ * @returns The probability of getting a robort drop
49
+ */
50
+ export function dropChance(dropNumber = get("_roboDrops")) {
51
+ return [1, 0.5, 0.4, 0.4, 0.4, 0.3, 0.3, 0.3][dropNumber] ?? 0.2;
52
+ }
53
+ export const minorDrinks = $items `literal grasshopper, double entendre, Phlegethon, Siberian sunrise, mentholated wine, low tide martini, shroomtini, morning dew, whiskey squeeze, great old fashioned, Gnomish sagngria, vodka stinger, extremely slippery nipple, piscatini, Churchill, soilzerac, London frog, nothingtini`;
54
+ export const majorDrinks = $items `eighth plague, single entendre, reverse Tantalus, elemental caipiroska, Feliz Navidad, Bloody Nora, moreltini, hell in a bucket, Newark, R'lyeh, Gnollish sangria, vodka barracuda, Mysterious Island iced tea, drive-by shooting, gunner's daughter, dirt julep, Simepore slime, Phil Collins`;
55
+ export const drinks = [...minorDrinks, ...majorDrinks];
56
+ /**
57
+ * @returns An array consisting of the drinks you've fed your robortender today.
58
+ */
59
+ export function currentDrinks() {
60
+ const pref = get("_roboDrinks");
61
+ if (!pref)
62
+ return [];
63
+ return pref
64
+ .split(",")
65
+ .filter((x) => x.trim())
66
+ .map((name) => toItem(name))
67
+ .filter((drink) => drinks.includes(drink));
68
+ }
69
+ /**
70
+ * @param beverage A robortender-consumable drink of choice (i.e. Drive-By Shooting, Single Entendre, etc)
71
+ * @returns A boolean; if true, the user's robortender has drunk that drink after execution. If false, it has not. This ALSO returns false if the user has not passed the function a robortender-consumable drink. If the user does not already have the beverage in their inventory, this function will not purchase the requested for you.
72
+ */
73
+ export function feed(beverage) {
74
+ if (currentDrinks().includes(beverage))
75
+ return true;
76
+ if (currentDrinks().length >= 5)
77
+ return false;
78
+ if (!drinks.includes(beverage))
79
+ return false;
80
+ if (!itemAmount(beverage))
81
+ return false;
82
+ visitUrl(`inventory.php?action=robooze&which=1&whichitem=${toInt(beverage)}`);
83
+ return currentDrinks().includes(beverage);
84
+ }
@@ -1,2 +1,8 @@
1
- import { Location, Monster } from "kolmafia";
2
- export declare function currentPredictions(withFree?: boolean): Map<Location, Monster>;
1
+ import { Location, Monster, Item } from "kolmafia";
2
+ export declare const orb: Item;
3
+ export declare function have(): boolean;
4
+ /**
5
+ * Ponders your orb (if it is able to do so safely) and then returns a Map keyed by location consisting of extant predictions
6
+ * @returns A map of all predictions currently active in an adventurer's miniature crystal ball, after visiting the "ponder" URL to refresh them.
7
+ */
8
+ export declare function ponder(): Map<Location, Monster>;
@@ -1,15 +1,22 @@
1
- import { myTurncount, toLocation, toMonster, } from "kolmafia";
1
+ import { toLocation, toMonster, availableAmount, Item, visitUrl, } from "kolmafia";
2
+ import { canVisitUrl } from "../../lib";
2
3
  import { get } from "../../property";
4
+ export const orb = Item.get("miniature crystal ball");
5
+ export function have() {
6
+ return availableAmount(orb) > 0;
7
+ }
3
8
  const parsedProp = () => get("crystalBallPredictions")
4
9
  .split("|")
5
10
  .map((element) => element.split(":"))
6
- .map(([turncount, location, monster]) => [parseInt(turncount), toLocation(location), toMonster(monster)]);
7
- export function currentPredictions(withFree = true) {
8
- const predictions = parsedProp();
9
- const freeCondition = (predictedTurns, turns) => predictedTurns === turns;
10
- const nonFreeCondition = (predictedTurns, turns) => predictedTurns + 1 === turns;
11
- return new Map(predictions
12
- .filter(([turncount]) => nonFreeCondition(turncount, myTurncount()) ||
13
- (withFree && freeCondition(turncount, myTurncount())))
14
- .map(([, location, monster]) => [location, monster]));
11
+ .map(([, location, monster]) => [toLocation(location), toMonster(monster)]);
12
+ /**
13
+ * Ponders your orb (if it is able to do so safely) and then returns a Map keyed by location consisting of extant predictions
14
+ * @returns A map of all predictions currently active in an adventurer's miniature crystal ball, after visiting the "ponder" URL to refresh them.
15
+ */
16
+ export function ponder() {
17
+ if (!have())
18
+ return new Map();
19
+ if (canVisitUrl())
20
+ visitUrl("inventory.php?ponder=1", false);
21
+ return new Map(parsedProp());
15
22
  }
@@ -28,9 +28,9 @@ export declare function monstersReminisced(): Monster[];
28
28
  */
29
29
  export declare function reminisce(monster: Monster): boolean;
30
30
  /**
31
- * Find a reminiscable monster that meets certain criteria and optionally maximizes a valuation function.
32
- * @param criteria A function for delineating which monsters are "fair game" for the search.
31
+ * This function efficiently evaluates all of an adventurer's possibly reminiscable monsters, placing them through a filtering criteria and evaluating them based on a passed function.
32
+ * @param criteria A filtering function for delineating which monsters are "fair game" for the search, such as "is this monster free".
33
33
  * @param value A function for deciding which monsters are "better" than others.
34
- * @returns A monster that fulfills the criteria function and maximizes the value function.
34
+ * @returns A singular monster that fulfills the criteria function and maximizes the value function.
35
35
  */
36
36
  export declare function findMonster(criteria: (monster: Monster) => boolean, value?: (monster: Monster) => number): Monster | null;
@@ -59,15 +59,16 @@ export function reminisce(monster) {
59
59
  return monstersReminisced().includes(monster);
60
60
  }
61
61
  /**
62
- * Find a reminiscable monster that meets certain criteria and optionally maximizes a valuation function.
63
- * @param criteria A function for delineating which monsters are "fair game" for the search.
62
+ * This function efficiently evaluates all of an adventurer's possibly reminiscable monsters, placing them through a filtering criteria and evaluating them based on a passed function.
63
+ * @param criteria A filtering function for delineating which monsters are "fair game" for the search, such as "is this monster free".
64
64
  * @param value A function for deciding which monsters are "better" than others.
65
- * @returns A monster that fulfills the criteria function and maximizes the value function.
65
+ * @returns A singular monster that fulfills the criteria function and maximizes the value function.
66
66
  */
67
67
  export function findMonster(criteria, value = () => 1) {
68
68
  if (!have() || reminiscesLeft() === 0)
69
69
  return null;
70
- return (availableLocketMonsters()
71
- .filter(criteria)
72
- .sort((a, b) => value(b) - value(a))[0] ?? null);
70
+ const options = availableLocketMonsters().filter(criteria);
71
+ if (!options.length)
72
+ return null;
73
+ return options.reduce((a, b) => (value(a) > value(b) ? a : b));
73
74
  }
@@ -0,0 +1,14 @@
1
+ export declare const goose: import("kolmafia").Familiar;
2
+ export declare function have(): boolean;
3
+ export declare function currentExperience(): number;
4
+ export declare function currentWeight(): number;
5
+ export declare function expectedDrones(weight?: number): number;
6
+ /**
7
+ * @param weight The goose weight you care about; defaults to current weight
8
+ * @returns In Grey You, returns the fullstats you'll gain from goose levelling; outside Grey You, returns substats
9
+ */
10
+ export declare function expectedExperience(weight?: number): number;
11
+ export declare function expectedMeat(weight?: number): number;
12
+ export declare function hasMeatified(): boolean;
13
+ export declare function fightsUntil(target: number, bonusExperience?: number): number;
14
+ export declare function currentDrones(): number;
@@ -0,0 +1,44 @@
1
+ import { toInt, myClass } from "kolmafia";
2
+ import { have as have_ } from "../../lib";
3
+ import { get as getModifier } from "../../modifier";
4
+ import { get } from "../../property";
5
+ import { $familiar, $item, $skill } from "../../template-string";
6
+ export const goose = $familiar `Grey Goose`;
7
+ export function have() {
8
+ return have_(goose);
9
+ }
10
+ export function currentExperience() {
11
+ return goose.experience ||
12
+ (have_($familiar `Shorter-Order Cook`) && !get("gooseReprocessed"))
13
+ ? 81 + (have_($item `blue plate`) ? 19 : 0)
14
+ : 0;
15
+ }
16
+ export function currentWeight() {
17
+ return Math.min(Math.floor(Math.sqrt(currentExperience())), 20);
18
+ }
19
+ export function expectedDrones(weight = currentWeight()) {
20
+ return Math.max(0, weight - 5);
21
+ }
22
+ /**
23
+ * @param weight The goose weight you care about; defaults to current weight
24
+ * @returns In Grey You, returns the fullstats you'll gain from goose levelling; outside Grey You, returns substats
25
+ */
26
+ export function expectedExperience(weight = currentWeight()) {
27
+ return Math.pow(Math.max(weight - 5, 0), toInt(myClass()) === 27 ? 2 : 3);
28
+ }
29
+ export function expectedMeat(weight = currentWeight()) {
30
+ return Math.pow(Math.max(weight - 5, 0), 4);
31
+ }
32
+ export function hasMeatified() {
33
+ return get("_meatifyMatterUsed");
34
+ }
35
+ export function fightsUntil(target, bonusExperience = getModifier("Familiar Experience")) {
36
+ const diff = target - currentWeight();
37
+ if (diff <= 0)
38
+ return 0;
39
+ return Math.ceil(diff /
40
+ (1 + bonusExperience + (have_($skill `Testudinal Teachings`) ? 1 / 6 : 0)));
41
+ }
42
+ export function currentDrones() {
43
+ return get("gooseDronesRemaining");
44
+ }
@@ -5,6 +5,7 @@ import * as ObtuseAngel from "./2011/ObtuseAngel";
5
5
  import * as StompingBoots from "./2011/StompingBoots";
6
6
  import * as RainDoh from "./2012/RainDoh";
7
7
  import * as FloristFriar from "./2013/Florist";
8
+ import * as CrimboShrub from "./2014/CrimboShrub";
8
9
  import * as DNALab from "./2014/DNALab";
9
10
  import * as WinterGarden from "./2014/WinterGarden";
10
11
  import * as ChateauMantegna from "./2015/ChateauMantegna";
@@ -14,6 +15,7 @@ import * as Witchess from "./2016/Witchess";
14
15
  import * as AsdonMartin from "./2017/AsdonMartin";
15
16
  import * as MummingTrunk from "./2017/MummingTrunk";
16
17
  import * as Pantogram from "./2017/Pantogram";
18
+ import * as Robortender from "./2017/Robortender";
17
19
  import * as TunnelOfLove from "./2017/TunnelOfLove";
18
20
  import * as Latte from "./2018/LatteLoversMembersMug";
19
21
  import * as SongBoom from "./2018/SongBoom";
@@ -24,6 +26,7 @@ import * as RetroCape from "./2020/RetroCape";
24
26
  import * as CrystalBall from "./2021/CrystalBall";
25
27
  import * as DaylightShavings from "./2021/DaylightShavings";
26
28
  import * as CombatLoversLocket from "./2022/CombatLoversLocket";
27
- export { AsdonMartin, Bandersnatch, BeachComb, ChateauMantegna, CombatLoversLocket, CrownOfThrones, CrystalBall, DaylightShavings, DNALab, FloristFriar, Guzzlr, Latte, MayoClinic, MummingTrunk, ObtuseAngel, Pantogram, RainDoh, RetroCape, Snapper, SongBoom, SourceTerminal, SpookyPutty, StompingBoots, TunnelOfLove, WinterGarden, Witchess, };
29
+ import * as GreyGoose from "./2022/GreyGoose";
30
+ export { AsdonMartin, Bandersnatch, BeachComb, ChateauMantegna, CombatLoversLocket, CrimboShrub, CrownOfThrones, CrystalBall, DaylightShavings, DNALab, FloristFriar, GreyGoose, Guzzlr, Latte, MayoClinic, MummingTrunk, ObtuseAngel, Pantogram, RainDoh, RetroCape, Robortender, Snapper, SongBoom, SourceTerminal, SpookyPutty, StompingBoots, TunnelOfLove, WinterGarden, Witchess, };
28
31
  export * from "./putty-likes";
29
32
  export * from "./LibramSummon";
@@ -5,6 +5,7 @@ import * as ObtuseAngel from "./2011/ObtuseAngel";
5
5
  import * as StompingBoots from "./2011/StompingBoots";
6
6
  import * as RainDoh from "./2012/RainDoh";
7
7
  import * as FloristFriar from "./2013/Florist";
8
+ import * as CrimboShrub from "./2014/CrimboShrub";
8
9
  import * as DNALab from "./2014/DNALab";
9
10
  import * as WinterGarden from "./2014/WinterGarden";
10
11
  import * as ChateauMantegna from "./2015/ChateauMantegna";
@@ -14,6 +15,7 @@ import * as Witchess from "./2016/Witchess";
14
15
  import * as AsdonMartin from "./2017/AsdonMartin";
15
16
  import * as MummingTrunk from "./2017/MummingTrunk";
16
17
  import * as Pantogram from "./2017/Pantogram";
18
+ import * as Robortender from "./2017/Robortender";
17
19
  import * as TunnelOfLove from "./2017/TunnelOfLove";
18
20
  import * as Latte from "./2018/LatteLoversMembersMug";
19
21
  import * as SongBoom from "./2018/SongBoom";
@@ -24,6 +26,7 @@ import * as RetroCape from "./2020/RetroCape";
24
26
  import * as CrystalBall from "./2021/CrystalBall";
25
27
  import * as DaylightShavings from "./2021/DaylightShavings";
26
28
  import * as CombatLoversLocket from "./2022/CombatLoversLocket";
27
- export { AsdonMartin, Bandersnatch, BeachComb, ChateauMantegna, CombatLoversLocket, CrownOfThrones, CrystalBall, DaylightShavings, DNALab, FloristFriar, Guzzlr, Latte, MayoClinic, MummingTrunk, ObtuseAngel, Pantogram, RainDoh, RetroCape, Snapper, SongBoom, SourceTerminal, SpookyPutty, StompingBoots, TunnelOfLove, WinterGarden, Witchess, };
29
+ import * as GreyGoose from "./2022/GreyGoose";
30
+ export { AsdonMartin, Bandersnatch, BeachComb, ChateauMantegna, CombatLoversLocket, CrimboShrub, CrownOfThrones, CrystalBall, DaylightShavings, DNALab, FloristFriar, GreyGoose, Guzzlr, Latte, MayoClinic, MummingTrunk, ObtuseAngel, Pantogram, RainDoh, RetroCape, Robortender, Snapper, SongBoom, SourceTerminal, SpookyPutty, StompingBoots, TunnelOfLove, WinterGarden, Witchess, };
28
31
  export * from "./putty-likes";
29
32
  export * from "./LibramSummon";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libram",
3
- "version": "0.6.11",
3
+ "version": "0.6.14",
4
4
  "description": "JavaScript helper library for KoLmafia",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -45,7 +45,7 @@
45
45
  "eslint-import-resolver-typescript": "^2.5.0",
46
46
  "eslint-plugin-import": "^2.25.4",
47
47
  "eslint-plugin-jest": "^25.2.3",
48
- "eslint-plugin-libram": "^0.2.9",
48
+ "eslint-plugin-libram": "^0.2.11",
49
49
  "husky": "^4.3.6",
50
50
  "java-parser": "^1.4.0",
51
51
  "jest": "^27.1.0",
@@ -63,6 +63,7 @@
63
63
  "@babel/runtime-corejs3": "^7.17.2",
64
64
  "core-js": "^3.21.0",
65
65
  "kolmafia": "^2.1.1",
66
+ "libram": "^0.6.12",
66
67
  "lodash": "^4.17.21"
67
68
  },
68
69
  "husky": {