90 lines
4.4 KiB
TypeScript
90 lines
4.4 KiB
TypeScript
import type { CaptureResult, KeyPressResult } from "../types/global";
|
|
import { validateLookupPackage, type LookupValidationStatus } from "./genshinLookup";
|
|
|
|
export type ScanEntryMode = "visible-inventory" | "direct-inventory" | "paimon-menu" | "auto-entry";
|
|
|
|
export interface AutoScanEntryAction {
|
|
type: "key" | "click-artifact-tab" | "click-first-artifact" | "capture-preflight";
|
|
key?: "ESC" | "B";
|
|
label: string;
|
|
}
|
|
|
|
export interface AutoScanEntryPreflight {
|
|
ok: boolean;
|
|
reason: string;
|
|
}
|
|
|
|
export function buildAutoScanEntryPlan(mode: ScanEntryMode): AutoScanEntryAction[] {
|
|
if (mode === "visible-inventory") {
|
|
return [{ type: "capture-preflight", label: "Capture visible artifact inventory" }];
|
|
}
|
|
if (mode === "direct-inventory") {
|
|
return [
|
|
{ type: "key", key: "B", label: "Open inventory from the current world state" },
|
|
{ type: "click-artifact-tab", label: "Select artifact inventory tab" },
|
|
{ type: "click-first-artifact", label: "Select first visible artifact so the detail card is open" },
|
|
{ type: "capture-preflight", label: "Verify artifact inventory grid and detail card" },
|
|
];
|
|
}
|
|
if (mode === "auto-entry") {
|
|
return [
|
|
{ type: "key", key: "B", label: "Try direct inventory entry from world" },
|
|
{ type: "click-artifact-tab", label: "Select artifact inventory tab if inventory opened" },
|
|
{ type: "click-first-artifact", label: "Select first visible artifact so the detail card is open" },
|
|
{ type: "key", key: "ESC", label: "Fallback: Inventory Kamera step from already-open Paimon menu" },
|
|
{ type: "key", key: "ESC", label: "Fallback: close Paimon menu if ESC opened or left it visible" },
|
|
{ type: "key", key: "B", label: "Fallback: open inventory from world" },
|
|
{ type: "click-artifact-tab", label: "Fallback: select artifact inventory tab" },
|
|
{ type: "click-first-artifact", label: "Fallback: select first visible artifact" },
|
|
{ type: "capture-preflight", label: "Verify artifact inventory grid and detail card" },
|
|
];
|
|
}
|
|
return [
|
|
{ type: "key", key: "ESC", label: "Inventory Kamera step: leave the already-open Paimon menu" },
|
|
{ type: "key", key: "ESC", label: "If Paimon is still visible, close it before opening inventory" },
|
|
{ type: "key", key: "B", label: "Inventory Kamera step: open inventory from world" },
|
|
{ type: "click-artifact-tab", label: "Inventory Kamera step: select artifact inventory tab" },
|
|
{ type: "click-first-artifact", label: "Select first visible artifact so the detail card is open" },
|
|
{ type: "capture-preflight", label: "Verify artifact inventory grid and detail card" },
|
|
];
|
|
}
|
|
|
|
export function artifactTabClickTarget(capture: CaptureResult): { x: number; y: number } {
|
|
return {
|
|
x: Math.round(capture.width * (448 / 1280)),
|
|
y: Math.round(capture.height * (31 / 720)),
|
|
};
|
|
}
|
|
|
|
export function keyPressBlocked(result: KeyPressResult | null | undefined) {
|
|
return !result?.ok || Boolean(result.inputBlocked);
|
|
}
|
|
|
|
export function validateAutoScanEntryPreflight(
|
|
capture: CaptureResult | null,
|
|
lookupStatus: LookupValidationStatus = validateLookupPackage(),
|
|
): AutoScanEntryPreflight {
|
|
if (!lookupStatus.valid) {
|
|
return {
|
|
ok: false,
|
|
reason: `Lookup invalid: ${lookupStatus.errors[0] ?? "unknown lookup error"}`,
|
|
};
|
|
}
|
|
if (!capture) return { ok: false, reason: "Keine Capture-Daten fuer den Auto-Scan-Start." };
|
|
if (capture.captureTarget === "primary-screen") {
|
|
return { ok: false, reason: "Auto-Scan blockiert: Capture stammt vom Primary Screen statt vom Genshin-Client." };
|
|
}
|
|
if (capture.layout?.warning) return { ok: false, reason: capture.layout.warning };
|
|
if (capture.paimonMenu?.present) {
|
|
return { ok: false, reason: `Paimon-Menue erkannt (${capture.paimonMenu.confidence}%). Auto-Scan startet erst im Artifact-Inventar mit sichtbarer Detailkarte.` };
|
|
}
|
|
if (!capture.inventoryGrid || capture.inventoryGrid.source === "missing" || capture.inventoryGrid.centers.length === 0) {
|
|
return { ok: false, reason: "Kein verlaessliches Artifact-Grid erkannt. Artifact-Inventar sichtbar lassen." };
|
|
}
|
|
if (!capture.artifactDetail?.present) {
|
|
const confidence = capture.artifactDetail ? ` (${capture.artifactDetail.confidence}% Detail-Marker)` : "";
|
|
return { ok: false, reason: `Keine Artifact-Detailansicht erkannt${confidence}. Artifact-Inventar mit sichtbarer Detailkarte oeffnen.` };
|
|
}
|
|
return { ok: true, reason: "" };
|
|
}
|