Skip to content

Commit 5b1c1ed

Browse files
feat(core): Implement more detailed types
Also replaces some button accesses with manual model+controller construction.
1 parent d9bee8f commit 5b1c1ed

21 files changed

+1299
-969
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ git-hook:
1313
echo "make pretty" > .git/hooks/pre-commit
1414

1515
pretty: node_modules
16-
yarn biome check --write --no-errors-on-unmatched
16+
yarn biome check --no-errors-on-unmatched --fix --unsafe
1717
npm pkg fix
1818

1919
lint: node_modules

source/BonfireManager.ts

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@ import type {
1414
BuildingBtnModernController,
1515
BuildingMeta,
1616
BuildingsModern,
17+
GatherCatnipButtonController,
1718
StagingBldBtnController,
1819
UnsafeBuilding,
20+
UnsafeStagingBldButtonOptions,
21+
UnsafeUnstagedBuildingButtonOptions,
1922
} from "./types/buildings.js";
20-
import type { UnsafeBuildingBtnModel } from "./types/core.js";
23+
import type {
24+
AllBuildingStackableBtnOptions,
25+
UnsafeBuildingBtnModel,
26+
UnsafeBuildingBtnModernModel,
27+
} from "./types/core.js";
2128
import type { Building } from "./types/index.js";
2229

2330
export class BonfireManager implements Automation {
@@ -327,32 +334,38 @@ export class BonfireManager implements Automation {
327334
}
328335

329336
autoGather(): void {
330-
const controller = new classes.game.ui.GatherCatnipButtonController(this._host.game);
337+
const controller = new classes.game.ui.GatherCatnipButtonController(
338+
this._host.game,
339+
) as GatherCatnipButtonController;
331340
for (let clicks = 0; clicks < Math.floor(this._host.engine.settings.interval / 20); ++clicks) {
332341
controller.buyItem(undefined, null);
333342
}
334343
}
335344

336-
build(name: Building, stage: number | undefined, amount: number): void {
345+
build(name: Building, _stage: number | undefined, amount: number): void {
337346
let amountCalculated = amount;
338-
const build = this.getBuild(name);
339-
const button = this.getBuildButton(name, stage);
340-
341-
if (!button?.model) {
342-
return;
343-
}
344-
345-
if (!button.model.enabled) {
346-
return;
347+
const amountTemp = amountCalculated;
348+
let label: string;
349+
const meta = game.bld.get(name);
350+
const metaExt = game.bld.getBuildingExt(name).getMeta();
351+
if ("stages" in meta) {
352+
const controller = new classes.ui.btn.StagingBldBtnController(
353+
this._host.game,
354+
) as StagingBldBtnController<UnsafeBuildingBtnModernModel<UnsafeStagingBldButtonOptions>>;
355+
const model = controller.fetchModel(metaExt);
356+
amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);
357+
label = metaExt.label ?? "";
358+
} else {
359+
const controller = new classes.ui.btn.BuildingBtnModernController(
360+
this._host.game,
361+
) as BuildingBtnModernController<
362+
UnsafeBuildingBtnModernModel<UnsafeUnstagedBuildingButtonOptions>
363+
>;
364+
const model = controller.fetchModel(meta);
365+
amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);
366+
label = meta.label ?? "";
347367
}
348368

349-
const amountTemp = amountCalculated;
350-
const label = this._getBuildLabel(build.meta, stage);
351-
amountCalculated = this._bulkManager.construct(
352-
button.model,
353-
button.controller,
354-
amountCalculated,
355-
);
356369
if (amountCalculated !== amountTemp) {
357370
cwarn(`${label} Amount ordered: ${amountTemp} Amount Constructed: ${amountCalculated}`);
358371
}
@@ -387,10 +400,10 @@ export class BonfireManager implements Automation {
387400
"stages" in meta
388401
? (new classes.ui.btn.StagingBldBtnController(
389402
this._host.game,
390-
) as StagingBldBtnController<UnsafeBuildingBtnModel>)
403+
) as StagingBldBtnController<UnsafeBuildingBtnModernModel>)
391404
: (new classes.ui.btn.BuildingBtnModernController(
392405
this._host.game,
393-
) as BuildingBtnModernController<UnsafeBuildingBtnModel>);
406+
) as BuildingBtnModernController<UnsafeBuildingBtnModernModel>);
394407
const model = controller.fetchModel({
395408
key: name,
396409
name: meta.label,

source/ReligionManager.ts

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { isNil, mustExist } from "@oliversalzburg/js-utils/data/nil.js";
2+
import { InvalidOperationError } from "@oliversalzburg/js-utils/errors/InvalidOperationError.js";
23
import type { BonfireManager } from "./BonfireManager.js";
34
import type { Automation, FrameContext } from "./Engine.js";
45
import type { KittenScientists } from "./KittenScientists.js";
@@ -9,7 +10,6 @@ import { BonfireBuildingSetting } from "./settings/BonfireSettings.js";
910
import { ReligionSettings, type ReligionSettingsItem } from "./settings/ReligionSettings.js";
1011
import { negativeOneToInfinity } from "./tools/Format.js";
1112
import { cdebug, cwarn } from "./tools/Log.js";
12-
import type { UnsafeButtonModernModel } from "./types/core.js";
1313
import {
1414
type FaithItem,
1515
type ReligionItem,
@@ -23,9 +23,13 @@ import {
2323
import type {
2424
CryptotheologyPanel,
2525
CryptotheologyWGT,
26+
ReligionBtnController,
2627
ReligionTab,
28+
TranscendenceBtnController,
2729
TransformBtnController,
2830
UnsafeReligionUpgrade,
31+
UnsafeTranscendenceBtnModel,
32+
UnsafeTranscendenceButtonOptions,
2933
UnsafeTranscendenceUpgrade,
3034
UnsafeTransformBtnModel,
3135
UnsafeZiggurathUpgrade,
@@ -335,7 +339,7 @@ export class ReligionManager implements Automation {
335339
// For all ziggurath upgrade buttons...
336340
for (const button of this.manager.tab.zgUpgradeButtons) {
337341
// ...that are in the "valid" buildings (are unicorn-related) and visible (unlocked)...
338-
if (validBuildings.includes(button.id) && button.model?.visible) {
342+
if (validBuildings.includes(button.id) && button.model.visible) {
339343
// Determine a price value for this building.
340344
let unicornPrice = 0;
341345
for (const price of mustExist(button.model.prices)) {
@@ -390,28 +394,38 @@ export class ReligionManager implements Automation {
390394

391395
build(name: ReligionItem | "unicornPasture", variant: UnicornItemVariant, amount: number): void {
392396
let amountCalculated = amount;
393-
const build = this.getBuild(name, variant);
394-
if (build === null) {
395-
throw new Error(`Unable to build '${name}'. Build information not available.`);
396-
}
397-
398-
const button = this._getBuildButton(name, variant);
399-
400-
if (!button?.model) {
401-
return;
402-
}
403-
404-
if (!button.model.enabled) {
405-
return;
397+
const amountTemp = amountCalculated;
398+
let label: string;
399+
if (variant === UnicornItemVariant.Cryptotheology) {
400+
const meta = game.religion.getTU(name as TranscendenceUpgrade);
401+
const controller = new classes.ui.TranscendenceBtnController(
402+
this._host.game,
403+
) as TranscendenceBtnController<
404+
UnsafeTranscendenceBtnModel<UnsafeTranscendenceButtonOptions>
405+
>;
406+
const model = controller.fetchModel(meta);
407+
amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);
408+
label = meta.label;
409+
} else if (variant === UnicornItemVariant.OrderOfTheSun) {
410+
const meta = game.religion.getRU(name as ReligionUpgrade);
411+
const controller = new com.nuclearunicorn.game.ui.ReligionBtnController(
412+
this._host.game,
413+
) as ReligionBtnController;
414+
const model = controller.fetchModel(meta);
415+
amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);
416+
label = meta.label;
417+
} else if (variant === UnicornItemVariant.Ziggurat) {
418+
const meta = game.religion.getZU(name as ZiggurathUpgrade);
419+
const controller = new com.nuclearunicorn.game.ui.ReligionBtnController(
420+
this._host.game,
421+
) as ReligionBtnController;
422+
const model = controller.fetchModel(meta);
423+
amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);
424+
label = meta.label;
425+
} else {
426+
throw new InvalidOperationError("unsupported");
406427
}
407428

408-
const amountTemp = amountCalculated;
409-
const label = build.label;
410-
amountCalculated = this._bulkManager.construct(
411-
button.model,
412-
mustExist(button.controller),
413-
amountCalculated,
414-
);
415429
if (amountCalculated !== amountTemp) {
416430
cwarn(`${label} Amount ordered: ${amountTemp} Amount Constructed: ${amountCalculated}`);
417431
}

source/SpaceManager.ts

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@ import { TabManager } from "./TabManager.js";
55
import type { WorkshopManager } from "./WorkshopManager.js";
66
import { BulkPurchaseHelper } from "./helper/BulkPurchaseHelper.js";
77
import { type SpaceBuildingSetting, SpaceSettings } from "./settings/SpaceSettings.js";
8-
import { cdebug, cwarn } from "./tools/Log.js";
9-
import type { BuildingStackableBtn, UnsafeBuildingBtnModel } from "./types/core.js";
8+
import { cwarn } from "./tools/Log.js";
9+
import type {
10+
BuildingStackableBtn,
11+
UnsafeBuildingBtnModel,
12+
UnsafeBuildingStackableBtnModel,
13+
} from "./types/core.js";
1014
import type { Mission, SpaceBuilding } from "./types/index.js";
1115
import type {
1216
PlanetBuildingBtnController,
1317
SpaceTab,
1418
UnsafePlanet,
19+
UnsafePlanetBuildingButtonOptions,
1520
UnsafeSpaceBuilding,
21+
UnsafeSpaceProgramButtonOptions,
1622
} from "./types/space.js";
1723

1824
export class SpaceManager implements Automation {
@@ -129,25 +135,18 @@ export class SpaceManager implements Automation {
129135

130136
build(name: SpaceBuilding, amount: number): number {
131137
let amountCalculated = amount;
132-
const build = this.getBuild(name);
133-
134-
const button = this._getBuildButton(name);
135-
136-
if (!build.unlocked || !button?.model || !this.settings.buildings[name].enabled) {
137-
return 0;
138-
}
139-
140-
if (!button.model.enabled) {
141-
return 0;
142-
}
143-
144138
const amountTemp = amountCalculated;
145-
const label = build.label;
146-
amountCalculated = this._bulkManager.construct(
147-
button.model,
148-
button.controller,
149-
amountCalculated,
150-
);
139+
let label: string;
140+
const meta = game.space.getBuilding(name);
141+
const controller = new classes.ui.space.PlanetBuildingBtnController(
142+
this._host.game,
143+
) as PlanetBuildingBtnController<
144+
UnsafeBuildingStackableBtnModel<UnsafePlanetBuildingButtonOptions>
145+
>;
146+
const model = controller.fetchModel(meta);
147+
amountCalculated = this._bulkManager.construct(model, controller, amountCalculated);
148+
label = meta.label;
149+
151150
if (amountCalculated !== amountTemp) {
152151
cwarn(`${label} Amount ordered: ${amountTemp} Amount Constructed: ${amountCalculated}`);
153152
}
@@ -177,15 +176,13 @@ export class SpaceManager implements Automation {
177176
return null;
178177
}
179178

180-
let button: BuildingStackableBtn<
181-
{
182-
id: SpaceBuilding;
183-
planet: UnsafePlanet;
184-
controller: PlanetBuildingBtnController;
185-
},
186-
PlanetBuildingBtnController,
187-
SpaceBuilding
188-
> | null = null;
179+
let button: BuildingStackableBtn<{
180+
id: SpaceBuilding;
181+
planet: UnsafePlanet;
182+
controller: PlanetBuildingBtnController<
183+
UnsafeBuildingStackableBtnModel<UnsafeSpaceProgramButtonOptions>
184+
>;
185+
}> | null = null;
189186
for (const panel of panels) {
190187
button = panel.children.find(child => child.id === id) ?? null;
191188

source/TimeControlManager.ts

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,29 @@ import type { WorkshopManager } from "./WorkshopManager.js";
99
import { type CycleIndices, TimeControlSettings } from "./settings/TimeControlSettings.js";
1010
import { objectEntries } from "./tools/Entries.js";
1111
import { negativeOneToInfinity } from "./tools/Format.js";
12-
import type { GatherCatnipButtonController, UnsafeBuildingExt } from "./types/buildings.js";
1312
import type {
14-
BuildingBtnController,
13+
BuildingMeta,
14+
UnsafeBuilding,
15+
UnsafeUnstagedBuildingButtonOptions,
16+
} from "./types/buildings.js";
17+
import type {
18+
AllBuildingBtnOptions,
19+
AllBuildingStackableBtnOptions,
20+
AllButtonIds,
21+
AllButtonOptions,
22+
BuildingBtn,
1523
Button,
16-
ButtonController,
17-
ButtonModern,
18-
ButtonModernController,
1924
UnsafeBuildingBtnModel,
20-
UnsafeButtonModel,
21-
UnsafeButtonModernModel,
22-
UnsafeButtonOptions,
2325
} from "./types/core.js";
2426
import {
2527
type Building,
2628
type ChronoForgeUpgrade,
2729
Cycles,
30+
type Price,
2831
TimeItemVariant,
2932
type VoidSpaceUpgrade,
3033
} from "./types/index.js";
31-
import type {
32-
ReligionBtnController,
33-
TranscendBtnController,
34-
TranscendenceBtnController,
35-
TransformBtnController,
36-
ZigguratBtnController,
37-
} from "./types/religion.js";
38-
import type {
39-
ChronoforgeBtnController,
40-
ShatterTCBtn,
41-
ShatterTCBtnController,
42-
TimeTab,
43-
VoidSpaceBtnController,
44-
} from "./types/time.js";
34+
import type { ShatterTCBtn, ShatterTCBtnController, TimeTab } from "./types/time.js";
4535

4636
export class TimeControlManager {
4737
private readonly _host: KittenScientists;
@@ -103,31 +93,7 @@ export class TimeControlManager {
10393
// If we don't have a given item, but we *could* buy it, then we act
10494
// as if we already had it.
10595
const check = <
106-
T extends Button<
107-
UnsafeButtonOptions<
108-
| BuildingBtnController
109-
| ButtonController
110-
| ButtonModernController
111-
| ChronoforgeBtnController
112-
| ReligionBtnController
113-
| TranscendBtnController
114-
| TranscendenceBtnController
115-
| TransformBtnController
116-
| VoidSpaceBtnController
117-
| ZigguratBtnController
118-
>,
119-
| BuildingBtnController
120-
| ButtonController
121-
| ButtonModernController
122-
| ChronoforgeBtnController
123-
| ReligionBtnController
124-
| TranscendBtnController
125-
| TranscendenceBtnController
126-
| TransformBtnController
127-
| VoidSpaceBtnController
128-
| ZigguratBtnController,
129-
string | undefined
130-
>,
96+
T extends BuildingBtn<UnsafeBuildingBtnModel<UnsafeUnstagedBuildingButtonOptions>>,
13197
>(
13298
buttons: Array<T>,
13399
) => {
@@ -137,13 +103,13 @@ export class TimeControlManager {
137103
continue;
138104
}
139105

140-
const model = button.model as UnsafeBuildingBtnModel<unknown, { name: Building }>;
106+
const model = button.model as { metadata: { name: string }; prices: Array<Price> };
141107

142108
const name = model.metadata.name;
143109
const index = checkList.indexOf(name);
144110
if (index !== -1) {
145111
checkList.splice(index, 1);
146-
if (this._host.game.resPool.hasRes(mustExist(button.model.prices))) {
112+
if (this._host.game.resPool.hasRes(mustExist(model.prices))) {
147113
return true;
148114
}
149115
}
@@ -156,7 +122,7 @@ export class TimeControlManager {
156122
for (const [name, entry] of objectEntries(this.settings.reset.bonfire.buildings))
157123
if (entry.enabled) {
158124
// TODO: Obvious error here. For upgraded buildings, it needs special handling.
159-
let bld: UnsafeBuildingExt | null;
125+
let bld: BuildingMeta<UnsafeBuilding> | null;
160126
try {
161127
// @ts-expect-error Obvious error here. For upgraded buildings, it needs special handling.
162128
bld = this._host.game.bld.getBuildingExt(name);

0 commit comments

Comments
 (0)