Prepare scanner branch for merge
This commit is contained in:
@@ -82,6 +82,7 @@ export function parseArtifactCandidate(capture: CaptureResult | null): ParsedArt
|
||||
const parsedLevel = levelField.value ? Number.parseInt(levelField.value, 10) : null;
|
||||
const level = parsedLevel ?? 0;
|
||||
let mainStatField = inferMainStat(slotField.value, mainText);
|
||||
mainStatField = promoteSlotPercentMainStat(slotField.value, mainStatField);
|
||||
let mainValueField = findMainValue(mainText, mainStatField.value, slotField.value, parsedLevel);
|
||||
if (!mainStatField.value && mainValueField.value) {
|
||||
const inferredFromValue = inferMainStatFromValue(slotField.value, mainValueField.value, mainText, parsedLevel);
|
||||
@@ -227,6 +228,8 @@ function parseSetName(setText: string, artifactName: ParsedField): ParsedField {
|
||||
const setFromText = fuzzyFindKnown(`${directLine ?? ""}\n${setText}`, knownSets, 0.64);
|
||||
if (setFromText && (!setFromPiece || setFromText.score >= 0.78)) return field(setFromText.value, Math.round(setFromText.score * 100), setFromText.score >= 0.95 ? "ocr" : "fallback");
|
||||
if (setFromPiece) return field(setFromPiece, derivedConfidence(artifactName, 92), "derived");
|
||||
const partialSetFromPiece = deriveSetFromPartialPieceName(artifactName.value);
|
||||
if (partialSetFromPiece) return field(partialSetFromPiece, 72, "derived");
|
||||
return setFromText ? field(setFromText.value, Math.round(setFromText.score * 100), "fallback") : field("", 0, "missing");
|
||||
}
|
||||
|
||||
@@ -275,6 +278,22 @@ function firstUsefulLine(text: string, rejectIncludes: string[]) {
|
||||
.find((line) => line.length > 5 && !rejectIncludes.some((reject) => simplifyForMatch(line).includes(simplifyForMatch(reject)))) ?? "";
|
||||
}
|
||||
|
||||
function deriveSetFromPartialPieceName(text: string) {
|
||||
const words = cleanupOcrLabel(text)
|
||||
.split(/\s+/)
|
||||
.map((word) => simplifyForMatch(word))
|
||||
.filter((word) => word.length >= 5);
|
||||
if (words.length < 2) return "";
|
||||
|
||||
const candidates = knownPieceNames.filter((piece) => {
|
||||
const normalizedPiece = simplifyForMatch(piece);
|
||||
const hits = words.filter((word) => normalizedPiece.includes(word)).length;
|
||||
return hits >= 2;
|
||||
});
|
||||
const sets = [...new Set(candidates.map((piece) => pieceToSet.get(piece)).filter((set): set is string => Boolean(set)))];
|
||||
return sets.length === 1 ? sets[0] : "";
|
||||
}
|
||||
|
||||
function findMainValue(text: string, mainStat: string, slot: string, level: number | null): ParsedField {
|
||||
const cleaned = text.replace(/\b20\b/g, " ").replace(/[Oo]/g, "0");
|
||||
const percentValue = extractPercentValue(cleaned);
|
||||
@@ -504,7 +523,7 @@ function parseEquippedCharacter(text: string): ParsedField {
|
||||
const wholeTextMatch = fallbackSearch ? fuzzyFindKnown(fallbackSearch, knownCharacters, 0.88) : null;
|
||||
if (wholeTextMatch) return field(wholeTextMatch.value, Math.round(wholeTextMatch.score * 100), "fallback");
|
||||
|
||||
return afterLabel ? field(afterLabel, 50, "fallback") : field("Not detected", 45, "missing");
|
||||
return field("Not detected", 45, "missing");
|
||||
}
|
||||
|
||||
function field(value: string, confidence: number, source: ParsedField["source"]): ParsedField {
|
||||
@@ -520,6 +539,20 @@ function promotePercentVariant(stat: string, text: string) {
|
||||
return stat;
|
||||
}
|
||||
|
||||
function promoteSlotPercentMainStat(slot: string, mainStat: ParsedField): ParsedField {
|
||||
if (!["ATK", "HP", "DEF"].includes(mainStat.value)) return mainStat;
|
||||
const references = getSlotMainStatValueReferences(slot);
|
||||
const hasFlat = references.some((candidate) => candidate.stat === mainStat.value);
|
||||
const hasPercent = references.some((candidate) => candidate.stat === `${mainStat.value}%`);
|
||||
if (hasFlat || !hasPercent) return mainStat;
|
||||
return {
|
||||
...mainStat,
|
||||
value: `${mainStat.value}%`,
|
||||
confidence: Math.max(mainStat.confidence, 90),
|
||||
source: "derived",
|
||||
};
|
||||
}
|
||||
|
||||
function getSlotMainStatValueReferences(slot: string): MainStatValueReference[] {
|
||||
const valueReferences = mainStatValueReferences[slot];
|
||||
return Array.isArray(valueReferences) ? valueReferences as MainStatValueReference[] : [];
|
||||
@@ -607,6 +640,7 @@ function cleanupOcrLabel(line: string) {
|
||||
function cleanupCharacterNoise(text: string) {
|
||||
return text
|
||||
.replace(/^.*?equipped\s*:?\s*/i, "")
|
||||
.replace(/^(?:by|to)\s+/i, "")
|
||||
.replace(/[^A-Za-z'\-\s]/g, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
|
||||
Reference in New Issue
Block a user