libram 0.6.7 → 0.6.10
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 +1 -1
- package/dist/ascend.d.ts +2 -2
- package/dist/ascend.js +24 -10
- package/dist/challengePaths/2015/CommunityService.d.ts +48 -35
- package/dist/challengePaths/2015/CommunityService.js +171 -124
- package/dist/challengePaths/index.d.ts +1 -1
- package/dist/challengePaths/index.js +1 -1
- 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 +3 -3
- package/dist/lib.js +20 -5
- package/dist/mood.d.ts +1 -1
- package/dist/mood.js +5 -3
- package/dist/propertyTypes.d.ts +4 -4
- package/dist/propertyTypes.js +4 -4
- package/dist/resources/2016/SourceTerminal.d.ts +27 -1
- package/dist/resources/2016/SourceTerminal.js +42 -1
- package/dist/resources/2020/RetroCape.d.ts +48 -0
- package/dist/resources/2020/RetroCape.js +111 -0
- package/dist/resources/2022/CombatLoversLocket.js +1 -1
- package/dist/resources/index.d.ts +2 -1
- package/dist/resources/index.js +2 -1
- package/package.json +1 -1
package/dist/Clan.js
CHANGED
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 {
|
|
@@ -17,7 +17,7 @@ declare type MoonSign = number | "mongoose" | "wallaby" | "vole" | "platypus" |
|
|
|
17
17
|
* @param consumable From the astral deli. Pick the container item, not the product.
|
|
18
18
|
* @param pet From the astral pet store.
|
|
19
19
|
*/
|
|
20
|
-
export declare function ascend(path: Path, playerClass: Class, lifestyle: Lifestyle, moon: MoonSign, consumable?: Item | undefined, pet?: Item | undefined): void;
|
|
20
|
+
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
21
|
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
22
|
declare type Workshed = typeof worksheds[number];
|
|
23
23
|
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 { 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;
|
|
@@ -68,13 +68,7 @@ function toMoonId(moon, playerClass) {
|
|
|
68
68
|
* @param consumable From the astral deli. Pick the container item, not the product.
|
|
69
69
|
* @param pet From the astral pet store.
|
|
70
70
|
*/
|
|
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
|
-
}
|
|
71
|
+
export function ascend(path, playerClass, lifestyle, moon, consumable = $item `astral six-pack`, pet = undefined, permSkills = undefined) {
|
|
78
72
|
if (!path.classes.includes(playerClass)) {
|
|
79
73
|
throw new Error(`Invalid class ${playerClass} for this path`);
|
|
80
74
|
}
|
|
@@ -85,11 +79,23 @@ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `a
|
|
|
85
79
|
throw new Error(`Invalid moon ${moon}`);
|
|
86
80
|
if (consumable &&
|
|
87
81
|
!$items `astral six-pack, astral hot dog dinner, [10882]carton of astral energy drinks`.includes(consumable)) {
|
|
88
|
-
throw new Error(`Invalid consumable ${consumable}
|
|
82
|
+
throw new Error(`Invalid consumable ${consumable}!`);
|
|
89
83
|
}
|
|
90
84
|
if (pet &&
|
|
91
85
|
!$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 Error(`Invalid astral item ${pet}
|
|
86
|
+
throw new Error(`Invalid astral item ${pet}!`);
|
|
87
|
+
}
|
|
88
|
+
const illegalSkill = permSkills
|
|
89
|
+
? Array.from(permSkills.keys()).find((skill) => !skill.permable || !haveSkill(skill))
|
|
90
|
+
: undefined;
|
|
91
|
+
if (illegalSkill) {
|
|
92
|
+
throw new Error(`Invalid skill ${illegalSkill}!`);
|
|
93
|
+
}
|
|
94
|
+
if (!containsText(visitUrl("charpane.php"), "Astral Spirit")) {
|
|
95
|
+
visitUrl("ascend.php?action=ascend&confirm=on&confirm2=on");
|
|
96
|
+
}
|
|
97
|
+
if (!containsText(visitUrl("charpane.php"), "Astral Spirit")) {
|
|
98
|
+
throw new Error("Failed to ascend.");
|
|
93
99
|
}
|
|
94
100
|
visitUrl("afterlife.php?action=pearlygates");
|
|
95
101
|
if (consumable) {
|
|
@@ -97,6 +103,14 @@ export function ascend(path, playerClass, lifestyle, moon, consumable = $item `a
|
|
|
97
103
|
}
|
|
98
104
|
if (pet)
|
|
99
105
|
visitUrl(`afterlife.php?action=buyarmory&whichitem=${toInt(pet)}`);
|
|
106
|
+
if (permSkills) {
|
|
107
|
+
for (const [skill, permLevel] of permSkills.entries()) {
|
|
108
|
+
if (permLevel !== Lifestyle.casual) {
|
|
109
|
+
const permText = permLevel === Lifestyle.hardcore ? "hcperm" : "scperm";
|
|
110
|
+
visitUrl(`afterlife.php?action=${permText}&whichskill=${toInt(skill)}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
100
114
|
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
115
|
}
|
|
102
116
|
const worksheds = [
|
|
@@ -1,31 +1,27 @@
|
|
|
1
1
|
import { Requirement } from "../../maximize";
|
|
2
|
-
|
|
3
|
-
* A log of the predicted turns, actual turns, and duration of each CS test performed.
|
|
4
|
-
*/
|
|
5
|
-
export declare const log: {
|
|
6
|
-
[index: string]: {
|
|
7
|
-
predictedTurns: number;
|
|
8
|
-
turnCost: number;
|
|
9
|
-
seconds: number;
|
|
10
|
-
};
|
|
11
|
-
};
|
|
12
|
-
declare class Test {
|
|
2
|
+
export default class CommunityService {
|
|
13
3
|
private choice;
|
|
4
|
+
private stat;
|
|
14
5
|
private property;
|
|
15
6
|
private predictor;
|
|
16
7
|
private maximizeRequirements;
|
|
17
8
|
/**
|
|
18
9
|
* Class to store properties of various CS tests.
|
|
19
10
|
* @param id The id the game HTML uses to identify the test; this is used primarily in runChoice.
|
|
11
|
+
* @param stat The principle stat the test measures, often used as more easily memorable shorthand for the specific tests
|
|
20
12
|
* @param property The name of the test as a string, often used as part of the string property "csServicesPerformed".
|
|
21
13
|
* @param predictor A function that returns an estimate for the number of turns that the test will take given your character's current state.
|
|
22
14
|
* @param maximizeRequirements A Requirement object, if applicable, that aligns with the things needed to maximize for this particular test.
|
|
23
15
|
*/
|
|
24
|
-
constructor(
|
|
16
|
+
private constructor();
|
|
25
17
|
/**
|
|
26
18
|
* @returns The id number of the test, used primarily in runChoice.
|
|
27
19
|
*/
|
|
28
20
|
get id(): number;
|
|
21
|
+
/**
|
|
22
|
+
* @returns The primary stat the test measures, used primarily as memorable shorthand in place of test names.
|
|
23
|
+
*/
|
|
24
|
+
get statName(): string;
|
|
29
25
|
/**
|
|
30
26
|
* @returns The name of the test, used primarily as part of the string property "csServicesPerformed"
|
|
31
27
|
*/
|
|
@@ -38,6 +34,7 @@ declare class Test {
|
|
|
38
34
|
* @returns A Requirement object, if applicable, that aligns with the things needed to maximize for this particular test.
|
|
39
35
|
*/
|
|
40
36
|
get requirement(): Requirement | null;
|
|
37
|
+
static logTask(name: string, action: () => number | void): void;
|
|
41
38
|
/**
|
|
42
39
|
* Checks the "csServicesPerformed" property to see whether mafia currently believes this test is complete.
|
|
43
40
|
* @returns Whether mafia currently believes this test is complete.
|
|
@@ -54,33 +51,49 @@ declare class Test {
|
|
|
54
51
|
do(): boolean;
|
|
55
52
|
/**
|
|
56
53
|
* Wrapper function that prepares for a test and then completes it, adding time and turn details to the log.
|
|
57
|
-
* @param prepare A function that does all necessary preparations for this CS test, including choosing your outfit.
|
|
58
|
-
* @param
|
|
59
|
-
* @
|
|
60
|
-
* @returns The output of the prepare function given, or null if the test is already complete.
|
|
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 maxTurns We will run the test iff the predicted/actual turns is less than or equal to this parameter.
|
|
56
|
+
* @returns "completed", "failed", or "already completed".
|
|
61
57
|
*/
|
|
62
|
-
run(prepare: () => void
|
|
58
|
+
run(prepare: () => void | number, maxTurns?: number): "completed" | "failed" | "already completed";
|
|
59
|
+
private _verifyIsDone;
|
|
63
60
|
/**
|
|
64
61
|
* Checks council.php to verify that a test is complete; more reliable than isDone, but requires an additional pagehit.
|
|
65
62
|
* @returns Whether council.php suggests that the test is complete.
|
|
66
63
|
*/
|
|
67
64
|
verifyIsDone(): boolean;
|
|
65
|
+
private _actualCost;
|
|
66
|
+
/**
|
|
67
|
+
* Checks council.php for the number of turns this test will take; more reliable than prediction, but requires an additional pagehit.
|
|
68
|
+
* @returns The number of turns to complete this test according to council.php.
|
|
69
|
+
*/
|
|
70
|
+
actualCost(): number;
|
|
71
|
+
/**
|
|
72
|
+
* A log of the predicted turns, actual turns, and duration of each CS test performed.
|
|
73
|
+
*/
|
|
74
|
+
static log: {
|
|
75
|
+
[index: string]: {
|
|
76
|
+
predictedTurns: number;
|
|
77
|
+
turnCost: number;
|
|
78
|
+
seconds: number;
|
|
79
|
+
type: "test" | "task";
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Prints turncount and time details of the test in question.
|
|
84
|
+
* @param colour The colour (or color) you'd like the log to be printed in.
|
|
85
|
+
*/
|
|
86
|
+
static printLog(colour?: string): void;
|
|
87
|
+
static HP: CommunityService;
|
|
88
|
+
static Muscle: CommunityService;
|
|
89
|
+
static Mysticality: CommunityService;
|
|
90
|
+
static Moxie: CommunityService;
|
|
91
|
+
static FamiliarWeight: CommunityService;
|
|
92
|
+
static WeaponDamage: CommunityService;
|
|
93
|
+
static SpellDamage: CommunityService;
|
|
94
|
+
static Noncombat: CommunityService;
|
|
95
|
+
static BoozeDrop: CommunityService;
|
|
96
|
+
static HotRes: CommunityService;
|
|
97
|
+
static CoilWire: CommunityService;
|
|
98
|
+
static donate: () => void;
|
|
68
99
|
}
|
|
69
|
-
export declare const HP: Test;
|
|
70
|
-
export declare const Muscle: Test;
|
|
71
|
-
export declare const Mysticality: Test;
|
|
72
|
-
export declare const Moxie: Test;
|
|
73
|
-
export declare const FamiliarWeight: Test;
|
|
74
|
-
export declare const WeaponDamage: Test;
|
|
75
|
-
export declare const SpellDamage: Test;
|
|
76
|
-
export declare const Noncombat: Test;
|
|
77
|
-
export declare const BoozeDrop: Test;
|
|
78
|
-
export declare const HotRes: Test;
|
|
79
|
-
export declare const CoilWire: Test;
|
|
80
|
-
/**
|
|
81
|
-
* Prints turncount and time details of the test in question.
|
|
82
|
-
* @param colour The colour (or color) you'd like the log to be printed in.
|
|
83
|
-
*/
|
|
84
|
-
export declare function printLog(colour?: string): void;
|
|
85
|
-
export declare const donate: () => void;
|
|
86
|
-
export {};
|
|
@@ -1,29 +1,39 @@
|
|
|
1
|
-
import { equippedItem, familiarWeight, getPower, haveEquipped, myBasestat, myBuffedstat, myFamiliar,
|
|
1
|
+
import { equippedItem, familiarWeight, getPower, haveEquipped, myAdventures, myBasestat, myBuffedstat, myFamiliar, myMaxhp, myThrall, myTurncount, numericModifier, print, runChoice, toSlot, visitUrl, weightAdjustment, } from "kolmafia";
|
|
2
2
|
import { have } from "../../lib";
|
|
3
3
|
import { Requirement } from "../../maximize";
|
|
4
4
|
import { get as getModifier } from "../../modifier";
|
|
5
5
|
import { get } from "../../property";
|
|
6
|
-
import { MummingTrunk
|
|
6
|
+
import { MummingTrunk } from "../../resources";
|
|
7
7
|
import { $effect, $familiar, $item, $items, $slot, $stat, $thrall, } from "../../template-string";
|
|
8
8
|
import { sum } from "../../utils";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const thralls = new Map([
|
|
10
|
+
[$stat `muscle`, $thrall `Elbow Macaroni`],
|
|
11
|
+
[$stat `moxie`, $thrall `Penne Dreadful`],
|
|
12
|
+
]);
|
|
13
|
+
const statCommunityServicePredictor = (stat) => {
|
|
14
|
+
return () => 60 -
|
|
15
|
+
Math.floor((1 / 30) *
|
|
16
|
+
(myBuffedstat(stat) -
|
|
17
|
+
myBasestat(thralls.get(stat) === myThrall() ? $stat `mysticality` : stat)));
|
|
18
|
+
};
|
|
19
|
+
const visitCouncil = () => visitUrl("council.php");
|
|
20
|
+
export default class CommunityService {
|
|
14
21
|
choice;
|
|
22
|
+
stat;
|
|
15
23
|
property;
|
|
16
24
|
predictor;
|
|
17
25
|
maximizeRequirements;
|
|
18
26
|
/**
|
|
19
27
|
* Class to store properties of various CS tests.
|
|
20
28
|
* @param id The id the game HTML uses to identify the test; this is used primarily in runChoice.
|
|
29
|
+
* @param stat The principle stat the test measures, often used as more easily memorable shorthand for the specific tests
|
|
21
30
|
* @param property The name of the test as a string, often used as part of the string property "csServicesPerformed".
|
|
22
31
|
* @param predictor A function that returns an estimate for the number of turns that the test will take given your character's current state.
|
|
23
32
|
* @param maximizeRequirements A Requirement object, if applicable, that aligns with the things needed to maximize for this particular test.
|
|
24
33
|
*/
|
|
25
|
-
constructor(id, property, predictor, maximizeRequirements
|
|
34
|
+
constructor(id, stat, property, predictor, maximizeRequirements) {
|
|
26
35
|
this.choice = id;
|
|
36
|
+
this.stat = stat;
|
|
27
37
|
this.property = property;
|
|
28
38
|
this.predictor = predictor;
|
|
29
39
|
this.maximizeRequirements = maximizeRequirements;
|
|
@@ -34,6 +44,12 @@ class Test {
|
|
|
34
44
|
get id() {
|
|
35
45
|
return this.choice;
|
|
36
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* @returns The primary stat the test measures, used primarily as memorable shorthand in place of test names.
|
|
49
|
+
*/
|
|
50
|
+
get statName() {
|
|
51
|
+
return this.stat;
|
|
52
|
+
}
|
|
37
53
|
/**
|
|
38
54
|
* @returns The name of the test, used primarily as part of the string property "csServicesPerformed"
|
|
39
55
|
*/
|
|
@@ -52,6 +68,17 @@ class Test {
|
|
|
52
68
|
get requirement() {
|
|
53
69
|
return this.maximizeRequirements;
|
|
54
70
|
}
|
|
71
|
+
static logTask(name, action) {
|
|
72
|
+
const startTime = Date.now();
|
|
73
|
+
const startTurns = myTurncount();
|
|
74
|
+
const estimatedTurns = action() ?? 0;
|
|
75
|
+
CommunityService.log[name] = {
|
|
76
|
+
type: "task",
|
|
77
|
+
turnCost: myTurncount() - startTurns,
|
|
78
|
+
predictedTurns: estimatedTurns,
|
|
79
|
+
seconds: (Date.now() - startTime) / 1000,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
55
82
|
/**
|
|
56
83
|
* Checks the "csServicesPerformed" property to see whether mafia currently believes this test is complete.
|
|
57
84
|
* @returns Whether mafia currently believes this test is complete.
|
|
@@ -71,139 +98,159 @@ class Test {
|
|
|
71
98
|
* @returns Whether mafia believes the test is complete at the end of this function.
|
|
72
99
|
*/
|
|
73
100
|
do() {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
101
|
+
if (get("csServicesPerformed").trim().length === 0)
|
|
102
|
+
visitCouncil();
|
|
103
|
+
visitCouncil();
|
|
104
|
+
const councilText = runChoice(this.choice);
|
|
105
|
+
return this._verifyIsDone(councilText);
|
|
77
106
|
}
|
|
78
107
|
/**
|
|
79
108
|
* Wrapper function that prepares for a test and then completes it, adding time and turn details to the log.
|
|
80
|
-
* @param prepare A function that does all necessary preparations for this CS test, including choosing your outfit.
|
|
81
|
-
* @param
|
|
82
|
-
* @
|
|
83
|
-
* @returns The output of the prepare function given, or null if the test is already complete.
|
|
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 maxTurns We will run the test iff the predicted/actual turns is less than or equal to this parameter.
|
|
111
|
+
* @returns "completed", "failed", or "already completed".
|
|
84
112
|
*/
|
|
85
|
-
run(prepare,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return false;
|
|
113
|
+
run(prepare, maxTurns = Infinity) {
|
|
114
|
+
if (this.isDone())
|
|
115
|
+
return "already completed";
|
|
89
116
|
const startTime = Date.now();
|
|
90
117
|
const startTurns = myTurncount();
|
|
118
|
+
let additionalTurns;
|
|
91
119
|
try {
|
|
92
|
-
prepare();
|
|
120
|
+
additionalTurns = prepare() ?? 0;
|
|
93
121
|
}
|
|
94
122
|
catch {
|
|
95
|
-
return
|
|
123
|
+
return "failed";
|
|
96
124
|
}
|
|
97
125
|
const prediction = this.predictor();
|
|
98
|
-
|
|
99
|
-
|
|
126
|
+
const council = visitCouncil();
|
|
127
|
+
const turns = this._actualCost(council);
|
|
128
|
+
if (!turns)
|
|
129
|
+
return "already completed";
|
|
130
|
+
if (turns > Math.min(maxTurns, myAdventures())) {
|
|
131
|
+
return "failed";
|
|
100
132
|
}
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
return
|
|
133
|
+
if (!this.do())
|
|
134
|
+
return "failed";
|
|
135
|
+
CommunityService.log[this.property] = {
|
|
136
|
+
predictedTurns: prediction + additionalTurns,
|
|
137
|
+
turnCost: myTurncount() - startTurns,
|
|
138
|
+
seconds: (Date.now() - startTime) / 1000,
|
|
139
|
+
type: "test",
|
|
140
|
+
};
|
|
141
|
+
return "completed";
|
|
142
|
+
}
|
|
143
|
+
_verifyIsDone(councilText) {
|
|
144
|
+
return !councilText.includes(`<input type=hidden name=option value=${this.choice}>`);
|
|
110
145
|
}
|
|
111
146
|
/**
|
|
112
147
|
* Checks council.php to verify that a test is complete; more reliable than isDone, but requires an additional pagehit.
|
|
113
148
|
* @returns Whether council.php suggests that the test is complete.
|
|
114
149
|
*/
|
|
115
150
|
verifyIsDone() {
|
|
116
|
-
return
|
|
151
|
+
return this._verifyIsDone(visitCouncil());
|
|
117
152
|
}
|
|
153
|
+
_actualCost(councilText) {
|
|
154
|
+
const match = councilText.match(`<input type=hidden name=option value=${this.id}>.*?Perform Service \\((\\d+) Adventures\\)`);
|
|
155
|
+
return match ? parseInt(match[1]) : 0;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Checks council.php for the number of turns this test will take; more reliable than prediction, but requires an additional pagehit.
|
|
159
|
+
* @returns The number of turns to complete this test according to council.php.
|
|
160
|
+
*/
|
|
161
|
+
actualCost() {
|
|
162
|
+
return this._actualCost(visitCouncil());
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* A log of the predicted turns, actual turns, and duration of each CS test performed.
|
|
166
|
+
*/
|
|
167
|
+
static log = {};
|
|
168
|
+
/**
|
|
169
|
+
* Prints turncount and time details of the test in question.
|
|
170
|
+
* @param colour The colour (or color) you'd like the log to be printed in.
|
|
171
|
+
*/
|
|
172
|
+
static printLog(colour = "blue") {
|
|
173
|
+
const logEntries = Object.entries(CommunityService.log);
|
|
174
|
+
for (const [testName, testEntry] of logEntries) {
|
|
175
|
+
const { type, predictedTurns, turnCost, seconds } = testEntry;
|
|
176
|
+
if (type === "test") {
|
|
177
|
+
print(`We predicted the ${testName} test would take ${predictedTurns} turns, ${predictedTurns === turnCost ? "and" : "but"} it took ${turnCost} turns.`, colour);
|
|
178
|
+
print(`${testName} took ${seconds.toFixed(1)} seconds.`, colour);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
if (!(predictedTurns === 0 && turnCost === 0)) {
|
|
182
|
+
print(`We predicted the task ${testName} would take ${predictedTurns} turns, ${predictedTurns === turnCost ? "and" : "but"} it took ${turnCost} turns.`, colour);
|
|
183
|
+
}
|
|
184
|
+
print(`The task ${testName} took ${seconds.toFixed(1)} seconds.`, colour);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
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
|
+
}
|
|
190
|
+
// Below, we have the tests themselves.
|
|
191
|
+
static HP = new CommunityService(1, "HP", "Donate Blood", () => 60 - Math.floor((myMaxhp() - myBuffedstat($stat `muscle`) - 3) / 30), new Requirement(["HP"], {}));
|
|
192
|
+
static Muscle = new CommunityService(2, "Muscle", "Feed The Children", statCommunityServicePredictor($stat `Muscle`), new Requirement(["Muscle"], {}));
|
|
193
|
+
static Mysticality = new CommunityService(3, "Mysticality", "Build Playground Mazes", statCommunityServicePredictor($stat `Mysticality`), new Requirement(["Mysticality"], {}));
|
|
194
|
+
static Moxie = new CommunityService(4, "Moxie", "Feed Conspirators", statCommunityServicePredictor($stat `Moxie`), new Requirement(["Moxie"], {}));
|
|
195
|
+
static FamiliarWeight = new CommunityService(5, "Familiar Weight", "Breed More Collies", () => 60 - Math.floor((familiarWeight(myFamiliar()) + weightAdjustment()) / 5), new Requirement(["Familiar Weight"], {}));
|
|
196
|
+
static WeaponDamage = new CommunityService(6, "Weapon Damage", "Reduce Gazelle Population", () => {
|
|
197
|
+
const weaponPower = getPower(equippedItem($slot `weapon`));
|
|
198
|
+
const offhandPower = toSlot(equippedItem($slot `off-hand`)) === $slot `weapon`
|
|
199
|
+
? getPower(equippedItem($slot `off-hand`))
|
|
200
|
+
: 0;
|
|
201
|
+
const familiarPower = toSlot(equippedItem($slot `familiar`)) === $slot `weapon`
|
|
202
|
+
? getPower(equippedItem($slot `familiar`))
|
|
203
|
+
: 0;
|
|
204
|
+
// mafia does not currently count swagger
|
|
205
|
+
const multiplier = have($effect `Bow-Legged Swagger`) ? 2 : 1;
|
|
206
|
+
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
207
|
+
return (60 -
|
|
208
|
+
Math.floor((multiplier *
|
|
209
|
+
(getModifier("Weapon Damage") -
|
|
210
|
+
0.15 * (weaponPower + offhandPower + familiarPower))) /
|
|
211
|
+
50 +
|
|
212
|
+
0.001) -
|
|
213
|
+
Math.floor((multiplier * getModifier("Weapon Damage Percent")) / 50 + 0.001));
|
|
214
|
+
}, new Requirement(["Weapon Damage", "Weapon Damage Percent"], {}));
|
|
215
|
+
static SpellDamage = new CommunityService(7, "Spell Damage", "Make Sausage", () => {
|
|
216
|
+
const dragonfishDamage = myFamiliar() === $familiar `Magic Dragonfish`
|
|
217
|
+
? numericModifier($familiar `Magic Dragonfish`, "Spell Damage Percent", familiarWeight($familiar `Magic Dragonfish`) + weightAdjustment(), $item `none`)
|
|
218
|
+
: 0;
|
|
219
|
+
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
220
|
+
return (60 -
|
|
221
|
+
Math.floor(getModifier("Spell Damage") / 50 + 0.001) -
|
|
222
|
+
Math.floor((getModifier("Spell Damage Percent") - dragonfishDamage) / 50 + 0.001));
|
|
223
|
+
}, new Requirement(["Spell Damage", "Spell Damage Percent"], {}));
|
|
224
|
+
static Noncombat = new CommunityService(8, "Non-Combat", "Be a Living Statue", () => {
|
|
225
|
+
const noncombatRate = -1 * getModifier("Combat Rate");
|
|
226
|
+
return 60 - 3 * Math.floor(noncombatRate / 5);
|
|
227
|
+
}, new Requirement(["-combat"], {}));
|
|
228
|
+
static BoozeDrop = new CommunityService(9, "Item Drop", "Make Margaritas", () => {
|
|
229
|
+
const mummingCostume = MummingTrunk.currentCostumes().get(myFamiliar());
|
|
230
|
+
const mummingBuff = mummingCostume && mummingCostume[0] === "Item Drop"
|
|
231
|
+
? mummingCostume[1]
|
|
232
|
+
: 0;
|
|
233
|
+
const familiarItemDrop = numericModifier(myFamiliar(), "Item Drop", familiarWeight(myFamiliar()) + weightAdjustment(), equippedItem($slot `familiar`)) +
|
|
234
|
+
mummingBuff -
|
|
235
|
+
numericModifier(equippedItem($slot `familiar`), "Item Drop");
|
|
236
|
+
const familiarBoozeDrop = numericModifier(myFamiliar(), "Booze Drop", familiarWeight(myFamiliar()) + weightAdjustment(), equippedItem($slot `familiar`)) - numericModifier(equippedItem($slot `familiar`), "Booze Drop");
|
|
237
|
+
// Champagne doubling does NOT count for CS, so we undouble
|
|
238
|
+
const multiplier = haveEquipped($item `broken champagne bottle`) &&
|
|
239
|
+
get("garbageChampagneCharge") > 0
|
|
240
|
+
? 0.5
|
|
241
|
+
: 1;
|
|
242
|
+
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
243
|
+
return (60 -
|
|
244
|
+
Math.floor((multiplier * (getModifier("Item Drop") - familiarItemDrop)) / 30 +
|
|
245
|
+
0.001) -
|
|
246
|
+
Math.floor((getModifier("Booze Drop") - familiarBoozeDrop) / 15 + 0.001));
|
|
247
|
+
}, new Requirement(["Item Drop", "2 Booze Drop"], {
|
|
248
|
+
preventEquip: $items `broken champagne bottle`,
|
|
249
|
+
}));
|
|
250
|
+
static HotRes = new CommunityService(10, "Hot Resistance", "Clean Steam Tunnels", () => 60 - getModifier("Hot Resistance"), new Requirement(["Hot Resistance"], {}));
|
|
251
|
+
static CoilWire = new CommunityService(11, "Coil Wire", "Coil Wire", () => 60, new Requirement([], {}));
|
|
252
|
+
static donate = () => {
|
|
253
|
+
visitCouncil();
|
|
254
|
+
visitUrl("choice.php?whichchoice=1089&option=30");
|
|
255
|
+
};
|
|
118
256
|
}
|
|
119
|
-
const thralls = new Map([
|
|
120
|
-
[$stat `muscle`, $thrall `Elbow Macaroni`],
|
|
121
|
-
[$stat `moxie`, $thrall `Penne Dreadful`],
|
|
122
|
-
]);
|
|
123
|
-
const statTestPredictor = (stat) => {
|
|
124
|
-
return () => 60 -
|
|
125
|
-
Math.floor((1 / 30) *
|
|
126
|
-
(myBuffedstat(stat) -
|
|
127
|
-
myBasestat(thralls.get(stat) === myThrall() ? $stat `mysticality` : stat)));
|
|
128
|
-
};
|
|
129
|
-
export const HP = new Test(1, "Donate Blood", () => 60 - Math.floor((myMaxhp() - myBuffedstat($stat `muscle`) - 3) / 30), new Requirement(["HP"], {}));
|
|
130
|
-
export const Muscle = new Test(2, "Feed The Children", statTestPredictor($stat `Muscle`), new Requirement(["Muscle"], {}));
|
|
131
|
-
export const Mysticality = new Test(3, "Build Playground Mazes", statTestPredictor($stat `Mysticality`), new Requirement(["Mysticality"], {}));
|
|
132
|
-
export const Moxie = new Test(4, "Feed Conspirators", statTestPredictor($stat `Moxie`), new Requirement(["Moxie"], {}));
|
|
133
|
-
export const FamiliarWeight = new Test(5, "Breed More Collies", () => 60 - Math.floor((familiarWeight(myFamiliar()) + weightAdjustment()) / 5), new Requirement(["Familiar Weight"], {}));
|
|
134
|
-
export const WeaponDamage = new Test(6, "Reduce Gazelle Population", () => {
|
|
135
|
-
const weaponPower = getPower(equippedItem($slot `weapon`));
|
|
136
|
-
const offhandPower = toSlot(equippedItem($slot `off-hand`)) === $slot `weapon`
|
|
137
|
-
? getPower(equippedItem($slot `off-hand`))
|
|
138
|
-
: 0;
|
|
139
|
-
const familiarPower = toSlot(equippedItem($slot `familiar`)) === $slot `weapon`
|
|
140
|
-
? getPower(equippedItem($slot `familiar`))
|
|
141
|
-
: 0;
|
|
142
|
-
const songDamage = SongBoom.song() === "These Fists Were Made for Punchin'" ? myLevel() : 0;
|
|
143
|
-
// mafia does not currently count swagger
|
|
144
|
-
const multiplier = have($effect `Bow-Legged Swagger`) ? 2 : 1;
|
|
145
|
-
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
146
|
-
return (60 -
|
|
147
|
-
Math.floor((multiplier *
|
|
148
|
-
(getModifier("Weapon Damage") -
|
|
149
|
-
0.15 * (weaponPower + offhandPower + familiarPower) -
|
|
150
|
-
songDamage)) /
|
|
151
|
-
50 +
|
|
152
|
-
0.001) -
|
|
153
|
-
Math.floor((multiplier * getModifier("Weapon Damage Percent")) / 50 + 0.001));
|
|
154
|
-
}, new Requirement(["Weapon Damage", "Weapon Damage Percent"], {}));
|
|
155
|
-
export const SpellDamage = new Test(7, "Make Sausage", () => {
|
|
156
|
-
const dragonfishDamage = myFamiliar() === $familiar `Magic Dragonfish`
|
|
157
|
-
? numericModifier($familiar `Magic Dragonfish`, "Spell Damage Percent", familiarWeight($familiar `Magic Dragonfish`) + weightAdjustment(), $item `none`)
|
|
158
|
-
: 0;
|
|
159
|
-
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
160
|
-
return (60 -
|
|
161
|
-
Math.floor(getModifier("Spell Damage") / 50 + 0.001) -
|
|
162
|
-
Math.floor((getModifier("Spell Damage Percent") - dragonfishDamage) / 50 + 0.001));
|
|
163
|
-
}, new Requirement(["Spell Damage", "Spell Damage Percent"], {}));
|
|
164
|
-
export const Noncombat = new Test(8, "Be a Living Statue", () => {
|
|
165
|
-
const noncombatRate = -1 * getModifier("Combat Rate");
|
|
166
|
-
const unsoftcappedRate = noncombatRate > 25 ? 25 + (noncombatRate - 25) * 5 : noncombatRate;
|
|
167
|
-
return 60 - 3 * Math.floor(unsoftcappedRate / 5);
|
|
168
|
-
}, new Requirement(["-combat"], {}));
|
|
169
|
-
export const BoozeDrop = new Test(9, "Make Margaritas", () => {
|
|
170
|
-
const mummingCostume = MummingTrunk.currentCostumes().get(myFamiliar());
|
|
171
|
-
const mummingBuff = mummingCostume && mummingCostume[0] === "Item Drop"
|
|
172
|
-
? mummingCostume[1]
|
|
173
|
-
: 0;
|
|
174
|
-
const familiarItemDrop = numericModifier(myFamiliar(), "Item Drop", familiarWeight(myFamiliar()) + weightAdjustment(), equippedItem($slot `familiar`)) +
|
|
175
|
-
mummingBuff -
|
|
176
|
-
numericModifier(equippedItem($slot `familiar`), "Item Drop");
|
|
177
|
-
const familiarBoozeDrop = numericModifier(myFamiliar(), "Booze Drop", familiarWeight(myFamiliar()) + weightAdjustment(), equippedItem($slot `familiar`)) - numericModifier(equippedItem($slot `familiar`), "Booze Drop");
|
|
178
|
-
//Champagne doubling does NOT count for CS, so we undouble
|
|
179
|
-
const multiplier = haveEquipped($item `broken champagne bottle`) &&
|
|
180
|
-
get("garbageChampagneCharge") > 0
|
|
181
|
-
? 0.5
|
|
182
|
-
: 1;
|
|
183
|
-
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
184
|
-
return (60 -
|
|
185
|
-
multiplier *
|
|
186
|
-
Math.floor((getModifier("Item Drop") - familiarItemDrop) / 30 + 0.001) -
|
|
187
|
-
Math.floor((getModifier("Booze Drop") - familiarBoozeDrop) / 15 + 0.001));
|
|
188
|
-
}, new Requirement(["Item Drop", "2 Booze Drop"], {
|
|
189
|
-
preventEquip: $items `broken champagne bottle`,
|
|
190
|
-
}));
|
|
191
|
-
export const HotRes = new Test(10, "Clean Steam Tunnels", () => 60 - getModifier("Hot Resistance"), new Requirement(["Hot Resistance"], {}));
|
|
192
|
-
export const CoilWire = new Test(11, "Coil Wire", () => 60, null);
|
|
193
|
-
/**
|
|
194
|
-
* Prints turncount and time details of the test in question.
|
|
195
|
-
* @param colour The colour (or color) you'd like the log to be printed in.
|
|
196
|
-
*/
|
|
197
|
-
export function printLog(colour = "blue") {
|
|
198
|
-
const logEntries = Object.entries(log);
|
|
199
|
-
for (const [testName, testEntry] of logEntries) {
|
|
200
|
-
const { predictedTurns, turnCost, seconds } = testEntry;
|
|
201
|
-
print(`We predicted the ${testName} test would take ${predictedTurns} turns, ${predictedTurns === turnCost ? "and" : "but"} it took ${turnCost} turns`, colour);
|
|
202
|
-
print(`${testName} took ${seconds} seconds`, colour);
|
|
203
|
-
}
|
|
204
|
-
print(`All together, you have spent ${sum(logEntries, ([, testEntry]) => testEntry.seconds)} seconds during this Community Service run`, colour);
|
|
205
|
-
}
|
|
206
|
-
export const donate = () => {
|
|
207
|
-
visitUrl("council.php");
|
|
208
|
-
visitUrl("choice.php?whichchoice=1089&option=30");
|
|
209
|
-
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import CommunityService from "./2015/CommunityService";
|
|
2
2
|
export { CommunityService };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
1
|
+
import CommunityService from "./2015/CommunityService";
|
|
2
2
|
export { CommunityService };
|
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
|