libram 0.8.28 → 0.8.29
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.d.ts +128 -0
- package/dist/Clan.js +300 -0
- package/dist/Copier.d.ts +9 -0
- package/dist/Copier.js +15 -0
- package/dist/Dungeon.d.ts +45 -0
- package/dist/Dungeon.js +115 -0
- package/dist/Kmail.d.ts +133 -0
- package/dist/Kmail.js +259 -0
- package/dist/actions/ActionSource.d.ts +131 -0
- package/dist/actions/ActionSource.js +178 -0
- package/dist/actions/Banish.d.ts +16 -0
- package/dist/actions/Banish.js +121 -0
- package/dist/actions/FreeKill.d.ts +16 -0
- package/dist/actions/FreeKill.js +94 -0
- package/dist/actions/FreeRun.d.ts +16 -0
- package/dist/actions/FreeRun.js +81 -0
- package/dist/actions/index.d.ts +4 -0
- package/dist/actions/index.js +4 -0
- package/dist/ascend.d.ts +83 -0
- package/dist/ascend.js +268 -0
- package/dist/challengePaths/2014/HeavyRains.d.ts +22 -0
- package/dist/challengePaths/2014/HeavyRains.js +75 -0
- package/dist/challengePaths/2015/CommunityService.d.ts +125 -0
- package/dist/challengePaths/2015/CommunityService.js +334 -0
- package/dist/challengePaths/2016/NuclearAutumn.d.ts +13 -0
- package/dist/challengePaths/2016/NuclearAutumn.js +21 -0
- package/dist/challengePaths/index.d.ts +4 -0
- package/dist/challengePaths/index.js +4 -0
- package/dist/combat.d.ts +414 -0
- package/dist/combat.js +711 -0
- package/dist/console.d.ts +12 -0
- package/dist/console.js +14 -0
- package/dist/counter.d.ts +22 -0
- package/dist/counter.js +37 -0
- package/dist/diet/index.d.ts +80 -0
- package/dist/diet/index.js +680 -0
- package/dist/diet/knapsack.d.ts +8 -0
- package/dist/diet/knapsack.js +128 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +26 -0
- package/dist/lib.d.ts +507 -0
- package/dist/lib.js +970 -0
- package/dist/logger.d.ts +35 -0
- package/dist/logger.js +62 -0
- package/dist/maximize.d.ts +122 -0
- package/dist/maximize.js +531 -0
- package/dist/modifier.d.ts +41 -0
- package/dist/modifier.js +160 -0
- package/dist/modifierTypes.d.ts +16 -0
- package/dist/modifierTypes.js +9 -0
- package/dist/mood.d.ts +105 -0
- package/dist/mood.js +349 -0
- package/dist/moonSign.d.ts +13 -0
- package/dist/moonSign.js +25 -0
- package/dist/overlappingNames.d.ts +3 -0
- package/dist/overlappingNames.js +42 -0
- package/dist/property.d.ts +222 -0
- package/dist/property.js +385 -0
- package/dist/propertyTypes.d.ts +19 -0
- package/dist/propertyTypes.js +10 -0
- package/dist/propertyTyping.d.ts +65 -0
- package/dist/propertyTyping.js +91 -0
- package/dist/resources/2007/CandyHearts.d.ts +9 -0
- package/dist/resources/2007/CandyHearts.js +24 -0
- package/dist/resources/2008/DivineFavors.d.ts +9 -0
- package/dist/resources/2008/DivineFavors.js +27 -0
- package/dist/resources/2008/Stickers.d.ts +49 -0
- package/dist/resources/2008/Stickers.js +84 -0
- package/dist/resources/2009/Bandersnatch.d.ts +56 -0
- package/dist/resources/2009/Bandersnatch.js +93 -0
- package/dist/resources/2009/LoveSongs.d.ts +9 -0
- package/dist/resources/2009/LoveSongs.js +24 -0
- package/dist/resources/2009/SpookyPutty.d.ts +31 -0
- package/dist/resources/2009/SpookyPutty.js +49 -0
- package/dist/resources/2010/Brickos.d.ts +9 -0
- package/dist/resources/2010/Brickos.js +21 -0
- package/dist/resources/2010/CrownOfThrones.d.ts +68 -0
- package/dist/resources/2010/CrownOfThrones.js +418 -0
- package/dist/resources/2010/LookingGlass.d.ts +29 -0
- package/dist/resources/2010/LookingGlass.js +89 -0
- package/dist/resources/2011/Gygaxian.d.ts +9 -0
- package/dist/resources/2011/Gygaxian.js +24 -0
- package/dist/resources/2011/ObtuseAngel.d.ts +33 -0
- package/dist/resources/2011/ObtuseAngel.js +51 -0
- package/dist/resources/2011/StompingBoots.d.ts +37 -0
- package/dist/resources/2011/StompingBoots.js +57 -0
- package/dist/resources/2012/RainDoh.d.ts +25 -0
- package/dist/resources/2012/RainDoh.js +37 -0
- package/dist/resources/2012/ReagnimatedGnome.d.ts +31 -0
- package/dist/resources/2012/ReagnimatedGnome.js +46 -0
- package/dist/resources/2012/Resolutions.d.ts +9 -0
- package/dist/resources/2012/Resolutions.js +28 -0
- package/dist/resources/2013/Florist.d.ts +81 -0
- package/dist/resources/2013/Florist.js +245 -0
- package/dist/resources/2013/JungMan.d.ts +33 -0
- package/dist/resources/2013/JungMan.js +69 -0
- package/dist/resources/2013/PulledTaffy.d.ts +9 -0
- package/dist/resources/2013/PulledTaffy.js +33 -0
- package/dist/resources/2014/CrimboShrub.d.ts +42 -0
- package/dist/resources/2014/CrimboShrub.js +89 -0
- package/dist/resources/2014/DNALab.d.ts +56 -0
- package/dist/resources/2014/DNALab.js +162 -0
- package/dist/resources/2014/WinterGarden.d.ts +23 -0
- package/dist/resources/2014/WinterGarden.js +35 -0
- package/dist/resources/2015/BarrelShrine.d.ts +8 -0
- package/dist/resources/2015/BarrelShrine.js +25 -0
- package/dist/resources/2015/ChateauMantegna.d.ts +52 -0
- package/dist/resources/2015/ChateauMantegna.js +99 -0
- package/dist/resources/2015/DeckOfEveryCard.d.ts +29 -0
- package/dist/resources/2015/DeckOfEveryCard.js +122 -0
- package/dist/resources/2015/Dinseylandfill.d.ts +89 -0
- package/dist/resources/2015/Dinseylandfill.js +205 -0
- package/dist/resources/2015/MayoClinic.d.ts +23 -0
- package/dist/resources/2015/MayoClinic.js +49 -0
- package/dist/resources/2016/GingerBread.d.ts +32 -0
- package/dist/resources/2016/GingerBread.js +73 -0
- package/dist/resources/2016/SourceTerminal.d.ts +181 -0
- package/dist/resources/2016/SourceTerminal.js +275 -0
- package/dist/resources/2016/Witchess.d.ts +17 -0
- package/dist/resources/2016/Witchess.js +47 -0
- package/dist/resources/2017/AsdonMartin.d.ts +59 -0
- package/dist/resources/2017/AsdonMartin.js +238 -0
- package/dist/resources/2017/Horsery.d.ts +19 -0
- package/dist/resources/2017/Horsery.js +42 -0
- package/dist/resources/2017/MummingTrunk.d.ts +8 -0
- package/dist/resources/2017/MummingTrunk.js +33 -0
- package/dist/resources/2017/Pantogram.d.ts +92 -0
- package/dist/resources/2017/Pantogram.js +174 -0
- package/dist/resources/2017/Robortender.d.ts +30 -0
- package/dist/resources/2017/Robortender.js +90 -0
- package/dist/resources/2017/Spacegate.d.ts +86 -0
- package/dist/resources/2017/Spacegate.js +178 -0
- package/dist/resources/2017/TunnelOfLove.d.ts +39 -0
- package/dist/resources/2017/TunnelOfLove.js +120 -0
- package/dist/resources/2018/LatteLoversMembersMug.d.ts +392 -0
- package/dist/resources/2018/LatteLoversMembersMug.js +303 -0
- package/dist/resources/2018/SongBoom.d.ts +33 -0
- package/dist/resources/2018/SongBoom.js +55 -0
- package/dist/resources/2019/BeachComb.d.ts +72 -0
- package/dist/resources/2019/BeachComb.js +118 -0
- package/dist/resources/2019/CampAway.d.ts +39 -0
- package/dist/resources/2019/CampAway.js +72 -0
- package/dist/resources/2019/Snapper.d.ts +33 -0
- package/dist/resources/2019/Snapper.js +73 -0
- package/dist/resources/2020/Cartography.d.ts +16 -0
- package/dist/resources/2020/Cartography.js +48 -0
- package/dist/resources/2020/Guzzlr.d.ts +160 -0
- package/dist/resources/2020/Guzzlr.js +275 -0
- package/dist/resources/2020/RetroCape.d.ts +51 -0
- package/dist/resources/2020/RetroCape.js +115 -0
- package/dist/resources/2021/CrystalBall.d.ts +14 -0
- package/dist/resources/2021/CrystalBall.js +41 -0
- package/dist/resources/2021/DaylightShavings.d.ts +40 -0
- package/dist/resources/2021/DaylightShavings.js +74 -0
- package/dist/resources/2022/AutumnAton.d.ts +78 -0
- package/dist/resources/2022/AutumnAton.js +182 -0
- package/dist/resources/2022/CombatLoversLocket.d.ts +44 -0
- package/dist/resources/2022/CombatLoversLocket.js +82 -0
- package/dist/resources/2022/GreyGoose.d.ts +59 -0
- package/dist/resources/2022/GreyGoose.js +90 -0
- package/dist/resources/2022/JuneCleaver.d.ts +47 -0
- package/dist/resources/2022/JuneCleaver.js +69 -0
- package/dist/resources/2022/TrainSet.d.ts +146 -0
- package/dist/resources/2022/TrainSet.js +228 -0
- package/dist/resources/2023/AugustScepter.d.ts +25 -0
- package/dist/resources/2023/AugustScepter.js +40 -0
- package/dist/resources/2023/BurningLeaves.d.ts +25 -0
- package/dist/resources/2023/BurningLeaves.js +74 -0
- package/dist/resources/2023/CinchoDeMayo.d.ts +25 -0
- package/dist/resources/2023/CinchoDeMayo.js +45 -0
- package/dist/resources/2023/ClosedCircuitPayphone.d.ts +80 -0
- package/dist/resources/2023/ClosedCircuitPayphone.js +129 -0
- package/dist/resources/2023/CursedMonkeyPaw.d.ts +46 -0
- package/dist/resources/2023/CursedMonkeyPaw.js +113 -0
- package/dist/resources/2024/AprilingBandHelmet.d.ts +57 -0
- package/dist/resources/2024/AprilingBandHelmet.js +118 -0
- package/dist/resources/2024/ChestMimic.d.ts +42 -0
- package/dist/resources/2024/ChestMimic.js +125 -0
- package/dist/resources/LibramSummon.d.ts +18 -0
- package/dist/resources/LibramSummon.js +74 -0
- package/dist/resources/index.d.ts +54 -0
- package/dist/resources/index.js +54 -0
- package/dist/resources/putty-likes.d.ts +21 -0
- package/dist/resources/putty-likes.js +33 -0
- package/dist/session.d.ts +169 -0
- package/dist/session.js +284 -0
- package/dist/since.d.ts +51 -0
- package/dist/since.js +108 -0
- package/dist/template-string.d.ts +324 -0
- package/dist/template-string.js +265 -0
- package/dist/url.d.ts +35 -0
- package/dist/url.js +67 -0
- package/dist/utils.d.ts +178 -0
- package/dist/utils.js +255 -0
- package/package.json +2 -2
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { equippedItem, familiarWeight, getPower, haveEquipped, myAdventures, myBasestat, myBuffedstat, myFamiliar, myMaxhp, myThrall, myTurncount, numericModifier, print, runChoice, toSlot, visitUrl, weightAdjustment, } from "kolmafia";
|
|
2
|
+
import { have } from "../../lib";
|
|
3
|
+
import { Requirement } from "../../maximize";
|
|
4
|
+
import { get } from "../../property";
|
|
5
|
+
import { MummingTrunk } from "../../resources";
|
|
6
|
+
import { $effect, $familiar, $item, $items, $path, $slot, $stat, $thrall, } from "../../template-string";
|
|
7
|
+
import { clamp, sum } from "../../utils";
|
|
8
|
+
const thralls = new Map([
|
|
9
|
+
[$stat `muscle`, $thrall `Elbow Macaroni`],
|
|
10
|
+
[$stat `moxie`, $thrall `Penne Dreadful`],
|
|
11
|
+
]);
|
|
12
|
+
const statCommunityServicePredictor = (stat) => {
|
|
13
|
+
return () => 60 -
|
|
14
|
+
Math.floor((1 / 30) *
|
|
15
|
+
(myBuffedstat(stat) -
|
|
16
|
+
myBasestat(thralls.get(stat) === myThrall() && !have($effect `Expert Oiliness`)
|
|
17
|
+
? $stat `mysticality`
|
|
18
|
+
: stat)));
|
|
19
|
+
};
|
|
20
|
+
const visitCouncil = () => visitUrl("council.php");
|
|
21
|
+
const baseWeight = () => have($effect `Fidoxene`) ? 20 : familiarWeight(myFamiliar());
|
|
22
|
+
function hypotheticalModifier(modifier, ...effects) {
|
|
23
|
+
const newEffects = effects.filter((e) => !have(e));
|
|
24
|
+
return (numericModifier(modifier) +
|
|
25
|
+
sum(newEffects, (effect) => numericModifier(effect, modifier)));
|
|
26
|
+
}
|
|
27
|
+
export default class CommunityService {
|
|
28
|
+
choice;
|
|
29
|
+
stat;
|
|
30
|
+
property;
|
|
31
|
+
predictor;
|
|
32
|
+
maximizeRequirements;
|
|
33
|
+
timer = null;
|
|
34
|
+
/**
|
|
35
|
+
* Class to store properties of various CS tests.
|
|
36
|
+
*
|
|
37
|
+
* @param id The id the game HTML uses to identify the test; this is used primarily in runChoice.
|
|
38
|
+
* @param stat The principle stat the test measures, often used as more easily memorable shorthand for the specific tests
|
|
39
|
+
* @param property The name of the test as a string, often used as part of the string property "csServicesPerformed".
|
|
40
|
+
* @param predictor A function that returns an estimate for the number of turns that the test will take given your character's current state.
|
|
41
|
+
* @param maximizeRequirements A Requirement object, if applicable, that aligns with the things needed to maximize for this particular test.
|
|
42
|
+
*/
|
|
43
|
+
constructor(id, stat, property, predictor, maximizeRequirements) {
|
|
44
|
+
this.choice = id;
|
|
45
|
+
this.stat = stat;
|
|
46
|
+
this.property = property;
|
|
47
|
+
this.predictor = predictor;
|
|
48
|
+
this.maximizeRequirements = maximizeRequirements;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* @returns The id number of the test, used primarily in runChoice.
|
|
52
|
+
*/
|
|
53
|
+
get id() {
|
|
54
|
+
return this.choice;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* @returns The primary stat the test measures, used primarily as memorable shorthand in place of test names.
|
|
58
|
+
*/
|
|
59
|
+
get statName() {
|
|
60
|
+
return this.stat;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @returns The name of the test, used primarily as part of the string property "csServicesPerformed"
|
|
64
|
+
*/
|
|
65
|
+
get name() {
|
|
66
|
+
return this.property;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @returns The predicted number of turns this test will take given your character's current state.
|
|
70
|
+
*/
|
|
71
|
+
get prediction() {
|
|
72
|
+
return this.predictor();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* @returns A Requirement object, if applicable, that aligns with the things needed to maximize for this particular test.
|
|
76
|
+
*/
|
|
77
|
+
get requirement() {
|
|
78
|
+
return this.maximizeRequirements;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Start the time & turn counter for the Test in question.
|
|
82
|
+
*/
|
|
83
|
+
startTimer() {
|
|
84
|
+
this.timer ??= { time: Date.now(), turns: myTurncount() };
|
|
85
|
+
}
|
|
86
|
+
static taskTimers = new Map();
|
|
87
|
+
/**
|
|
88
|
+
* Start the time & turn counter for the given task
|
|
89
|
+
*
|
|
90
|
+
* @param name The name of the task to start the counter of
|
|
91
|
+
*/
|
|
92
|
+
static startTimer(name) {
|
|
93
|
+
if (!this.taskTimers.has(name)) {
|
|
94
|
+
this.taskTimers.set(name, { time: Date.now(), turns: myTurncount() });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
static logTask(name, action) {
|
|
98
|
+
const { time, turns } = this.taskTimers.get(name) ?? {
|
|
99
|
+
time: Date.now(),
|
|
100
|
+
turns: myTurncount(),
|
|
101
|
+
};
|
|
102
|
+
const estimatedTurns = action() ?? 0;
|
|
103
|
+
CommunityService.log[name] = {
|
|
104
|
+
type: "task",
|
|
105
|
+
turnCost: myTurncount() - turns,
|
|
106
|
+
predictedTurns: estimatedTurns,
|
|
107
|
+
seconds: (Date.now() - time) / 1000,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Checks the "csServicesPerformed" property to see whether mafia currently believes this test is complete.
|
|
112
|
+
*
|
|
113
|
+
* @returns Whether mafia currently believes this test is complete.
|
|
114
|
+
*/
|
|
115
|
+
isDone() {
|
|
116
|
+
return get("csServicesPerformed").includes(this.property);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Maximizes based on the Requirement associated with this particular test.
|
|
120
|
+
*/
|
|
121
|
+
maximize() {
|
|
122
|
+
if (this.maximizeRequirements)
|
|
123
|
+
this.maximizeRequirements.maximize();
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Attempts to turn in the test to the Council of Loathing.
|
|
127
|
+
*
|
|
128
|
+
* @returns Whether mafia believes the test is complete at the end of this function.
|
|
129
|
+
*/
|
|
130
|
+
do() {
|
|
131
|
+
if (get("csServicesPerformed").trim().length === 0)
|
|
132
|
+
visitCouncil();
|
|
133
|
+
visitCouncil();
|
|
134
|
+
const councilText = runChoice(this.choice);
|
|
135
|
+
return this._verifyIsDone(councilText);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Wrapper function that prepares for a test and then completes it, adding time and turn details to the log.
|
|
139
|
+
*
|
|
140
|
+
* @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.
|
|
141
|
+
* @param maxTurns We will run the test iff the predicted/actual turns is less than or equal to this parameter.
|
|
142
|
+
* @returns "completed", "failed", or "already completed".
|
|
143
|
+
*/
|
|
144
|
+
run(prepare, maxTurns = Infinity) {
|
|
145
|
+
if (this.isDone())
|
|
146
|
+
return "already completed";
|
|
147
|
+
const { time, turns } = this.timer ?? {
|
|
148
|
+
time: Date.now(),
|
|
149
|
+
turns: myTurncount(),
|
|
150
|
+
};
|
|
151
|
+
let additionalTurns;
|
|
152
|
+
try {
|
|
153
|
+
const result = prepare();
|
|
154
|
+
additionalTurns = typeof result === "number" ? result : 0;
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
print(`${e}`, "red");
|
|
158
|
+
return "failed";
|
|
159
|
+
}
|
|
160
|
+
const prediction = this.predictor();
|
|
161
|
+
const council = visitCouncil();
|
|
162
|
+
const turnCost = this._actualCost(council);
|
|
163
|
+
if (!turnCost)
|
|
164
|
+
return "already completed";
|
|
165
|
+
if (turnCost > Math.min(maxTurns, myAdventures())) {
|
|
166
|
+
return "failed";
|
|
167
|
+
}
|
|
168
|
+
if (!this.do())
|
|
169
|
+
return "failed";
|
|
170
|
+
CommunityService.log[this.property] = {
|
|
171
|
+
predictedTurns: prediction + additionalTurns,
|
|
172
|
+
turnCost: myTurncount() - turns,
|
|
173
|
+
seconds: (Date.now() - time) / 1000,
|
|
174
|
+
type: "test",
|
|
175
|
+
};
|
|
176
|
+
return "completed";
|
|
177
|
+
}
|
|
178
|
+
_verifyIsDone(councilText) {
|
|
179
|
+
return !councilText.includes(`<input type=hidden name=option value=${this.choice}>`);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Checks council.php to verify that a test is complete; more reliable than isDone, but requires an additional pagehit.
|
|
183
|
+
*
|
|
184
|
+
* @returns Whether council.php suggests that the test is complete.
|
|
185
|
+
*/
|
|
186
|
+
verifyIsDone() {
|
|
187
|
+
return this._verifyIsDone(visitCouncil());
|
|
188
|
+
}
|
|
189
|
+
_actualCost(councilText) {
|
|
190
|
+
const match = councilText.match(`<input type=hidden name=option value=${this.id}>.*?Perform Service \\((\\d+) Adventures\\)`);
|
|
191
|
+
return match ? parseInt(match[1]) : 0;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Checks council.php for the number of turns this test will take; more reliable than prediction, but requires an additional pagehit.
|
|
195
|
+
*
|
|
196
|
+
* @returns The number of turns to complete this test according to council.php.
|
|
197
|
+
*/
|
|
198
|
+
actualCost() {
|
|
199
|
+
return this._actualCost(visitCouncil());
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* @param effects A spread array of Effects to consider
|
|
203
|
+
* @returns The number of turns we expect to save if we start using those effects
|
|
204
|
+
*/
|
|
205
|
+
turnsSavedBy(...effects) {
|
|
206
|
+
const currentTurns = clamp(this.prediction, 1, 60);
|
|
207
|
+
const newTurns = clamp(this.predictor(...effects), 1, 60);
|
|
208
|
+
return currentTurns - newTurns;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* A log of the predicted turns, actual turns, and duration of each CS test performed.
|
|
212
|
+
*/
|
|
213
|
+
static log = {};
|
|
214
|
+
/**
|
|
215
|
+
* Prints turncount and time details of the test in question.
|
|
216
|
+
*
|
|
217
|
+
* @param colour The colour (or color) you'd like the log to be printed in.
|
|
218
|
+
*/
|
|
219
|
+
static printLog(colour = "blue") {
|
|
220
|
+
const logEntries = Object.entries(CommunityService.log);
|
|
221
|
+
for (const [testName, testEntry] of logEntries) {
|
|
222
|
+
const { type, predictedTurns, turnCost, seconds } = testEntry;
|
|
223
|
+
if (type === "test") {
|
|
224
|
+
print(`We predicted the ${testName} test would take ${predictedTurns} turns, ${predictedTurns === turnCost ? "and" : "but"} it took ${turnCost} turns.`, colour);
|
|
225
|
+
print(`${testName} took ${seconds.toFixed(1)} seconds.`, colour);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
if (!(predictedTurns === 0 && turnCost === 0)) {
|
|
229
|
+
print(`We predicted the task ${testName} would take ${predictedTurns} turns, ${predictedTurns === turnCost ? "and" : "but"} it took ${turnCost} turns.`, colour);
|
|
230
|
+
}
|
|
231
|
+
print(`The task ${testName} took ${seconds.toFixed(1)} seconds.`, colour);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const totalTime = sum(logEntries, ([, testEntry]) => testEntry.seconds);
|
|
235
|
+
print(`All together, you have spent ${totalTime.toFixed(1)} seconds during this Community Service run`, colour);
|
|
236
|
+
}
|
|
237
|
+
// Below, we have the tests themselves.
|
|
238
|
+
static HP = new CommunityService(1, "HP", "Donate Blood", () => 60 - Math.floor((myMaxhp() - myBuffedstat($stat `muscle`) - 3) / 30), new Requirement(["HP"], {}));
|
|
239
|
+
static Muscle = new CommunityService(2, "Muscle", "Feed The Children", statCommunityServicePredictor($stat `Muscle`), new Requirement(["Muscle"], {}));
|
|
240
|
+
static Mysticality = new CommunityService(3, "Mysticality", "Build Playground Mazes", statCommunityServicePredictor($stat `Mysticality`), new Requirement(["Mysticality"], {}));
|
|
241
|
+
static Moxie = new CommunityService(4, "Moxie", "Feed Conspirators", statCommunityServicePredictor($stat `Moxie`), new Requirement(["Moxie"], {}));
|
|
242
|
+
static FamiliarWeight = new CommunityService(5, "Familiar Weight", "Breed More Collies", (...effects) => 60 -
|
|
243
|
+
Math.floor((baseWeight() + hypotheticalModifier("Familiar Weight", ...effects)) / 5), new Requirement(["Familiar Weight"], {}));
|
|
244
|
+
static WeaponDamage = new CommunityService(6, "Weapon Damage", "Reduce Gazelle Population", (...effects) => {
|
|
245
|
+
const weaponPower = getPower(equippedItem($slot `weapon`));
|
|
246
|
+
const offhandPower = toSlot(equippedItem($slot `off-hand`)) === $slot `weapon`
|
|
247
|
+
? getPower(equippedItem($slot `off-hand`))
|
|
248
|
+
: 0;
|
|
249
|
+
const familiarPower = toSlot(equippedItem($slot `familiar`)) === $slot `weapon`
|
|
250
|
+
? getPower(equippedItem($slot `familiar`))
|
|
251
|
+
: 0;
|
|
252
|
+
// mafia does not currently count swagger
|
|
253
|
+
const multiplier = have($effect `Bow-Legged Swagger`) ? 2 : 1;
|
|
254
|
+
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
255
|
+
return (60 -
|
|
256
|
+
Math.floor((multiplier *
|
|
257
|
+
(hypotheticalModifier("Weapon Damage", ...effects) -
|
|
258
|
+
0.15 * (weaponPower + offhandPower + familiarPower))) /
|
|
259
|
+
50 +
|
|
260
|
+
0.001) -
|
|
261
|
+
Math.floor((multiplier *
|
|
262
|
+
hypotheticalModifier("Weapon Damage Percent", ...effects)) /
|
|
263
|
+
50 +
|
|
264
|
+
0.001));
|
|
265
|
+
}, new Requirement(["Weapon Damage", "Weapon Damage Percent"], {}));
|
|
266
|
+
static SpellDamage = new CommunityService(7, "Spell Damage", "Make Sausage", (...effects) => {
|
|
267
|
+
const dragonfishDamage = myFamiliar() === $familiar `Magic Dragonfish`
|
|
268
|
+
? numericModifier($familiar `Magic Dragonfish`, "Spell Damage Percent", baseWeight() + weightAdjustment(), $item.none)
|
|
269
|
+
: 0;
|
|
270
|
+
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
271
|
+
return (60 -
|
|
272
|
+
Math.floor(hypotheticalModifier("Spell Damage", ...effects) / 50 + 0.001) -
|
|
273
|
+
Math.floor((hypotheticalModifier("Spell Damage Percent", ...effects) -
|
|
274
|
+
dragonfishDamage) /
|
|
275
|
+
50 +
|
|
276
|
+
0.001));
|
|
277
|
+
}, new Requirement(["Spell Damage", "Spell Damage Percent"], {}));
|
|
278
|
+
static Noncombat = new CommunityService(8, "Non-Combat", "Be a Living Statue", (...effects) => {
|
|
279
|
+
const noncombatRate = -1 * hypotheticalModifier("Combat Rate", ...effects);
|
|
280
|
+
const unsoftcappedRate = (rate) => rate > 25 ? 25 + (rate - 25) * 5 : rate;
|
|
281
|
+
const currentFamiliarModifier = -1 *
|
|
282
|
+
numericModifier(myFamiliar(), "Combat Rate", familiarWeight(myFamiliar()) + numericModifier("Familiar Weight"), equippedItem($slot `familiar`));
|
|
283
|
+
const newFamiliarModifier = -1 *
|
|
284
|
+
numericModifier(myFamiliar(), "Combat Rate", familiarWeight(myFamiliar()) +
|
|
285
|
+
hypotheticalModifier("Familiar Weight", ...effects), equippedItem($slot `familiar`));
|
|
286
|
+
const adjustedRate = unsoftcappedRate(noncombatRate) -
|
|
287
|
+
unsoftcappedRate(currentFamiliarModifier) +
|
|
288
|
+
unsoftcappedRate(newFamiliarModifier);
|
|
289
|
+
return 60 - 3 * Math.floor(adjustedRate / 5);
|
|
290
|
+
}, new Requirement(["-combat"], {}));
|
|
291
|
+
static BoozeDrop = new CommunityService(9, "Item Drop", "Make Margaritas", (...effects) => {
|
|
292
|
+
const mummingCostume = MummingTrunk.currentCostumes().get(myFamiliar());
|
|
293
|
+
const mummingBuff = mummingCostume && mummingCostume[0] === "Item Drop"
|
|
294
|
+
? mummingCostume[1]
|
|
295
|
+
: 0;
|
|
296
|
+
const familiarItemDrop = numericModifier(myFamiliar(), "Item Drop", baseWeight() + weightAdjustment(), equippedItem($slot `familiar`)) +
|
|
297
|
+
mummingBuff -
|
|
298
|
+
numericModifier(equippedItem($slot `familiar`), "Item Drop");
|
|
299
|
+
const familiarBoozeDrop = numericModifier(myFamiliar(), "Booze Drop", baseWeight() + weightAdjustment(), equippedItem($slot `familiar`)) - numericModifier(equippedItem($slot `familiar`), "Booze Drop");
|
|
300
|
+
// Champagne doubling does NOT count for CS, so we undouble
|
|
301
|
+
const multiplier = haveEquipped($item `broken champagne bottle`) &&
|
|
302
|
+
get("garbageChampagneCharge") > 0
|
|
303
|
+
? 0.5
|
|
304
|
+
: 1;
|
|
305
|
+
// We add 0.001 because the floor function sometimes introduces weird rounding errors
|
|
306
|
+
return (60 -
|
|
307
|
+
Math.floor((multiplier *
|
|
308
|
+
(hypotheticalModifier("Item Drop", ...effects) -
|
|
309
|
+
familiarItemDrop -
|
|
310
|
+
numericModifier(myThrall(), "Item Drop"))) /
|
|
311
|
+
30 +
|
|
312
|
+
0.001) -
|
|
313
|
+
Math.floor((hypotheticalModifier("Booze Drop", ...effects) - familiarBoozeDrop) /
|
|
314
|
+
15 +
|
|
315
|
+
0.001));
|
|
316
|
+
}, new Requirement(["Item Drop", "2 Booze Drop"], {
|
|
317
|
+
preventEquip: $items `broken champagne bottle`,
|
|
318
|
+
}));
|
|
319
|
+
static HotRes = new CommunityService(10, "Hot Resistance", "Clean Steam Tunnels", (...effects) => {
|
|
320
|
+
const currentFamiliarModifier = numericModifier(myFamiliar(), "Hot Resistance", familiarWeight(myFamiliar()) + numericModifier("Familiar Weight"), equippedItem($slot `familiar`));
|
|
321
|
+
const newFamiliarModifier = numericModifier(myFamiliar(), "Hot Resistance", familiarWeight(myFamiliar()) +
|
|
322
|
+
hypotheticalModifier("Familiar Weight", ...effects), equippedItem($slot `familiar`));
|
|
323
|
+
return (60 -
|
|
324
|
+
(hypotheticalModifier("Hot Resistance", ...effects) -
|
|
325
|
+
currentFamiliarModifier +
|
|
326
|
+
newFamiliarModifier));
|
|
327
|
+
}, new Requirement(["Hot Resistance"], {}));
|
|
328
|
+
static CoilWire = new CommunityService(11, "Coil Wire", "Coil Wire", () => 60, new Requirement([], {}));
|
|
329
|
+
static donate = () => {
|
|
330
|
+
visitCouncil();
|
|
331
|
+
visitUrl("choice.php?whichchoice=1089&option=30");
|
|
332
|
+
};
|
|
333
|
+
static path = $path `Community Service`;
|
|
334
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visits the Cooling Tank on level 8 of the Fallout shelter to gain 300 rads
|
|
3
|
+
*/
|
|
4
|
+
export declare function coolingTank(): void;
|
|
5
|
+
/**
|
|
6
|
+
* Visits the Spa Simulation Chamber on level 4 of the Fallout shelter for 100 turns of "100% all stats"
|
|
7
|
+
*/
|
|
8
|
+
export declare function spa(): void;
|
|
9
|
+
/**
|
|
10
|
+
* Visits the Chronodynamics Laboratory on level 5 of the Fallout shelter to permanently increase radiation level by 3
|
|
11
|
+
*/
|
|
12
|
+
export declare function chronoLab(): void;
|
|
13
|
+
export declare const path: import("kolmafia").Path;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { visitUrl } from "kolmafia";
|
|
2
|
+
import { $path } from "../../template-string";
|
|
3
|
+
/**
|
|
4
|
+
* Visits the Cooling Tank on level 8 of the Fallout shelter to gain 300 rads
|
|
5
|
+
*/
|
|
6
|
+
export function coolingTank() {
|
|
7
|
+
visitUrl("place.php?whichplace=falloutshelter&action=vault8");
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Visits the Spa Simulation Chamber on level 4 of the Fallout shelter for 100 turns of "100% all stats"
|
|
11
|
+
*/
|
|
12
|
+
export function spa() {
|
|
13
|
+
visitUrl("place.php?whichplace=falloutshelter&action=vault3");
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Visits the Chronodynamics Laboratory on level 5 of the Fallout shelter to permanently increase radiation level by 3
|
|
17
|
+
*/
|
|
18
|
+
export function chronoLab() {
|
|
19
|
+
visitUrl("place.php?whichplace=falloutshelter&action=vault5");
|
|
20
|
+
}
|
|
21
|
+
export const path = $path `Nuclear Autumn`;
|