Skip to content

Commit

Permalink
feat(core): Use explicit controller types
Browse files Browse the repository at this point in the history
So far, we've used only a single type to define the shape of controllers in KG. We now have distinct definitions for each controller, which we can extend over time.
  • Loading branch information
oliversalzburg committed Jan 7, 2023
1 parent 0bc8a59 commit c3f824b
Show file tree
Hide file tree
Showing 10 changed files with 286 additions and 104 deletions.
27 changes: 19 additions & 8 deletions packages/userscript/source/BonfireManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import { BonfireBuildingSetting, BonfireItem, BonfireSettings } from "./settings
import { TabManager } from "./TabManager";
import { cwarn } from "./tools/Log";
import { isNil, mustExist } from "./tools/Maybe";
import { BuildButton, Building, BuildingExt, BuildingMeta, GameTab } from "./types";
import {
BuildButton,
Building,
BuildingExt,
BuildingMeta,
ButtonModernController,
ButtonModernModel,
GameTab,
} from "./types";
import { UserScript } from "./UserScript";
import { WorkshopManager } from "./WorkshopManager";

Expand Down Expand Up @@ -113,7 +121,7 @@ export class BonfireManager implements Automation {
// We need to perform the process like this to avoid UI confirmations
// for selling items.
// Sell all pastures (to regain the resources).
button.controller.sellInternal!(button.model, 0);
button.controller.sellInternal(button.model, 0);
// Manually update the metadata, as we bypassed the full selling logic.
pastureMeta.on = 0;
pastureMeta.val = 0;
Expand Down Expand Up @@ -145,7 +153,7 @@ export class BonfireManager implements Automation {
const prices = mustExist(aqueductMeta.stages)[1].prices;
if (this._bulkManager.singleBuildPossible(aqueductMeta, prices, 1)) {
const button = mustExist(this.getBuildButton("aqueduct", 0));
button.controller.sellInternal!(button.model, 0);
button.controller.sellInternal(button.model, 0);
aqueductMeta.on = 0;
aqueductMeta.val = 0;
aqueductMeta.stage = 1;
Expand Down Expand Up @@ -206,7 +214,7 @@ export class BonfireManager implements Automation {
const prices = mustExist(libraryMeta.stages)[1].prices;
if (this._bulkManager.singleBuildPossible(libraryMeta, prices, 1)) {
const button = mustExist(this.getBuildButton("library", 0));
button.controller.sellInternal!(button.model, 0);
button.controller.sellInternal(button.model, 0);
libraryMeta.on = 0;
libraryMeta.val = 0;
libraryMeta.stage = 1;
Expand Down Expand Up @@ -235,7 +243,7 @@ export class BonfireManager implements Automation {
const prices = mustExist(amphitheatreMeta.stages)[1].prices;
if (this._bulkManager.singleBuildPossible(amphitheatreMeta, prices, 1)) {
const button = mustExist(this.getBuildButton("amphitheatre", 0));
button.controller.sellInternal!(button.model, 0);
button.controller.sellInternal(button.model, 0);
amphitheatreMeta.on = 0;
amphitheatreMeta.val = 0;
amphitheatreMeta.stage = 1;
Expand All @@ -257,7 +265,7 @@ export class BonfireManager implements Automation {
const steamworks = this._host.gamePage.bld.getBuildingExt("steamworks");
if (steamworks.meta.val && steamworks.meta.on === 0) {
const button = mustExist(this.getBuildButton("steamworks"));
button.controller.onAll!(button.model);
button.controller.onAll(button.model);
}
}

Expand Down Expand Up @@ -297,15 +305,18 @@ export class BonfireManager implements Automation {
return this._host.gamePage.bld.getBuildingExt(name);
}

getBuildButton(name: Building, stage?: number): BuildButton | null {
getBuildButton(
name: Building,
stage?: number
): BuildButton<string, ButtonModernModel, ButtonModernController> | null {
const buttons = this.manager.tab.children;
const build = this.getBuild(name);
const label = this._getBuildLabel(build.meta, stage);

for (const button of buttons) {
const haystack = button.model.name;
if (haystack.indexOf(label) !== -1) {
return button;
return button as BuildButton<string, ButtonModernModel, ButtonModernController>;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/userscript/source/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export class Engine {
this.spaceManager.tick(context);
await this.workshopManager.tick(context);
this.tradeManager.tick(context);
this.religionManager.tick(context);
await this.religionManager.tick(context);
this.timeManager.tick(context);
this.villageManager.tick(context);
await this.timeControlManager.tick(context);
Expand Down
28 changes: 20 additions & 8 deletions packages/userscript/source/ReligionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { cwarn } from "./tools/Log";
import { isNil, mustExist } from "./tools/Maybe";
import {
BuildButton,
ButtonModernController,
ButtonModernModel,
ReligionTab,
ReligionUpgradeInfo,
ReligionUpgrades,
Expand Down Expand Up @@ -118,7 +120,9 @@ export class ReligionManager implements Automation {
);

let tearsNeeded = 0;
const priceTears = buildingButton.model.prices.find(subject => subject.name === "tears");
const priceTears = mustExist(mustExist(buildingButton.model).prices).find(
subject => subject.name === "tears"
);
if (!isNil(priceTears)) {
tearsNeeded = priceTears.val;
}
Expand All @@ -145,7 +149,7 @@ export class ReligionManager implements Automation {

// Sacrifice some unicorns to get the tears to buy the building.
if (needSacrifice < maxSacrifice) {
this._host.gamePage.religionTab.sacrificeBtn.controller._transform!(
this._host.gamePage.religionTab.sacrificeBtn.controller._transform(
this._host.gamePage.religionTab.sacrificeBtn.model,
needSacrifice
);
Expand Down Expand Up @@ -310,7 +314,7 @@ export class ReligionManager implements Automation {
// If the unicorn pasture amortizes itself in less than infinity ticks,
// set it as the default. This is likely to protect against cases where
// production of unicorns is 0.
const pastureAmortization = pastureButton.model.prices[0].val / pastureProduction;
const pastureAmortization = mustExist(pastureButton.model.prices)[0].val / pastureProduction;
if (pastureAmortization < bestAmoritization) {
bestAmoritization = pastureAmortization;
bestBuilding = "unicornPasture";
Expand All @@ -322,7 +326,7 @@ export class ReligionManager implements Automation {
if (validBuildings.includes(button.id) && button.model.visible) {
// Determine a price value for this building.
let unicornPrice = 0;
for (const price of button.model.prices) {
for (const price of mustExist(button.model.prices)) {
// Add the amount of unicorns the building costs (if any).
if (price.name === "unicorns") {
unicornPrice += price.val;
Expand Down Expand Up @@ -470,7 +474,7 @@ export class ReligionManager implements Automation {
getBuildButton(
name: ReligionUpgrades | TranscendenceUpgrades | ZiggurathUpgrades,
variant: UnicornItemVariant
): BuildButton | null {
): BuildButton<string, ButtonModernModel, ButtonModernController> | null {
let buttons: Array<BuildButton>;
switch (variant) {
case UnicornItemVariant.Ziggurat:
Expand All @@ -494,7 +498,7 @@ export class ReligionManager implements Automation {
for (const button of buttons) {
const haystack = button.model.name;
if (haystack.indexOf(build.label) !== -1) {
return button;
return button as BuildButton<string, ButtonModernModel, ButtonModernController>;
}
}

Expand All @@ -511,7 +515,11 @@ export class ReligionManager implements Automation {
const controller = new classes.ui.religion.RefineTearsBtnController(this._host.gamePage);

await new Promise(resolve =>
controller.buyItem(this._host.gamePage.religionTab.refineBtn.model, undefined, resolve)
controller.buyItem(
this._host.gamePage.religionTab.refineBtn.model,
new MouseEvent("click"),
resolve
)
);

this._host.engine.iactivity("act.refineTears", [], "ks-faith");
Expand All @@ -534,7 +542,11 @@ export class ReligionManager implements Automation {
.controller as TransformBtnController;
const model = this._host.gamePage.religionTab.refineTCBtn.model;
await new Promise(resolve =>
controller.buyItem(this._host.gamePage.religionTab.refineTCBtn.model, undefined, resolve)
controller.buyItem(
this._host.gamePage.religionTab.refineTCBtn.model,
new MouseEvent("click"),
resolve
)
);

const cost = mustExist(model.prices?.[0]).val;
Expand Down
20 changes: 16 additions & 4 deletions packages/userscript/source/SpaceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { BulkPurchaseHelper } from "./helper/BulkPurchaseHelper";
import { SpaceBuildingSetting, SpaceSettings } from "./settings/SpaceSettings";
import { TabManager } from "./TabManager";
import { cwarn } from "./tools/Log";
import { BuildButton, SpaceBuildingInfo, SpaceBuildings, SpaceTab } from "./types";
import { mustExist } from "./tools/Maybe";
import {
BuildButton,
ButtonModernController,
ButtonModernModel,
SpaceBuildingInfo,
SpaceBuildings,
SpaceTab,
} from "./types";
import { UserScript } from "./UserScript";
import { WorkshopManager } from "./WorkshopManager";

Expand Down Expand Up @@ -98,7 +106,7 @@ export class SpaceManager implements Automation {
}

const model = this.manager.tab.GCPanel.children[i];
const prices = model.model.prices;
const prices = mustExist(model.model.prices);
for (const resource of prices) {
// If we can't afford this resource price, continue with the next mission.
if (this._workshopManager.getValueAvailable(resource.name, true) < resource.val) {
Expand Down Expand Up @@ -149,12 +157,16 @@ export class SpaceManager implements Automation {
return this._host.gamePage.space.getBuilding(name);
}

getBuildButton(name: string): BuildButton | null {
getBuildButton(
name: string
): BuildButton<string, ButtonModernModel, ButtonModernController> | null {
const panels = this.manager.tab.planetPanels;

for (const panel of panels) {
for (const child of panel.children) {
if (child.id === name) return child;
if (child.id === name) {
return child as BuildButton<string, ButtonModernModel, ButtonModernController>;
}
}
}

Expand Down
54 changes: 43 additions & 11 deletions packages/userscript/source/TimeControlManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import { objectEntries } from "./tools/Entries";
import { isNil, mustExist } from "./tools/Maybe";
import {
BuildButton,
ButtonModernController,
ButtonModernModel,
ChronoForgeUpgradeInfo,
ChronoForgeUpgrades,
ShatterTCBtnController,
TimeItemVariant,
TimeTab,
VoidSpaceUpgradeInfo,
Expand Down Expand Up @@ -81,7 +84,9 @@ export class TimeControlManager {
// buttons and see if the item appears on the checklist.
// If we don't have a given item, but we *could* buy it, then we act
// as if we already had it.
const check = (buttons: Array<BuildButton>) => {
const check = (
buttons: Array<BuildButton<string, ButtonModernModel, ButtonModernController>>
) => {
if (checkList.length !== 0) {
for (const button of buttons) {
if (!button.model.metadata) {
Expand All @@ -91,7 +96,7 @@ export class TimeControlManager {
const index = checkList.indexOf(name);
if (index !== -1) {
checkList.splice(index, 1);
if (this._host.gamePage.resPool.hasRes(button.model.prices)) {
if (this._host.gamePage.resPool.hasRes(mustExist(button.model.prices))) {
return true;
}
}
Expand Down Expand Up @@ -149,7 +154,14 @@ export class TimeControlManager {
checkList.push("unicornPasture");
}
}
if (check(this._bonfireManager.manager.tab.buttons) || checkList.length) {
if (
check(
this._bonfireManager.manager.tab.buttons as Array<
BuildButton<string, ButtonModernModel, ButtonModernController>
>
) ||
checkList.length
) {
return;
}

Expand All @@ -173,12 +185,12 @@ export class TimeControlManager {
const panels = this._spaceManager.manager.tab.planetPanels;
for (const panel of panels) {
for (const panelButton of panel.children) {
const model = panelButton.model;
const model = panelButton.model as ButtonModernModel;
const name = model.metadata.name;
const index = checkList.indexOf(name);
if (index !== -1) {
checkList.splice(index, 1);
if (this._host.gamePage.resPool.hasRes(model.prices)) {
if (this._host.gamePage.resPool.hasRes(mustExist(model.prices))) {
break;
}
}
Expand All @@ -205,9 +217,21 @@ export class TimeControlManager {
}

if (
check(this._religionManager.manager.tab.zgUpgradeButtons) ||
check(this._religionManager.manager.tab.rUpgradeButtons) ||
check(this._religionManager.manager.tab.children[0].children[0].children) ||
check(
this._religionManager.manager.tab.zgUpgradeButtons as Array<
BuildButton<string, ButtonModernModel, ButtonModernController>
>
) ||
check(
this._religionManager.manager.tab.rUpgradeButtons as Array<
BuildButton<string, ButtonModernModel, ButtonModernController>
>
) ||
check(
this._religionManager.manager.tab.children[0].children[0].children as Array<
BuildButton<string, ButtonModernModel, ButtonModernController>
>
) ||
checkList.length
) {
return;
Expand All @@ -229,8 +253,16 @@ export class TimeControlManager {
}

if (
check(this.manager.tab.children[2].children[0].children) ||
check(this.manager.tab.children[3].children[0].children) ||
check(
this.manager.tab.children[2].children[0].children as Array<
BuildButton<string, ButtonModernModel, ButtonModernController>
>
) ||
check(
this.manager.tab.children[3].children[0].children as Array<
BuildButton<string, ButtonModernModel, ButtonModernController>
>
) ||
checkList.length
) {
return;
Expand Down Expand Up @@ -433,7 +465,7 @@ export class TimeControlManager {
if (0 < willSkip) {
const shatter = this._host.gamePage.timeTab.cfPanel.children[0].children[0]; // check?
this._host.engine.iactivity("act.time.skip", [willSkip], "ks-timeSkip");
shatter.controller.doShatterAmt!(shatter.model, willSkip);
(shatter.controller as ShatterTCBtnController).doShatterAmt(shatter.model, willSkip);
this._host.engine.storeForSummary("time.skip", willSkip);
}
}
Expand Down
13 changes: 10 additions & 3 deletions packages/userscript/source/TimeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import { cwarn } from "./tools/Log";
import { mustExist } from "./tools/Maybe";
import {
BuildButton,
ButtonModernController,
ButtonModernModel,
ChronoForgeUpgradeInfo,
ChronoForgeUpgrades,
FixCryochamberBtnController,
TimeItemVariant,
TimeTab,
VoidSpaceUpgradeInfo,
Expand Down Expand Up @@ -135,7 +138,7 @@ export class TimeManager {
getBuildButton(
name: ChronoForgeUpgrades | VoidSpaceUpgrades,
variant: TimeItemVariant
): BuildButton | null {
): BuildButton<string, ButtonModernModel, ButtonModernController> | null {
let buttons: Array<BuildButton>;
if (variant === TimeItemVariant.Chronoforge) {
buttons = this.manager.tab.children[2].children[0].children;
Expand All @@ -151,7 +154,7 @@ export class TimeManager {
for (const button of buttons) {
const haystack = button.model.name;
if (haystack.indexOf(build.label) !== -1) {
return button;
return button as BuildButton<string, ButtonModernModel, ButtonModernController>;
}
}

Expand All @@ -165,7 +168,11 @@ export class TimeManager {
let fixed = 0;
const btn = this.manager.tab.vsPanel.children[0].children[0]; //check?
// doFixCryochamber will check resources
while (btn.controller.doFixCryochamber!(btn.model)) {
while (
(btn.controller as FixCryochamberBtnController).doFixCryochamber(
btn.model as ButtonModernModel
)
) {
++fixed;
}
if (0 < fixed) {
Expand Down
3 changes: 2 additions & 1 deletion packages/userscript/source/UpgradeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export abstract class UpgradeManager {

this._host.gamePage.opts.noConfirm = true;
const success = await UpgradeManager.skipConfirm(
() => new Promise(resolve => controller.buyItem(button.model, undefined, resolve))
() =>
new Promise(resolve => controller.buyItem(button.model, new MouseEvent("click"), resolve))
);

if (!success) {
Expand Down
Loading

0 comments on commit c3f824b

Please sign in to comment.