libram 0.6.9 → 0.6.12
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/ascend.d.ts +6 -2
- package/dist/ascend.js +52 -12
- package/dist/challengePaths/2015/CommunityService.d.ts +0 -1
- package/dist/challengePaths/2015/CommunityService.js +6 -6
- package/dist/combat.d.ts +1 -1
- package/dist/combat.js +6 -0
- package/dist/counter.d.ts +9 -3
- package/dist/counter.js +14 -6
- package/dist/diet/index.d.ts +2 -0
- package/dist/diet/index.js +2 -2
- package/dist/lib.d.ts +12 -1
- package/dist/lib.js +42 -6
- package/dist/mood.d.ts +3 -2
- package/dist/mood.js +21 -15
- package/dist/propertyTypes.d.ts +4 -4
- package/dist/propertyTypes.js +4 -4
- package/dist/resources/2013/Florist.d.ts +2 -2
- package/dist/resources/2013/Florist.js +4 -4
- package/dist/resources/2014/CrimboShrub.d.ts +30 -0
- package/dist/resources/2014/CrimboShrub.js +65 -0
- package/dist/resources/2017/Robortender.d.ts +33 -0
- package/dist/resources/2017/Robortender.js +84 -0
- package/dist/resources/2021/CrystalBall.d.ts +8 -2
- package/dist/resources/2021/CrystalBall.js +17 -10
- package/dist/resources/2022/CombatLoversLocket.d.ts +3 -3
- package/dist/resources/2022/CombatLoversLocket.js +7 -6
- package/dist/resources/2022/GreyGoose.d.ts +14 -0
- package/dist/resources/2022/GreyGoose.js +44 -0
- package/dist/resources/index.d.ts +4 -1
- package/dist/resources/index.js +4 -1
- package/package.json +2 -2
package/dist/ascend.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Class, Item } from "kolmafia";
|
|
1
|
+
import { Skill, Class, Item } from "kolmafia";
|
|
2
2
|
import { Path } from "./Path";
|
|
3
3
|
import { Ceiling, Desk, Nightstand } from "./resources/2015/ChateauMantegna";
|
|
4
4
|
export declare enum Lifestyle {
|
|
@@ -7,6 +7,10 @@ export declare enum Lifestyle {
|
|
|
7
7
|
normal = 2,
|
|
8
8
|
hardcore = 3
|
|
9
9
|
}
|
|
10
|
+
export declare class AscendError extends Error {
|
|
11
|
+
cause?: Skill | Item | Class | Path;
|
|
12
|
+
constructor(cause?: Skill | Item | Class | Path);
|
|
13
|
+
}
|
|
10
14
|
declare type MoonSign = number | "mongoose" | "wallaby" | "vole" | "platypus" | "opossum" | "marmot" | "wombat" | "blender" | "packrat" | "degrassi" | "degrassi knoll" | "friendly degrassi knoll" | "knoll" | "canada" | "canadia" | "little canadia" | "gnomads" | "gnomish" | "gnomish gnomads camp";
|
|
11
15
|
/**
|
|
12
16
|
* Hops the gash, perming no skills
|
|
@@ -17,7 +21,7 @@ declare type MoonSign = number | "mongoose" | "wallaby" | "vole" | "platypus" |
|
|
|
17
21
|
* @param consumable From the astral deli. Pick the container item, not the product.
|
|
18
22
|
* @param pet From the astral pet store.
|
|
19
23
|
*/
|
|
20
|
-
export declare function ascend(path: Path, playerClass: Class, lifestyle: Lifestyle, moon: MoonSign, consumable?: Item | undefined, pet?: Item | undefined): void;
|
|
24
|
+
export declare function ascend(path: Path, playerClass: Class, lifestyle: Lifestyle, moon: MoonSign, consumable?: Item | undefined, pet?: Item | undefined, permSkills?: Map<Skill, Lifestyle> | undefined): void;
|
|
21
25
|
declare const worksheds: readonly ["warbear LP-ROM burner", "warbear jackhammer drill press", "warbear induction oven", "warbear high-efficiency still", "warbear chemistry lab", "warbear auto-anvil", "spinning wheel", "snow machine", "Little Geneticist DNA-Splicing Lab", "portable Mayo Clinic", "Asdon Martin keyfob", "diabolic pizza cube", "cold medicine cabinet"];
|
|
22
26
|
declare type Workshed = typeof worksheds[number];
|
|
23
27
|
declare const gardens: readonly ["packet of pumpkin seeds", "Peppermint Pip Packet", "packet of dragon's teeth", "packet of beer seeds", "packet of winter seeds", "packet of thanksgarden seeds", "packet of tall grass seeds", "packet of mushroom spores"];
|
package/dist/ascend.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { containsText, eudoraItem, getCampground, getWorkshed, Item, toInt, use, visitUrl, xpath, } from "kolmafia";
|
|
1
|
+
import { Skill, Class, containsText, eudoraItem, getCampground, getWorkshed, Item, toInt, use, visitUrl, xpath, haveSkill, } from "kolmafia";
|
|
2
2
|
import { ChateauMantegna } from "./resources";
|
|
3
3
|
import { $item, $items, $stat } from "./template-string";
|
|
4
4
|
export var Lifestyle;
|
|
@@ -8,6 +8,32 @@ export var Lifestyle;
|
|
|
8
8
|
Lifestyle[Lifestyle["normal"] = 2] = "normal";
|
|
9
9
|
Lifestyle[Lifestyle["hardcore"] = 3] = "hardcore";
|
|
10
10
|
})(Lifestyle || (Lifestyle = {}));
|
|
11
|
+
export class AscendError extends Error {
|
|
12
|
+
cause;
|
|
13
|
+
constructor(cause) {
|
|
14
|
+
if (!cause) {
|
|
15
|
+
super("Failed to ascend--do you have a pending trade offer?");
|
|
16
|
+
}
|
|
17
|
+
else if (cause instanceof Skill) {
|
|
18
|
+
const reason = cause.permable
|
|
19
|
+
? haveSkill(cause)
|
|
20
|
+
? "invalid for mysterious reasons"
|
|
21
|
+
: "not a skill you currently know"
|
|
22
|
+
: "unpermable";
|
|
23
|
+
super(`Skill ${cause} is ${reason}!`);
|
|
24
|
+
}
|
|
25
|
+
else if (cause instanceof Item) {
|
|
26
|
+
super(`Invalid astral item: ${cause}!`);
|
|
27
|
+
}
|
|
28
|
+
else if (cause instanceof Class) {
|
|
29
|
+
super(`Invalid class ${cause} for this path!`);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
super(`Invalid path ${cause}!`);
|
|
33
|
+
}
|
|
34
|
+
this.cause = cause;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
11
37
|
function toMoonId(moon, playerClass) {
|
|
12
38
|
if (typeof moon === "number")
|
|
13
39
|
return moon;
|
|
@@ -68,28 +94,34 @@ function toMoonId(moon, playerClass) {
|
|
|
68
94
|
* @param consumable From the astral deli. Pick the container item, not the product.
|
|
69
95
|
* @param pet From the astral pet store.
|
|
70
96
|
*/
|
|
71
|
-
export function ascend(path, playerClass, lifestyle, moon, consumable = $item `astral six-pack`, pet = undefined) {
|
|
72
|
-
if (!containsText(visitUrl("charpane.php"), "Astral Spirit")) {
|
|
73
|
-
visitUrl("ascend.php?action=ascend&confirm=on&confirm2=on");
|
|
74
|
-
}
|
|
75
|
-
if (!containsText(visitUrl("charpane.php"), "Astral Spirit")) {
|
|
76
|
-
throw new Error("Failed to ascend.");
|
|
77
|
-
}
|
|
97
|
+
export function ascend(path, playerClass, lifestyle, moon, consumable = $item `astral six-pack`, pet = undefined, permSkills = undefined) {
|
|
78
98
|
if (!path.classes.includes(playerClass)) {
|
|
79
|
-
throw new
|
|
99
|
+
throw new AscendError(playerClass);
|
|
80
100
|
}
|
|
81
101
|
if (path.id < 0)
|
|
82
|
-
throw new
|
|
102
|
+
throw new AscendError(path);
|
|
83
103
|
const moonId = toMoonId(moon, playerClass);
|
|
84
104
|
if (moonId < 1 || moonId > 9)
|
|
85
105
|
throw new Error(`Invalid moon ${moon}`);
|
|
86
106
|
if (consumable &&
|
|
87
107
|
!$items `astral six-pack, astral hot dog dinner, [10882]carton of astral energy drinks`.includes(consumable)) {
|
|
88
|
-
throw new
|
|
108
|
+
throw new AscendError(consumable);
|
|
89
109
|
}
|
|
90
110
|
if (pet &&
|
|
91
111
|
!$items `astral bludgeon, astral shield, astral chapeau, astral bracer, astral longbow, astral shorts, astral mace, astral ring, astral statuette, astral pistol, astral mask, astral pet sweater, astral shirt, astral belt`.includes(pet)) {
|
|
92
|
-
throw new
|
|
112
|
+
throw new AscendError(pet);
|
|
113
|
+
}
|
|
114
|
+
const illegalSkill = permSkills
|
|
115
|
+
? Array.from(permSkills.keys()).find((skill) => !skill.permable || !haveSkill(skill))
|
|
116
|
+
: undefined;
|
|
117
|
+
if (illegalSkill) {
|
|
118
|
+
throw new AscendError(illegalSkill);
|
|
119
|
+
}
|
|
120
|
+
if (!containsText(visitUrl("charpane.php"), "Astral Spirit")) {
|
|
121
|
+
visitUrl("ascend.php?action=ascend&confirm=on&confirm2=on");
|
|
122
|
+
}
|
|
123
|
+
if (!containsText(visitUrl("charpane.php"), "Astral Spirit")) {
|
|
124
|
+
throw new AscendError();
|
|
93
125
|
}
|
|
94
126
|
visitUrl("afterlife.php?action=pearlygates");
|
|
95
127
|
if (consumable) {
|
|
@@ -97,6 +129,14 @@ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `a
|
|
|
97
129
|
}
|
|
98
130
|
if (pet)
|
|
99
131
|
visitUrl(`afterlife.php?action=buyarmory&whichitem=${toInt(pet)}`);
|
|
132
|
+
if (permSkills) {
|
|
133
|
+
for (const [skill, permLevel] of permSkills.entries()) {
|
|
134
|
+
if (permLevel !== Lifestyle.casual) {
|
|
135
|
+
const permText = permLevel === Lifestyle.hardcore ? "hcperm" : "scperm";
|
|
136
|
+
visitUrl(`afterlife.php?action=${permText}&whichskill=${toInt(skill)}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
100
140
|
visitUrl(`afterlife.php?action=ascend&confirmascend=1&whichsign=${moonId}&gender=2&whichclass=${toInt(playerClass)}&whichpath=${path.id}&asctype=${lifestyle}&nopetok=1&noskillsok=1&lamepathok=1&lamesignok=1&pwd`, true);
|
|
101
141
|
}
|
|
102
142
|
const worksheds = [
|
|
@@ -52,7 +52,6 @@ export default class CommunityService {
|
|
|
52
52
|
/**
|
|
53
53
|
* Wrapper function that prepares for a test and then completes it, adding time and turn details to the log.
|
|
54
54
|
* @param prepare A function that does all necessary preparations for this CS test, including choosing your outfit. Optionally returns the number of turns you expect to spend preparing for the test.
|
|
55
|
-
* @param beCertain Whether we should check council.php instead of mafia to determine the test cost and whether the test is complete.
|
|
56
55
|
* @param maxTurns We will run the test iff the predicted/actual turns is less than or equal to this parameter.
|
|
57
56
|
* @returns "completed", "failed", or "already completed".
|
|
58
57
|
*/
|
|
@@ -107,7 +107,6 @@ export default class CommunityService {
|
|
|
107
107
|
/**
|
|
108
108
|
* Wrapper function that prepares for a test and then completes it, adding time and turn details to the log.
|
|
109
109
|
* @param prepare A function that does all necessary preparations for this CS test, including choosing your outfit. Optionally returns the number of turns you expect to spend preparing for the test.
|
|
110
|
-
* @param beCertain Whether we should check council.php instead of mafia to determine the test cost and whether the test is complete.
|
|
111
110
|
* @param maxTurns We will run the test iff the predicted/actual turns is less than or equal to this parameter.
|
|
112
111
|
* @returns "completed", "failed", or "already completed".
|
|
113
112
|
*/
|
|
@@ -128,7 +127,7 @@ export default class CommunityService {
|
|
|
128
127
|
const turns = this._actualCost(council);
|
|
129
128
|
if (!turns)
|
|
130
129
|
return "already completed";
|
|
131
|
-
if (turns > Math.
|
|
130
|
+
if (turns > Math.min(maxTurns, myAdventures())) {
|
|
132
131
|
return "failed";
|
|
133
132
|
}
|
|
134
133
|
if (!this.do())
|
|
@@ -176,16 +175,17 @@ export default class CommunityService {
|
|
|
176
175
|
const { type, predictedTurns, turnCost, seconds } = testEntry;
|
|
177
176
|
if (type === "test") {
|
|
178
177
|
print(`We predicted the ${testName} test would take ${predictedTurns} turns, ${predictedTurns === turnCost ? "and" : "but"} it took ${turnCost} turns.`, colour);
|
|
179
|
-
print(`${testName} took ${seconds} seconds.`, colour);
|
|
178
|
+
print(`${testName} took ${seconds.toFixed(1)} seconds.`, colour);
|
|
180
179
|
}
|
|
181
180
|
else {
|
|
182
181
|
if (!(predictedTurns === 0 && turnCost === 0)) {
|
|
183
182
|
print(`We predicted the task ${testName} would take ${predictedTurns} turns, ${predictedTurns === turnCost ? "and" : "but"} it took ${turnCost} turns.`, colour);
|
|
184
|
-
print(`The task ${testName} took ${seconds} seconds.`, colour);
|
|
185
183
|
}
|
|
184
|
+
print(`The task ${testName} took ${seconds.toFixed(1)} seconds.`, colour);
|
|
186
185
|
}
|
|
187
186
|
}
|
|
188
|
-
|
|
187
|
+
const totalTime = sum(logEntries, ([, testEntry]) => testEntry.seconds);
|
|
188
|
+
print(`All together, you have spent ${totalTime.toFixed(1)} seconds during this Community Service run`, colour);
|
|
189
189
|
}
|
|
190
190
|
// Below, we have the tests themselves.
|
|
191
191
|
static HP = new CommunityService(1, "HP", "Donate Blood", () => 60 - Math.floor((myMaxhp() - myBuffedstat($stat `muscle`) - 3) / 30), new Requirement(["HP"], {}));
|
|
@@ -251,7 +251,7 @@ export default class CommunityService {
|
|
|
251
251
|
static HotRes = new CommunityService(10, "Hot Resistance", "Clean Steam Tunnels", () => 60 - getModifier("Hot Resistance"), new Requirement(["Hot Resistance"], {}));
|
|
252
252
|
static CoilWire = new CommunityService(11, "Coil Wire", "Coil Wire", () => 60, new Requirement([], {}));
|
|
253
253
|
static donate = () => {
|
|
254
|
-
|
|
254
|
+
visitCouncil();
|
|
255
255
|
visitUrl("choice.php?whichchoice=1089&option=30");
|
|
256
256
|
};
|
|
257
257
|
}
|
package/dist/combat.d.ts
CHANGED
|
@@ -103,7 +103,7 @@ export declare class Macro {
|
|
|
103
103
|
* @param ifTrue Continuation if the condition is true.
|
|
104
104
|
* @returns {Macro} This object itself.
|
|
105
105
|
*/
|
|
106
|
-
if_(condition: string | Monster | Effect | Skill | Item | Location | Class | Stat, ifTrue: string | Macro): this;
|
|
106
|
+
if_(condition: string | Monster | Monster[] | Effect | Skill | Item | Location | Class | Stat, ifTrue: string | Macro): this;
|
|
107
107
|
/**
|
|
108
108
|
* Create a new macro with an "if" statement.
|
|
109
109
|
* @param condition The BALLS condition for the if statement.
|
package/dist/combat.js
CHANGED
|
@@ -211,6 +211,12 @@ export class Macro {
|
|
|
211
211
|
if (condition instanceof Monster) {
|
|
212
212
|
ballsCondition = `monsterid ${condition.id}`;
|
|
213
213
|
}
|
|
214
|
+
else if (condition instanceof Array) {
|
|
215
|
+
ballsCondition = condition
|
|
216
|
+
.map((mon) => `monsterid ${mon.id}`)
|
|
217
|
+
.join(" || ");
|
|
218
|
+
ballsCondition = `(${ballsCondition})`;
|
|
219
|
+
}
|
|
214
220
|
else if (condition instanceof Effect) {
|
|
215
221
|
ballsCondition = `haseffect ${toInt(condition)}`;
|
|
216
222
|
}
|
package/dist/counter.d.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns
|
|
2
|
+
* Returns Infinity for counters that do not exist, and otherwise returns the duration of the counter
|
|
3
3
|
* @param counter The name of the counter in question
|
|
4
|
-
* @returns
|
|
4
|
+
* @returns Infinity if the counter does not exist; otherwise returns the duration of the counter
|
|
5
5
|
*/
|
|
6
|
-
export declare function get(counter: string): number
|
|
6
|
+
export declare function get(counter: string): number;
|
|
7
|
+
/**
|
|
8
|
+
* The world is everything that is the case. This determines which counters are the case.
|
|
9
|
+
* @param counter The name of the counter in question
|
|
10
|
+
* @returns True for counters which currently exist; false for those which do not
|
|
11
|
+
*/
|
|
12
|
+
export declare function exists(counter: string): boolean;
|
|
7
13
|
/**
|
|
8
14
|
* Creates a manual counter with specified name and duration
|
|
9
15
|
* @param counter Name of the counter to manually create
|
package/dist/counter.js
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import { cliExecute, getCounter, getCounters } from "kolmafia";
|
|
2
2
|
/**
|
|
3
|
-
* Returns
|
|
3
|
+
* Returns Infinity for counters that do not exist, and otherwise returns the duration of the counter
|
|
4
4
|
* @param counter The name of the counter in question
|
|
5
|
-
* @returns
|
|
5
|
+
* @returns Infinity if the counter does not exist; otherwise returns the duration of the counter
|
|
6
6
|
*/
|
|
7
7
|
export function get(counter) {
|
|
8
8
|
const value = getCounter(counter);
|
|
9
|
-
//getCounter returns -1 for counters that don't exist, but it also returns -1 for counters whose value is -1
|
|
9
|
+
// getCounter returns -1 for counters that don't exist, but it also returns -1 for counters whose value is -1
|
|
10
10
|
if (value === -1) {
|
|
11
|
-
//if we have a counter with value -1, we check to see if that counter exists via getCounters()
|
|
12
|
-
//We return null if it doesn't exist
|
|
13
|
-
return getCounters(counter, -1, -1).trim() === "" ?
|
|
11
|
+
// if we have a counter with value -1, we check to see if that counter exists via getCounters()
|
|
12
|
+
// We return null if it doesn't exist
|
|
13
|
+
return getCounters(counter, -1, -1).trim() === "" ? Infinity : -1;
|
|
14
14
|
}
|
|
15
15
|
return value;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* The world is everything that is the case. This determines which counters are the case.
|
|
19
|
+
* @param counter The name of the counter in question
|
|
20
|
+
* @returns True for counters which currently exist; false for those which do not
|
|
21
|
+
*/
|
|
22
|
+
export function exists(counter) {
|
|
23
|
+
return (getCounter(counter) !== -1 || getCounters(counter, -1, -1).trim() !== "");
|
|
24
|
+
}
|
|
17
25
|
/**
|
|
18
26
|
* Creates a manual counter with specified name and duration
|
|
19
27
|
* @param counter Name of the counter to manually create
|
package/dist/diet/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ declare type MenuItemOptions<T> = {
|
|
|
10
10
|
priceOverride?: number;
|
|
11
11
|
mayo?: Item;
|
|
12
12
|
data?: T;
|
|
13
|
+
useRetrievePrice?: boolean;
|
|
13
14
|
};
|
|
14
15
|
export declare class MenuItem<T> {
|
|
15
16
|
item: Item;
|
|
@@ -21,6 +22,7 @@ export declare class MenuItem<T> {
|
|
|
21
22
|
priceOverride?: number;
|
|
22
23
|
mayo?: Item;
|
|
23
24
|
data?: T;
|
|
25
|
+
static defaultPriceFunction: (item: Item) => number;
|
|
24
26
|
static defaultOptions<T>(): Map<Item, MenuItemOptions<T>>;
|
|
25
27
|
/**
|
|
26
28
|
* Construct a new menu item, possibly with extra properties. Items in MenuItem.defaultOptions have intelligent defaults.
|
package/dist/diet/index.js
CHANGED
|
@@ -60,6 +60,7 @@ export class MenuItem {
|
|
|
60
60
|
priceOverride;
|
|
61
61
|
mayo;
|
|
62
62
|
data;
|
|
63
|
+
static defaultPriceFunction = (item) => npcPrice(item) > 0 ? npcPrice(item) : mallPrice(item);
|
|
63
64
|
static defaultOptions() {
|
|
64
65
|
return new Map([
|
|
65
66
|
[
|
|
@@ -159,8 +160,7 @@ export class MenuItem {
|
|
|
159
160
|
return this.item.toString();
|
|
160
161
|
}
|
|
161
162
|
price() {
|
|
162
|
-
return
|
|
163
|
-
(npcPrice(this.item) > 0 ? npcPrice(this.item) : mallPrice(this.item)));
|
|
163
|
+
return this.priceOverride ?? MenuItem.defaultPriceFunction?.(this.item);
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
const organs = ["food", "booze", "spleen item"];
|
package/dist/lib.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @module GeneralLibrary */
|
|
2
2
|
import "core-js/modules/es.object.entries";
|
|
3
3
|
import "core-js/features/array/flat";
|
|
4
|
-
import { Effect, Familiar, Item, Location, Monster, Servant, Skill, Thrall } from "kolmafia";
|
|
4
|
+
import { Effect, Element, Familiar, Item, Location, Monster, Servant, Skill, Thrall } from "kolmafia";
|
|
5
5
|
/**
|
|
6
6
|
* Returns the current maximum Accordion Thief songs the player can have in their head
|
|
7
7
|
*
|
|
@@ -269,3 +269,14 @@ export declare function findLeprechaunMultiplier(familiar: Familiar): number;
|
|
|
269
269
|
export declare function findFairyMultiplier(familiar: Familiar): number;
|
|
270
270
|
export declare const holidayWanderers: Map<string, Monster[]>;
|
|
271
271
|
export declare function getTodaysHolidayWanderers(): Monster[];
|
|
272
|
+
/**
|
|
273
|
+
* Determines & returns whether or not we can safely call visitUrl(), based on whether we're in a fight, multi-fight, choice, etc
|
|
274
|
+
*/
|
|
275
|
+
export declare function canVisitUrl(): boolean;
|
|
276
|
+
/**
|
|
277
|
+
* Calculate damage taken from a specific element after factoring in resistance
|
|
278
|
+
* @param baseDamage
|
|
279
|
+
* @param element
|
|
280
|
+
* @returns damage after factoring in resistances
|
|
281
|
+
*/
|
|
282
|
+
export declare function damageTakenByElement(baseDamage: number, element: Element): number;
|
package/dist/lib.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/** @module GeneralLibrary */
|
|
2
2
|
import "core-js/modules/es.object.entries";
|
|
3
3
|
import "core-js/features/array/flat";
|
|
4
|
-
import { appearanceRates, autosellPrice, availableAmount, booleanModifier, cliExecute, Effect, Familiar, fullnessLimit, getCampground, getCounters, getPlayerId, getPlayerName, getRelated, haveEffect, haveFamiliar, haveServant, haveSkill, holiday, inebrietyLimit, Item, Location, mallPrice, Monster, myEffects, myFamiliar, myFullness, myInebriety, myPath, mySpleenUse, myThrall, myTurncount, numericModifier, Servant, Skill, spleenLimit, Thrall, toItem, toSkill, totalTurnsPlayed, } from "kolmafia";
|
|
4
|
+
import { appearanceRates, autosellPrice, availableAmount, booleanModifier, choiceFollowsFight, cliExecute, currentRound, Effect, elementalResistance, Familiar, fullnessLimit, getCampground, getCounters, getPlayerId, getPlayerName, getRelated, handlingChoice, haveEffect, haveFamiliar, haveServant, haveSkill, holiday, inebrietyLimit, inMultiFight, Item, Location, mallPrice, Monster, myEffects, myFamiliar, myFullness, myInebriety, myPath, mySpleenUse, myThrall, myTurncount, numericModifier, Servant, Skill, spleenLimit, Thrall, toItem, toSkill, totalTurnsPlayed, } from "kolmafia";
|
|
5
5
|
import { get } from "./property";
|
|
6
|
-
import { $class, $familiar, $item, $items, $monsters } from "./template-string";
|
|
6
|
+
import { $class, $familiar, $item, $items, $monsters, $skill, } from "./template-string";
|
|
7
7
|
import { chunk } from "./utils";
|
|
8
8
|
/**
|
|
9
9
|
* Returns the current maximum Accordion Thief songs the player can have in their head
|
|
@@ -323,10 +323,25 @@ export function getBanishedMonsters() {
|
|
|
323
323
|
break;
|
|
324
324
|
// toItem doesn"t error if the item doesn"t exist, so we have to use that.
|
|
325
325
|
const banisherItem = toItem(banisher);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
326
|
+
if (banisher.toLowerCase() === "saber force") {
|
|
327
|
+
result.set($skill `Use the Force`, Monster.get(foe));
|
|
328
|
+
}
|
|
329
|
+
else if ([
|
|
330
|
+
Item.get("none"),
|
|
331
|
+
Item.get(`training scroll: Snokebomb`),
|
|
332
|
+
Item.get(`tomayohawk-style reflex hammer`),
|
|
333
|
+
null,
|
|
334
|
+
].includes(banisherItem)) {
|
|
335
|
+
if (Skill.get(banisher) === $skill `none`) {
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
result.set(Skill.get(banisher), Monster.get(foe));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
result.set(banisherItem, Monster.get(foe));
|
|
344
|
+
}
|
|
330
345
|
}
|
|
331
346
|
return result;
|
|
332
347
|
}
|
|
@@ -533,3 +548,24 @@ export function getTodaysHolidayWanderers() {
|
|
|
533
548
|
.map((holiday) => holidayWanderers.get(holiday) ?? [])
|
|
534
549
|
.flat();
|
|
535
550
|
}
|
|
551
|
+
/**
|
|
552
|
+
* Determines & returns whether or not we can safely call visitUrl(), based on whether we're in a fight, multi-fight, choice, etc
|
|
553
|
+
*/
|
|
554
|
+
export function canVisitUrl() {
|
|
555
|
+
return !(currentRound() ||
|
|
556
|
+
inMultiFight() ||
|
|
557
|
+
choiceFollowsFight() ||
|
|
558
|
+
handlingChoice());
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Calculate damage taken from a specific element after factoring in resistance
|
|
562
|
+
* @param baseDamage
|
|
563
|
+
* @param element
|
|
564
|
+
* @returns damage after factoring in resistances
|
|
565
|
+
*/
|
|
566
|
+
export function damageTakenByElement(baseDamage, element) {
|
|
567
|
+
if (baseDamage < 0)
|
|
568
|
+
return 1;
|
|
569
|
+
const res = elementalResistance(element);
|
|
570
|
+
return Math.max(1, Math.ceil(baseDamage - (baseDamage * res) / 100));
|
|
571
|
+
}
|
package/dist/mood.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "core-js/modules/es.object.values";
|
|
2
2
|
import { Effect, Item, Skill } from "kolmafia";
|
|
3
3
|
export declare abstract class MpSource {
|
|
4
|
-
usesRemaining(): number
|
|
4
|
+
usesRemaining(): number;
|
|
5
5
|
abstract availableMpMin(): number;
|
|
6
6
|
availableMpMax(): number;
|
|
7
7
|
abstract execute(): void;
|
|
@@ -9,13 +9,14 @@ export declare abstract class MpSource {
|
|
|
9
9
|
export declare class OscusSoda extends MpSource {
|
|
10
10
|
static instance: OscusSoda;
|
|
11
11
|
available(): boolean;
|
|
12
|
-
usesRemaining(): number
|
|
12
|
+
usesRemaining(): number;
|
|
13
13
|
availableMpMin(): number;
|
|
14
14
|
availableMpMax(): number;
|
|
15
15
|
execute(): void;
|
|
16
16
|
}
|
|
17
17
|
export declare class MagicalSausages extends MpSource {
|
|
18
18
|
static instance: MagicalSausages;
|
|
19
|
+
available(): boolean;
|
|
19
20
|
usesRemaining(): number;
|
|
20
21
|
availableMpMin(): number;
|
|
21
22
|
execute(): void;
|
package/dist/mood.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "core-js/modules/es.object.values";
|
|
2
|
-
import { availableAmount, buy, cliExecute, eat, effectModifier, haveEffect, haveSkill, hpCost,
|
|
2
|
+
import { availableAmount, buy, cliExecute, eat, effectModifier, haveEffect, haveSkill, hpCost, mallPrice, mpCost, myHp, myMaxmp, myMp, numericModifier, retrieveItem, toEffect, toSkill, turnsPerCast, use, useSkill, } from "kolmafia";
|
|
3
3
|
import { getActiveSongs, have, isSong } from "./lib";
|
|
4
4
|
import { get } from "./property";
|
|
5
5
|
import { AsdonMartin } from "./resources";
|
|
@@ -7,7 +7,7 @@ import { $item, $skill } from "./template-string";
|
|
|
7
7
|
import { clamp, sum } from "./utils";
|
|
8
8
|
export class MpSource {
|
|
9
9
|
usesRemaining() {
|
|
10
|
-
return
|
|
10
|
+
return 0;
|
|
11
11
|
}
|
|
12
12
|
availableMpMax() {
|
|
13
13
|
return this.availableMpMin();
|
|
@@ -22,10 +22,10 @@ export class OscusSoda extends MpSource {
|
|
|
22
22
|
return get("oscusSodaUsed") ? 0 : 1;
|
|
23
23
|
}
|
|
24
24
|
availableMpMin() {
|
|
25
|
-
return this.available() ? 200 : 0;
|
|
25
|
+
return this.available() && this.usesRemaining() > 0 ? 200 : 0;
|
|
26
26
|
}
|
|
27
27
|
availableMpMax() {
|
|
28
|
-
return this.available() ? 300 : 0;
|
|
28
|
+
return this.available() && this.usesRemaining() > 0 ? 300 : 0;
|
|
29
29
|
}
|
|
30
30
|
execute() {
|
|
31
31
|
use($item `Oscus's neverending soda`);
|
|
@@ -33,22 +33,26 @@ export class OscusSoda extends MpSource {
|
|
|
33
33
|
}
|
|
34
34
|
export class MagicalSausages extends MpSource {
|
|
35
35
|
static instance = new MagicalSausages();
|
|
36
|
+
available() {
|
|
37
|
+
return have($item `Kramco Sausage-o-Matic™`);
|
|
38
|
+
}
|
|
36
39
|
usesRemaining() {
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
const maxSausages = availableAmount($item `magical sausage`) +
|
|
41
|
+
availableAmount($item `magical sausage casing`);
|
|
42
|
+
return this.available()
|
|
43
|
+
? clamp(23 - get("_sausagesEaten"), 0, maxSausages)
|
|
39
44
|
: 0;
|
|
40
45
|
}
|
|
41
46
|
availableMpMin() {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
return this.available()
|
|
48
|
+
? Math.min(myMaxmp(), 999) * this.usesRemaining()
|
|
49
|
+
: 0;
|
|
45
50
|
}
|
|
46
51
|
execute() {
|
|
47
52
|
const mpSpaceAvailable = myMaxmp() - myMp();
|
|
48
53
|
if (mpSpaceAvailable < 700)
|
|
49
54
|
return;
|
|
50
|
-
const maxSausages = Math.min(this.usesRemaining(),
|
|
51
|
-
itemAmount($item `magical sausage casing`), Math.floor((myMaxmp() - myMp()) / Math.min(myMaxmp() - myMp(), 999)));
|
|
55
|
+
const maxSausages = Math.min(this.usesRemaining(), Math.floor((myMaxmp() - myMp()) / Math.min(myMaxmp() - myMp(), 999)));
|
|
52
56
|
retrieveItem(maxSausages, $item `magical sausage`);
|
|
53
57
|
eat(maxSausages, $item `magical sausage`);
|
|
54
58
|
}
|
|
@@ -102,10 +106,10 @@ class SkillMoodElement extends MoodElement {
|
|
|
102
106
|
}
|
|
103
107
|
else {
|
|
104
108
|
const cost = mpCost(this.skill);
|
|
105
|
-
maxCasts = Math.floor(myMp() / cost);
|
|
109
|
+
maxCasts = Math.floor(Math.min(mood.availableMp(), myMp()) / cost);
|
|
106
110
|
if (maxCasts === 0) {
|
|
107
111
|
mood.moreMp(cost);
|
|
108
|
-
maxCasts = Math.floor(myMp() / cost);
|
|
112
|
+
maxCasts = Math.floor(Math.min(mood.availableMp(), myMp()) / cost);
|
|
109
113
|
}
|
|
110
114
|
}
|
|
111
115
|
const casts = clamp(remainingCasts, 0, Math.min(100, maxCasts));
|
|
@@ -236,9 +240,10 @@ export class Mood {
|
|
|
236
240
|
return (sum(this.options.mpSources, (mpSource) => mpSource.availableMpMin()) + Math.max(myMp() - this.options.reserveMp, 0));
|
|
237
241
|
}
|
|
238
242
|
moreMp(minimumTarget) {
|
|
243
|
+
if (myMp() >= minimumTarget)
|
|
244
|
+
return;
|
|
239
245
|
for (const mpSource of this.options.mpSources) {
|
|
240
|
-
|
|
241
|
-
if (usesRemaining !== null && usesRemaining > 0) {
|
|
246
|
+
if (mpSource.usesRemaining() > 0) {
|
|
242
247
|
mpSource.execute();
|
|
243
248
|
if (myMp() >= minimumTarget)
|
|
244
249
|
break;
|
|
@@ -315,6 +320,7 @@ export class Mood {
|
|
|
315
320
|
}
|
|
316
321
|
completeSuccess = element.execute(this, elementTurns) && completeSuccess;
|
|
317
322
|
}
|
|
323
|
+
this.moreMp(this.options.reserveMp);
|
|
318
324
|
return completeSuccess;
|
|
319
325
|
}
|
|
320
326
|
}
|