Skip to content

Commit cc817b9

Browse files
feat(core): Implement entire game API surface
1 parent 3790c90 commit cc817b9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+5273
-2025
lines changed

source/BonfireManager.ts

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,23 @@ import {
99
type BonfireItem,
1010
BonfireSettings,
1111
} from "./settings/BonfireSettings.js";
12-
import { cwarn } from "./tools/Log.js";
12+
import { cdebug, cwarn } from "./tools/Log.js";
1313
import type {
14-
BuildButton,
15-
Building,
16-
BuildingExt,
1714
BuildingMeta,
18-
ButtonModernController,
19-
ButtonModernModel,
20-
GameTab,
21-
} from "./types/index.js";
22-
23-
export type BonfireTab = GameTab;
15+
BuildingsModern,
16+
GatherCatnipButton,
17+
GatherCatnipButtonController,
18+
RefineCatnipButton,
19+
UnsafeBuilding,
20+
UnsafeBuildingExt,
21+
} from "./types/buildings.js";
22+
import type { ButtonModern, UnsafeButtonModernModel } from "./types/core.js";
23+
import type { Building } from "./types/index.js";
2424

2525
export class BonfireManager implements Automation {
2626
private readonly _host: KittenScientists;
2727
readonly settings: BonfireSettings;
28-
readonly manager: TabManager;
28+
readonly manager: TabManager<BuildingsModern>;
2929
private readonly _bulkManager: BulkPurchaseHelper;
3030
private readonly _workshopManager: WorkshopManager;
3131

@@ -36,7 +36,7 @@ export class BonfireManager implements Automation {
3636
) {
3737
this._host = host;
3838
this.settings = settings;
39-
this.manager = new TabManager<BonfireTab>(this._host, "Bonfire");
39+
this.manager = new TabManager<BuildingsModern>(this._host, "Bonfire");
4040

4141
this._workshopManager = workshopManager;
4242
this._bulkManager = new BulkPurchaseHelper(this._host, this._workshopManager);
@@ -69,7 +69,7 @@ export class BonfireManager implements Automation {
6969
const bulkManager = this._bulkManager;
7070

7171
// Get the current metadata for all the referenced buildings.
72-
const metaData: Partial<Record<BonfireItem, BuildingMeta>> = {};
72+
const metaData: Partial<Record<BonfireItem, Required<UnsafeBuilding>>> = {};
7373
for (const build of Object.values(builds)) {
7474
metaData[build.building] = this.getBuild(
7575
(build.baseBuilding ?? build.building) as Building,
@@ -125,7 +125,7 @@ export class BonfireManager implements Automation {
125125
this._host.engine.iactivity("upgrade.building.pasture", [], "ks-upgrade");
126126

127127
// Upgrade the pasture.
128-
this._host.game.ui.render();
128+
this._host.game.ui?.render();
129129
this.build("pasture", 1, 1);
130130
context.requestGameUiRefresh = true;
131131
}
@@ -158,7 +158,7 @@ export class BonfireManager implements Automation {
158158

159159
this._host.engine.iactivity("upgrade.building.aqueduct", [], "ks-upgrade");
160160

161-
this._host.game.ui.render();
161+
this._host.game.ui?.render();
162162
this.build("aqueduct", 1, 1);
163163
context.requestGameUiRefresh = true;
164164
}
@@ -215,7 +215,7 @@ export class BonfireManager implements Automation {
215215
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
216216
libraryMeta.calculateEffects?.(libraryMeta, this._host.game);
217217
this._host.engine.iactivity("upgrade.building.library", [], "ks-upgrade");
218-
this._host.game.ui.render();
218+
this._host.game.ui?.render();
219219
this.build("library", 1, 1);
220220
context.requestGameUiRefresh = true;
221221
return;
@@ -241,7 +241,7 @@ export class BonfireManager implements Automation {
241241

242242
this._host.engine.iactivity("upgrade.building.warehouse", [], "ks-upgrade");
243243

244-
this._host.game.ui.render();
244+
this._host.game.ui?.render();
245245
this.build("warehouse", 1, 1);
246246
context.requestGameUiRefresh = true;
247247

@@ -272,7 +272,7 @@ export class BonfireManager implements Automation {
272272

273273
this._host.engine.iactivity("upgrade.building.amphitheatre", [], "ks-upgrade");
274274

275-
this._host.game.ui.render();
275+
this._host.game.ui?.render();
276276
this.build("amphitheatre", 1, 1);
277277
context.requestGameUiRefresh = true;
278278
}
@@ -333,7 +333,7 @@ export class BonfireManager implements Automation {
333333
autoGather(): void {
334334
const controller = new classes.game.ui.GatherCatnipButtonController(this._host.game);
335335
for (let clicks = 0; clicks < Math.floor(this._host.engine.settings.interval / 20); ++clicks) {
336-
controller.buyItem(null, null);
336+
controller.buyItem(undefined, null);
337337
}
338338
}
339339

@@ -369,22 +369,32 @@ export class BonfireManager implements Automation {
369369
}
370370
}
371371

372-
private _getBuildLabel(meta: BuildingMeta, stage?: number): string {
372+
private _getBuildLabel(meta: UnsafeBuilding, stage?: number): string {
373373
return meta.stages && !isNil(stage) ? meta.stages[stage].label : mustExist(meta.label);
374374
}
375375

376-
getBuild(name: Building): BuildingExt {
377-
return this._host.game.bld.getBuildingExt(name);
376+
getBuild(name: Building): BuildingMeta<Required<UnsafeBuilding>> {
377+
return this._host.game.bld.getBuildingExt(name) as BuildingMeta<Required<UnsafeBuilding>>;
378378
}
379379

380-
getBuildButton(
381-
name: Building,
382-
stage?: number,
383-
): BuildButton<string, ButtonModernModel, ButtonModernController> | null {
380+
getBuildButton(name: Building, stage?: number) {
384381
const buttons = this.manager.tab.children;
385-
const build = this.getBuild(name);
386-
const label = this._getBuildLabel(build.meta, stage);
387-
return (buttons.find(button => (button.model?.options.name as string).startsWith(label)) ??
388-
null) as BuildButton<string, ButtonModernModel, ButtonModernController> | null;
382+
383+
const button =
384+
(
385+
buttons.filter(
386+
button =>
387+
button instanceof com.nuclearunicorn.game.ui.ButtonModern === false &&
388+
button instanceof classes.game.ui.RefineCatnipButton === false,
389+
) as Array<Exclude<(typeof buttons)[number], GatherCatnipButton | RefineCatnipButton>>
390+
).find(
391+
button => button.model?.metadata.name === name && button.model?.metadata.stage === stage,
392+
) ?? null;
393+
394+
if (button === null) {
395+
cdebug(`Couldn't find button for ${name}! This will likely create problems.`);
396+
}
397+
398+
return button;
389399
}
390400
}

source/KittenScientists.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import { ScienceSettings } from "./settings/ScienceSettings.js";
77
import { SpaceSettings } from "./settings/SpaceSettings.js";
88
import { WorkshopSettings } from "./settings/WorkshopSettings.js";
99
import { cdebug, cerror, cinfo, cwarn } from "./tools/Log.js";
10-
import type { Game, I18nEngine } from "./types/index.js";
11-
import type { ReleaseChannel, ReleaseInfoSchema } from "./types/releases.js";
10+
import type { ReleaseChannel, ReleaseInfoSchema } from "./types/_releases.js";
11+
import type { GamePage } from "./types/game.js";
12+
import type { I18nEngine } from "./types/index.js";
1213
import { UserInterface } from "./ui/UserInterface.js";
1314

1415
declare global {
@@ -25,7 +26,7 @@ export const ksVersion = (prefix = "") => {
2526
};
2627

2728
export class KittenScientists {
28-
readonly game: Game;
29+
readonly game: GamePage;
2930

3031
/**
3132
* A function in the game that allows to retrieve translated messages.
@@ -42,7 +43,7 @@ export class KittenScientists {
4243
private _serverLoadHandle: ["server/load", number] | undefined;
4344

4445
constructor(
45-
game: Game,
46+
game: GamePage,
4647
i18nEngine: I18nEngine,
4748
gameLanguage: GameLanguage = "en",
4849
engineState?: EngineState,

source/ReligionManager.ts

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,29 @@ import { TabManager } from "./TabManager.js";
66
import type { WorkshopManager } from "./WorkshopManager.js";
77
import { BulkPurchaseHelper } from "./helper/BulkPurchaseHelper.js";
88
import { BonfireBuildingSetting } from "./settings/BonfireSettings.js";
9+
import { ReligionSettings, type ReligionSettingsItem } from "./settings/ReligionSettings.js";
10+
import { negativeOneToInfinity } from "./tools/Format.js";
11+
import { cdebug, cwarn } from "./tools/Log.js";
12+
import type { UnsafeButtonModernModel } from "./types/core.js";
913
import {
1014
type FaithItem,
1115
type ReligionItem,
12-
ReligionSettings,
13-
type ReligionSettingsItem,
14-
type UnicornItem,
15-
UnicornItems,
16-
} from "./settings/ReligionSettings.js";
17-
import { negativeOneToInfinity } from "./tools/Format.js";
18-
import { cwarn } from "./tools/Log.js";
19-
import {
20-
type BuildButton,
21-
type ButtonModernController,
22-
type ButtonModernModel,
23-
type ReligionTab,
2416
type ReligionUpgrade,
25-
type ReligionUpgradeInfo,
2617
type TranscendenceUpgrade,
27-
type TranscendenceUpgradeInfo,
28-
type TransformBtnController,
18+
type UnicornItem,
2919
UnicornItemVariant,
20+
UnicornItems,
3021
type ZiggurathUpgrade,
31-
type ZiggurathUpgradeInfo,
3222
} from "./types/index.js";
23+
import type {
24+
CryptotheologyPanel,
25+
CryptotheologyWGT,
26+
ReligionTab,
27+
TransformBtnController,
28+
UnsafeReligionUpgrade,
29+
UnsafeTranscendenceUpgrade,
30+
UnsafeZiggurathUpgrade,
31+
} from "./types/religion.js";
3332

3433
export class ReligionManager implements Automation {
3534
private readonly _host: KittenScientists;
@@ -170,7 +169,7 @@ export class ReligionManager implements Automation {
170169
needSacrifice < maxSacrifice &&
171170
!isNil(this._host.game.religionTab.sacrificeBtn.model)
172171
) {
173-
this._host.game.religionTab.sacrificeBtn.controller._transform(
172+
this._host.game.religionTab.sacrificeBtn?.controller?._transform(
174173
this._host.game.religionTab.sacrificeBtn.model,
175174
needSacrifice,
176175
);
@@ -218,7 +217,7 @@ export class ReligionManager implements Automation {
218217
this.manager.render();
219218

220219
const metaData: Partial<
221-
Record<FaithItem, ReligionUpgradeInfo | TranscendenceUpgradeInfo | ZiggurathUpgradeInfo>
220+
Record<FaithItem, UnsafeReligionUpgrade | UnsafeTranscendenceUpgrade | UnsafeZiggurathUpgrade>
222221
> = this.getBuildMetaData(builds);
223222
const sectionTrigger = this.settings.trigger;
224223

@@ -436,7 +435,7 @@ export class ReligionManager implements Automation {
436435

437436
getBuildMetaData(builds: Partial<Record<FaithItem, ReligionSettingsItem>>) {
438437
const metaData: Partial<
439-
Record<FaithItem, ReligionUpgradeInfo | TranscendenceUpgradeInfo | ZiggurathUpgradeInfo>
438+
Record<FaithItem, UnsafeReligionUpgrade | UnsafeTranscendenceUpgrade | UnsafeZiggurathUpgrade>
440439
> = {};
441440
for (const build of Object.values(builds)) {
442441
const buildInfo = this.getBuild(build.building, build.variant);
@@ -470,10 +469,7 @@ export class ReligionManager implements Automation {
470469
* @param variant The variant of the upgrade.
471470
* @returns The build information for the upgrade.
472471
*/
473-
getBuild(
474-
name: ReligionItem | "unicornPasture",
475-
variant: UnicornItemVariant,
476-
): ReligionUpgradeInfo | TranscendenceUpgradeInfo | ZiggurathUpgradeInfo | null {
472+
getBuild(name: ReligionItem | "unicornPasture", variant: UnicornItemVariant) {
477473
switch (variant) {
478474
case UnicornItemVariant.Ziggurat:
479475
return this._host.game.religion.getZU(name as ZiggurathUpgrade) ?? null;
@@ -482,7 +478,7 @@ export class ReligionManager implements Automation {
482478
case UnicornItemVariant.Cryptotheology:
483479
return this._host.game.religion.getTU(name as TranscendenceUpgrade) ?? null;
484480
}
485-
return null;
481+
throw new Error(`Unknown build: ${name} (${variant})`);
486482
}
487483

488484
/**
@@ -492,11 +488,11 @@ export class ReligionManager implements Automation {
492488
* @param variant The variant of the upgrade.
493489
* @returns The button to buy the upgrade, or `null`.
494490
*/
495-
private _getBuildButton(
496-
name: ReligionItem | "unicornPasture",
497-
variant: UnicornItemVariant,
498-
): BuildButton<string, ButtonModernModel, ButtonModernController> | null {
499-
let buttons: Array<BuildButton>;
491+
private _getBuildButton(name: ReligionItem | "unicornPasture", variant: UnicornItemVariant) {
492+
let buttons:
493+
| typeof this.manager.tab.zgUpgradeButtons
494+
| typeof this.manager.tab.rUpgradeButtons
495+
| CryptotheologyWGT["children"];
500496
switch (variant) {
501497
case UnicornItemVariant.Ziggurat:
502498
buttons = this.manager.tab.zgUpgradeButtons;
@@ -505,7 +501,7 @@ export class ReligionManager implements Automation {
505501
buttons = this.manager.tab.rUpgradeButtons;
506502
break;
507503
case UnicornItemVariant.Cryptotheology:
508-
buttons = this.manager.tab.children[0].children[0].children;
504+
buttons = (this.manager.tab.children[0] as CryptotheologyPanel).children[0].children;
509505
break;
510506
default:
511507
throw new Error(`Invalid variant '${variant}'`);
@@ -516,26 +512,28 @@ export class ReligionManager implements Automation {
516512
return null;
517513
}
518514

519-
return (buttons.find(button => button.id === name) ?? null) as BuildButton<
520-
string,
521-
ButtonModernModel,
522-
ButtonModernController
523-
> | null;
515+
const button = buttons.find(button => button.id === name) ?? null;
516+
517+
if (button === null) {
518+
cdebug(`Couldn't find button for ${name}! This will likely create problems.`);
519+
}
520+
521+
return button;
524522
}
525523

526524
private _transformBtnSacrificeHelper(
527525
available: number,
528526
total: number,
529527
controller: TransformBtnController,
530-
model: ButtonModernModel,
528+
model: UnsafeButtonModernModel,
531529
) {
532530
const conversionPercentage = available / total;
533531
const percentageInverse = 1 / conversionPercentage;
534532

535533
const customController = new classes.ui.religion.TransformBtnController(
536534
game,
537535
controller.controllerOpts,
538-
) as TransformBtnController;
536+
);
539537

540538
const link = customController._newLink(model, percentageInverse);
541539
return new Promise<boolean>(resolve => {
@@ -796,9 +794,9 @@ export class ReligionManager implements Automation {
796794
this._host.game.religion.transcendenceTier += 1;
797795

798796
const atheism = mustExist(this._host.game.challenges.getChallenge("atheism"));
799-
atheism.calculateEffects(atheism, this._host.game);
797+
atheism.calculateEffects?.(atheism, this._host.game);
800798
const blackObelisk = mustExist(this._host.game.religion.getTU("blackObelisk"));
801-
blackObelisk.calculateEffects(blackObelisk, this._host.game);
799+
blackObelisk.calculateEffects?.(blackObelisk, this._host.game);
802800

803801
this._host.game.msg(
804802
this._host.engine.i18n("$religion.transcend.msg.success", [

source/ScienceManager.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import { UserScriptLoader } from "./UserScriptLoader.js";
77
import type { WorkshopManager } from "./WorkshopManager.js";
88
import { ScienceSettings } from "./settings/ScienceSettings.js";
99
import { cerror } from "./tools/Log.js";
10-
import type { PolicyInfo, ScienceTab, TechInfo } from "./types/index.js";
10+
import type { Library, UnsafePolicy, UnsafeTech } from "./types/science.js";
1111

1212
export class ScienceManager extends UpgradeManager {
13-
readonly manager: TabManager<ScienceTab>;
13+
readonly manager: TabManager<Library>;
1414
readonly settings: ScienceSettings;
1515
private readonly _workshopManager: WorkshopManager;
1616

@@ -51,7 +51,7 @@ export class ScienceManager extends UpgradeManager {
5151

5252
async autoUnlock() {
5353
const techs = this._host.game.science.techs;
54-
const toUnlock = new Array<TechInfo>();
54+
const toUnlock = new Array<UnsafeTech>();
5555

5656
workLoop: for (const setting of Object.values(this.settings.techs.techs)) {
5757
if (!setting.enabled) {
@@ -92,7 +92,7 @@ export class ScienceManager extends UpgradeManager {
9292

9393
async autoPolicy() {
9494
const policies = this._host.game.science.policies;
95-
const toUnlock = new Array<PolicyInfo>();
95+
const toUnlock = new Array<UnsafePolicy>();
9696

9797
for (const setting of Object.values(this.settings.policies.policies)) {
9898
if (!setting.enabled) {

0 commit comments

Comments
 (0)