leonitousconforti/tinyburg

View on GitHub
packages/doorman/src/upgrades/unlock-roof.ts

Summary

Maintainability
A
0 mins
Test Coverage
import type { IUpgrade } from "./base-upgrade.js";
import type { Roof } from "@tinyburg/nucleus/data/roofs";
import type { Image } from "../image-operations/image.js";
import type { PromiseClient } from "@connectrpc/connect";
import type { EmulatorController } from "@tinyburg/architect/protobuf/emulator_controller_connect";

import Debug from "debug";
// import { roofs } from "@tinyburg/nucleus/data/roofs";
import { getScreenshot } from "../grpc/get-screenshots.js";
import { cropImage } from "../image-operations/crop-image.js";
import { NeedsVersion } from "../decorators/needs-version.js";
import { negateImage } from "../image-operations/negate-image.js";
import { upscaleImage } from "../image-operations/upscale-image.js";
import { EnterLog, ExitLog } from "../decorators/invocation-logs.js";
import { matchTemplate } from "../image-operations/template-matching.js";
import { loadTemplateByName } from "../image-operations/load-template.js";
import { calculateResourceScale } from "../utils/calculate-resource-scale.js";
import { alphabeticalImagesDictionary, prepDictionaryToLibrary, detectSequence } from "../image-operations/ocr.js";

const mv_right: Image = await loadTemplateByName("mv_right");
const debug: Debug.Debugger = Debug("doorman:upgrades:unlock-roof");

@NeedsVersion("3.14.6")
export class UnlockRoof implements IUpgrade {
    private readonly _roofToBuy: Roof["name"];
    public readonly logger: Debug.Debugger = debug;

    public constructor(roofToBuy: Roof["name"]) {
        this._roofToBuy = roofToBuy;
    }

    @EnterLog(debug)
    @ExitLog(debug, { withReturnValue: true })
    public canAfford(): boolean {
        // return roofs.find(({ name }) => name === this._roofToBuy)!.buxcost < 10;
        return false;
    }

    @EnterLog(debug)
    @ExitLog(debug)
    public async doUpgrade(client: PromiseClient<typeof EmulatorController>): Promise<void> {
        // Open the hud and navigate to the roofs upgrades menu
        // await openHud(client);
        // await openUpgradesMenu(client);
        // await changeToRoofsMenu(client);

        // Grab an initial screenshot to calculate the resource scale and find the buttons
        const initialScreenshot = await getScreenshot(client);
        const resourceScale = calculateResourceScale(initialScreenshot.width, initialScreenshot.height);

        // Prep the detection library for ocr
        const alphabeticalDetectionLibrary = prepDictionaryToLibrary(
            alphabeticalImagesDictionary,
            resourceScale,
            (image: Image) => negateImage(image)
        );

        // Find the move right button
        const mv_rightUpscaled = upscaleImage(mv_right, resourceScale);
        const screenshotCroppedForMoveButton = cropImage(initialScreenshot, { top: 0, left: 0, width: 0, height: 0 });
        const moveRightButton = matchTemplate(screenshotCroppedForMoveButton, mv_rightUpscaled)[0];
        if (!moveRightButton) throw new Error("Could not find the move right button");

        // Now cycle until we find the roof we want to unlock
        // eslint-disable-next-line no-constant-condition
        while (true) {
            // Go to next roof, grab a screenshot of it, crop it, and then find its name
            // await click(client, { x: moveRightButton.position.x, y: moveRightButton.position.y, timeout: 1000 });
            const roofScreenshot = await getScreenshot(client);
            const roofScreenshotCroppedForName = cropImage(roofScreenshot, { top: 0, left: 0, width: 0, height: 0 });
            const roofSequence = detectSequence(roofScreenshotCroppedForName, alphabeticalDetectionLibrary);

            // If we went through every roof and ended back at the beginning then leave
            if (roofSequence.sequence === "Lobby") {
                break;
            }

            // If this is the roof we want to buy
            if (roofSequence.sequence === this._roofToBuy.toUpperCase()) {
                break;
            }
        }

        // Close the roofs upgrades menu and then then hud
        // await closeRoofsMenu(client);
        // await closeUpgradesMenu(client);
        // await closeHud(client);
    }
}