mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-25 04:59:52 +08:00
- 添加调试日志输出ocrPhysical数据 - 移除ocrPhysical.ok验证条件以提高兼容性 - 使用可选链操作符安全访问remainder属性 - 更新版本号从4.5到4.5.1 - 调整添加按钮识别区域坐标和尺寸参数
602 lines
21 KiB
JavaScript
602 lines
21 KiB
JavaScript
/**
|
||
* OCR树脂数量统计脚本
|
||
* 功能:自动识别并统计原神中各种树脂的数量
|
||
* 支持:原粹树脂、浓缩树脂、须臾树脂、脆弱树脂
|
||
*/
|
||
|
||
// ==================== 常量定义 ====================
|
||
|
||
// 树脂图标识别对象
|
||
const RESIN_ICONS = {
|
||
ORIGINAL: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/original_resin.png")),
|
||
CONDENSED: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/condensed_resin.png")),
|
||
FRAGILE: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/fragile_resin.png")),
|
||
TRANSIENT: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/transient_resin.png")),
|
||
REPLENISH_BUTTON: RecognitionObject.TemplateMatch(file.ReadImageMatSync("assets/icon/replenish_resin_button.png"))
|
||
};
|
||
|
||
// 普通数字识别对象(1-4)
|
||
const NUMBER_ICONS = [
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num1.png")), value: 1},
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num2.png")), value: 2},
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num3.png")), value: 3},
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num4.png")), value: 4}
|
||
];
|
||
|
||
// 白色数字识别对象(0-5,用于浓缩树脂)
|
||
const WHITE_NUMBER_ICONS = [
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num0_white.png")), value: 0},
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num1_white.png")), value: 1},
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num2_white.png")), value: 2},
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num3_white.png")), value: 3},
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num4_white.png")), value: 4},
|
||
{ro: RecognitionObject.TemplateMatch(file.ReadImageMatSync("RecognitionObject/num5_white.png")), value: 5}
|
||
];
|
||
|
||
// 配置常量
|
||
const CONFIG = {
|
||
RECOGNITION_TIMEOUT: 2000, // 图像识别超时时间(毫秒)
|
||
SLEEP_INTERVAL: 500, // 循环间隔时间(毫秒)
|
||
UI_DELAY: 1500, // UI操作延迟时间(毫秒)
|
||
MAP_ZOOM_LEVEL: 6, // 地图缩放级别
|
||
|
||
// 点击坐标
|
||
COORDINATES: {
|
||
MAP_SWITCH: {x: 1840, y: 1020}, // 地图右下角切换按钮
|
||
MONDSTADT: {x: 1420, y: 180}, // 蒙德选择按钮
|
||
AVOID_SELECTION: {x: 1090, y: 450} // 避免选中效果的点击位置
|
||
},
|
||
|
||
// OCR识别区域配置
|
||
OCR_REGIONS: {
|
||
ORIGINAL_RESIN: {width: 200, height: 40},
|
||
CONDENSED_RESIN: {width: 90, height: 40},
|
||
OTHER_RESIN: {width: 0, height: 60} // width会根据图标宽度动态设置
|
||
}
|
||
};
|
||
|
||
// 树脂数量存储
|
||
let resinCounts = {
|
||
original: 0, // 原粹树脂数量
|
||
condensed: 0, // 浓缩树脂数量
|
||
transient: 0, // 须臾树脂数量
|
||
fragile: 0 // 脆弱树脂数量
|
||
};
|
||
|
||
// ==================== 工具函数 ====================
|
||
|
||
/**
|
||
* 通用图像识别函数
|
||
* @param {Object} recognitionObject - 识别对象
|
||
* @param {number} timeout - 超时时间(毫秒)
|
||
* @returns {Object|null} 识别结果或null
|
||
*/
|
||
async function recognizeImage(recognitionObject, timeout = CONFIG.RECOGNITION_TIMEOUT) {
|
||
const startTime = Date.now();
|
||
|
||
while (Date.now() - startTime < timeout) {
|
||
try {
|
||
// 直接链式调用,不保存gameRegion变量,避免内存管理问题
|
||
const imageResult = captureGameRegion().find(recognitionObject);
|
||
if (imageResult.isExist()) {
|
||
return imageResult;
|
||
}
|
||
} catch (error) {
|
||
log.error(`识别图像时发生异常: ${error.message}`);
|
||
}
|
||
await sleep(CONFIG.SLEEP_INTERVAL);
|
||
}
|
||
|
||
log.warn(`经过多次尝试,仍然无法识别图像`);
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 在指定区域内识别数字图片
|
||
* @param {Object} ocrRegion - OCR识别区域
|
||
* @param {Array} numberIcons - 数字图标数组
|
||
* @param {string} logPrefix - 日志前缀
|
||
* @returns {number|null} 识别到的数字或null
|
||
*/
|
||
async function recognizeNumberInRegion(ocrRegion, numberIcons, logPrefix = "") {
|
||
try {
|
||
for (const numObj of numberIcons) {
|
||
try {
|
||
// 直接链式调用,避免内存管理问题
|
||
const numResult = captureGameRegion().find(numObj.ro);
|
||
if (numResult && isPointInRegion(numResult, ocrRegion)) {
|
||
log.info(`${logPrefix}通过图片识别到数字: ${numObj.value}`);
|
||
return numObj.value;
|
||
}
|
||
} catch (error) {
|
||
log.error(`${logPrefix}识别数字图片时发生异常: ${error.message}`);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
log.error(`${logPrefix}识别数字区域时发生异常: ${error.message}`);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 普通数字图片识别函数
|
||
* @param {Object} ocrRegion - OCR识别区域
|
||
* @returns {number|null} 识别到的数字或null
|
||
*/
|
||
async function recognizeNumberByImage(ocrRegion) {
|
||
return await recognizeNumberInRegion(ocrRegion, NUMBER_ICONS, "普通数字 - ");
|
||
}
|
||
|
||
/**
|
||
* 白色数字图片识别函数(用于浓缩树脂)
|
||
* @param {Object} ocrRegion - OCR识别区域
|
||
* @returns {number|null} 识别到的数字或null
|
||
*/
|
||
async function recognizeWhiteNumberByImage(ocrRegion) {
|
||
return await recognizeNumberInRegion(ocrRegion, WHITE_NUMBER_ICONS, "白色数字 - ");
|
||
}
|
||
|
||
/**
|
||
* 检查点是否在指定区域内
|
||
* @param {Object} point - 点坐标 {x, y}
|
||
* @param {Object} region - 区域 {x, y, width, height}
|
||
* @returns {boolean} 是否在区域内
|
||
*/
|
||
function isPointInRegion(point, region) {
|
||
return point.x >= region.x &&
|
||
point.x <= region.x + region.width &&
|
||
point.y >= region.y &&
|
||
point.y <= region.y + region.height;
|
||
}
|
||
|
||
/**
|
||
* 通过OCR识别数字
|
||
* @param {Object} ocrRegion - OCR识别区域
|
||
* @param {RegExp} pattern - 匹配模式
|
||
* @returns {number|null} 识别到的数字或null
|
||
*/
|
||
async function recognizeNumberByOCR(ocrRegion, pattern) {
|
||
let resList = null;
|
||
let captureRegion = null;
|
||
try {
|
||
const ocrRo = RecognitionObject.ocr(ocrRegion.x, ocrRegion.y, ocrRegion.width, ocrRegion.height);
|
||
captureRegion = captureGameRegion();
|
||
resList = captureRegion.findMulti(ocrRo);
|
||
|
||
if (!resList || resList.length === 0) {
|
||
log.warn("OCR未识别到任何文本");
|
||
return null;
|
||
}
|
||
|
||
for (const res of resList) {
|
||
if (!res || !res.text) {
|
||
continue;
|
||
}
|
||
|
||
const numberMatch = res.text.match(pattern);
|
||
if (numberMatch) {
|
||
const number = parseInt(numberMatch[1] || numberMatch[0]);
|
||
if (!isNaN(number)) {
|
||
return number;
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
} catch (error) {
|
||
log.error(`OCR识别时发生异常: ${error.message}`);
|
||
return null;
|
||
} finally {
|
||
if (resList && typeof resList.dispose === 'function') {
|
||
resList.dispose();
|
||
}
|
||
if (captureRegion && typeof captureRegion.dispose === 'function') {
|
||
captureRegion.dispose();
|
||
}
|
||
}
|
||
}
|
||
|
||
// ==================== 树脂计数函数 ====================
|
||
|
||
/**
|
||
* 统计原粹树脂数量
|
||
* @returns {number} 原粹树脂数量
|
||
*/
|
||
/**
|
||
* 统计原粹树脂数量
|
||
* @returns {number} 原粹树脂数量
|
||
*/
|
||
async function countOriginalResin(tryOriginalMode, opToMainUi, openMap) {
|
||
if (tryOriginalMode) {
|
||
log.info("尝试使用原始模式");
|
||
return await countOriginalResinBackup()
|
||
} else {
|
||
log.info('尝试使用优化模式');
|
||
let ocrPhysical = await physical.ocrPhysical(opToMainUi, openMap);
|
||
log.debug(`ocrPhysical: {0}`,JSON.stringify(ocrPhysical))
|
||
await sleep(600)
|
||
// ocrPhysical = false//模拟异常
|
||
if (ocrPhysical/* && ocrPhysical.ok*/) {
|
||
return ocrPhysical?.remainder;
|
||
} else {
|
||
//异常 退出至地图 尝试使用原始模式
|
||
await keyPress("VK_ESCAPE")
|
||
log.error(`ocrPhysical error`);
|
||
throw new Error("ocrPhysical error");
|
||
}
|
||
}
|
||
}
|
||
|
||
async function countOriginalResinBackup() {
|
||
const originalResin = await recognizeImage(RESIN_ICONS.ORIGINAL);
|
||
if (!originalResin) {
|
||
log.warn(`未找到原粹树脂图标`);
|
||
return 0;
|
||
}
|
||
|
||
const ocrRegion = {
|
||
x: originalResin.x,
|
||
y: originalResin.y,
|
||
width: CONFIG.OCR_REGIONS.ORIGINAL_RESIN.width,
|
||
height: CONFIG.OCR_REGIONS.ORIGINAL_RESIN.height
|
||
};
|
||
|
||
// 匹配 xxx/200 格式中的第一个数字(1-3位)
|
||
const count = await recognizeNumberByOCR(ocrRegion, /(\d{1,3})\/\d+/);
|
||
if (count !== null) {
|
||
log.info(`原粹树脂数量: ${count}`);
|
||
return count;
|
||
}
|
||
|
||
log.warn(`未能识别原粹树脂数量`);
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* 统计浓缩树脂数量
|
||
* @returns {number} 浓缩树脂数量
|
||
*/
|
||
async function countCondensedResin() {
|
||
const condensedResin = await recognizeImage(RESIN_ICONS.CONDENSED);
|
||
if (!condensedResin) {
|
||
log.warn(`未找到浓缩树脂图标`);
|
||
return 0;
|
||
}
|
||
|
||
const ocrRegion = {
|
||
x: condensedResin.x,
|
||
y: condensedResin.y,
|
||
width: CONFIG.OCR_REGIONS.CONDENSED_RESIN.width,
|
||
height: CONFIG.OCR_REGIONS.CONDENSED_RESIN.height
|
||
};
|
||
|
||
// 首先尝试OCR识别
|
||
const ocrCount = await recognizeNumberByOCR(ocrRegion, /\d+/);
|
||
if (ocrCount !== null) {
|
||
log.info(`浓缩树脂数量: ${ocrCount}`);
|
||
return ocrCount;
|
||
}
|
||
|
||
// OCR识别失败,尝试白色数字图片识别
|
||
log.info(`OCR识别浓缩树脂失败,尝试白色数字图片识别`);
|
||
const imageCount = await recognizeWhiteNumberByImage(ocrRegion);
|
||
if (imageCount !== null) {
|
||
log.info(`浓缩树脂数量(白色数字图片识别): ${imageCount}`);
|
||
return imageCount;
|
||
}
|
||
|
||
log.info(`白色数字图片识别识别浓缩树脂失败,尝试在说明界面获取`);
|
||
// 点击浓缩树脂打开说明界面统计
|
||
condensedResin.click();
|
||
await sleep(CONFIG.UI_DELAY);
|
||
let captureRegion = captureGameRegion();
|
||
let textList = null;
|
||
try {
|
||
// OCR识别整个界面的文本
|
||
let ocrRo = RecognitionObject.Ocr(0, 0, captureRegion.width, captureRegion.height);
|
||
textList = captureRegion.findMulti(ocrRo);
|
||
|
||
for (const res of textList) {
|
||
if (res.text.includes("当前拥有")) {
|
||
const match = res.text.match(/当前拥有\s*([0-5ss])/);
|
||
if (match && match[1]) {
|
||
const count = parseInt(match[1]);
|
||
log.info(`浓缩树脂数量(说明界面): ${count}`);
|
||
keyPress("ESCAPE");
|
||
await sleep(CONFIG.UI_DELAY);
|
||
return count;
|
||
}
|
||
}
|
||
}
|
||
} finally {
|
||
if (textList && typeof textList.dispose === 'function') {
|
||
textList.dispose();
|
||
}
|
||
captureRegion.dispose();
|
||
}
|
||
|
||
log.warn(`未能识别浓缩树脂数量`);
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* 统计须臾树脂数量
|
||
* @returns {number} 须臾树脂数量
|
||
*/
|
||
async function countTransientResin() {
|
||
const transientResin = await recognizeImage(RESIN_ICONS.TRANSIENT);
|
||
if (!transientResin) {
|
||
log.warn(`未找到须臾树脂图标`);
|
||
return 0;
|
||
}
|
||
|
||
const ocrRegion = {
|
||
x: transientResin.x,
|
||
y: transientResin.y + transientResin.height,
|
||
width: transientResin.width,
|
||
height: CONFIG.OCR_REGIONS.OTHER_RESIN.height
|
||
};
|
||
|
||
return await countResinWithFallback(ocrRegion, "须臾树脂", recognizeNumberByImage);
|
||
}
|
||
|
||
/**
|
||
* 统计脆弱树脂数量
|
||
* @returns {number} 脆弱树脂数量
|
||
*/
|
||
async function countFragileResin() {
|
||
const fragileResin = await recognizeImage(RESIN_ICONS.FRAGILE);
|
||
if (!fragileResin) {
|
||
log.warn(`未找到脆弱树脂图标`);
|
||
return 0;
|
||
}
|
||
|
||
const ocrRegion = {
|
||
x: fragileResin.x,
|
||
y: fragileResin.y + fragileResin.height,
|
||
width: fragileResin.width,
|
||
height: CONFIG.OCR_REGIONS.OTHER_RESIN.height
|
||
};
|
||
|
||
return await countResinWithFallback(ocrRegion, "脆弱树脂", recognizeNumberByImage);
|
||
}
|
||
|
||
/**
|
||
* 通用树脂计数函数(带图片识别回退)
|
||
* @param {Object} ocrRegion - OCR识别区域
|
||
* @param {string} resinType - 树脂类型名称
|
||
* @param {Function} fallbackFunction - 回退识别函数
|
||
* @returns {number} 树脂数量
|
||
*/
|
||
async function countResinWithFallback(ocrRegion, resinType, fallbackFunction) {
|
||
// 首先尝试OCR识别
|
||
const ocrCount = await recognizeNumberByOCR(ocrRegion, /\d+/);
|
||
if (ocrCount !== null) {
|
||
log.info(`${resinType}数量: ${ocrCount}`);
|
||
return ocrCount;
|
||
}
|
||
|
||
// OCR识别失败,尝试图片识别
|
||
log.info(`OCR识别${resinType}失败,尝试图片识别`);
|
||
const imageCount = await fallbackFunction(ocrRegion);
|
||
if (imageCount !== null) {
|
||
log.info(`${resinType}数量(图片识别): ${imageCount}`);
|
||
return imageCount;
|
||
}
|
||
|
||
log.warn(`未能识别${resinType}数量`);
|
||
return 0;
|
||
}
|
||
|
||
// ==================== UI操作函数 ====================
|
||
|
||
/**
|
||
* 打开并设置地图界面
|
||
*/
|
||
async function openMap() {
|
||
log.info("打开地图界面");
|
||
keyPress("M");
|
||
await sleep(CONFIG.UI_DELAY);
|
||
|
||
// 切换到国家选择界面
|
||
// click(CONFIG.COORDINATES.MAP_SWITCH.x, CONFIG.COORDINATES.MAP_SWITCH.y);
|
||
// await sleep(CONFIG.UI_DELAY);
|
||
|
||
// 选择蒙德
|
||
// click(CONFIG.COORDINATES.MONDSTADT.x, CONFIG.COORDINATES.MONDSTADT.y);
|
||
// await sleep(CONFIG.UI_DELAY);
|
||
// await switchtoCountrySelection(CONFIG.COORDINATES.MONDSTADT.x, CONFIG.COORDINATES.MONDSTADT.y)
|
||
|
||
// 设置地图缩放级别,排除识别干扰
|
||
await genshin.setBigMapZoomLevel(CONFIG.MAP_ZOOM_LEVEL);
|
||
log.info("地图界面设置完成");
|
||
}
|
||
|
||
/**
|
||
* 切换到国家选择界面的异步函数
|
||
* 通过点击指定坐标并等待界面加载来完成切换操作
|
||
*/
|
||
async function switchtoCountrySelection(x, y) {
|
||
// 切换到国家选择界面
|
||
click(CONFIG.COORDINATES.MAP_SWITCH.x, CONFIG.COORDINATES.MAP_SWITCH.y);
|
||
await sleep(CONFIG.UI_DELAY);
|
||
click(x, y);
|
||
await sleep(CONFIG.UI_DELAY);
|
||
}
|
||
|
||
/**
|
||
* 打开补充树脂界面
|
||
*/
|
||
async function openReplenishResinUi() {
|
||
log.info("尝试打开补充树脂界面");
|
||
const replenishResinButton = await recognizeImage(RESIN_ICONS.REPLENISH_BUTTON);
|
||
if (replenishResinButton) {
|
||
replenishResinButton.Click();
|
||
log.info("成功打开补充树脂界面");
|
||
} else {
|
||
log.warn("未找到补充树脂按钮");
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 显示统计结果并发送通知
|
||
* @param {Object} results - 统计结果对象
|
||
*/
|
||
function displayResults(results) {
|
||
const resultText = `原粹:${results.original} 浓缩:${results.condensed} 须臾:${results.transient} 脆弱:${results.fragile}`;
|
||
|
||
log.info(`============ 树脂统计结果 ============`);
|
||
log.info(`原粹树脂数量: ${results.original}`);
|
||
log.info(`浓缩树脂数量: ${results.condensed}`);
|
||
log.info(`须臾树脂数量: ${results.transient}`);
|
||
log.info(`脆弱树脂数量: ${results.fragile}`);
|
||
log.info(`====================================`);
|
||
}
|
||
|
||
// ==================== 主要功能函数 ====================
|
||
|
||
/**
|
||
* 统计所有树脂数量的主函数
|
||
* @returns {Object} 包含所有树脂数量的对象
|
||
*/
|
||
this.countAllResin = async function () {
|
||
try {
|
||
setGameMetrics(1920, 1080, 1);
|
||
log.info("开始统计树脂数量");
|
||
|
||
await genshin.returnMainUi();
|
||
await sleep(CONFIG.UI_DELAY);
|
||
|
||
// 打开地图界面统计原粹/浓缩树脂
|
||
await openMap();
|
||
await sleep(CONFIG.UI_DELAY);
|
||
let tryPass = true;
|
||
try {
|
||
log.info("[开始]统计补充树脂界面中的树脂");
|
||
resinCounts.original = await countOriginalResin(false, false);
|
||
moveMouseTo(CONFIG.COORDINATES.AVOID_SELECTION.x, CONFIG.COORDINATES.AVOID_SELECTION.y)
|
||
await sleep(500);
|
||
resinCounts.transient = await countTransientResin();
|
||
resinCounts.fragile = await countFragileResin();
|
||
log.info("[完成]统计补充树脂界面中的树脂");
|
||
// 点击避免选中效果影响统计
|
||
click(CONFIG.COORDINATES.AVOID_SELECTION.x, CONFIG.COORDINATES.AVOID_SELECTION.y);
|
||
} catch (e) {
|
||
tryPass = false
|
||
}
|
||
await sleep(CONFIG.UI_DELAY);
|
||
log.info("开始统计地图界面中的树脂");
|
||
if (!tryPass) {
|
||
// 如果第一次尝试失败,则切换到蒙德
|
||
await switchtoCountrySelection(CONFIG.COORDINATES.MONDSTADT.x, CONFIG.COORDINATES.MONDSTADT.y)
|
||
resinCounts.original = await countOriginalResin(!tryPass);
|
||
}
|
||
resinCounts.condensed = await countCondensedResin();
|
||
if (!tryPass) {
|
||
// 打开补充树脂界面统计须臾/脆弱树脂
|
||
await openReplenishResinUi();
|
||
await sleep(CONFIG.UI_DELAY);
|
||
|
||
// 点击避免选中效果影响统计
|
||
click(CONFIG.COORDINATES.AVOID_SELECTION.x, CONFIG.COORDINATES.AVOID_SELECTION.y);
|
||
await sleep(500);
|
||
|
||
log.info("开始统计补充树脂界面中的树脂");
|
||
resinCounts.transient = await countTransientResin();
|
||
resinCounts.fragile = await countFragileResin();
|
||
}
|
||
// 显示结果
|
||
displayResults(resinCounts);
|
||
|
||
// 返回主界面
|
||
await genshin.returnMainUi();
|
||
await sleep(CONFIG.UI_DELAY);
|
||
|
||
log.info("树脂统计完成");
|
||
return {
|
||
originalResinCount: resinCounts.original,
|
||
condensedResinCount: resinCounts.condensed,
|
||
transientResinCount: resinCounts.transient,
|
||
fragileResinCount: resinCounts.fragile
|
||
};
|
||
|
||
} catch (error) {
|
||
log.error(`统计树脂数量时发生异常: ${error.message}`);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @returns {Object} 包含可刷取次数的对象
|
||
* {
|
||
* count: number,
|
||
* originalResinTimes: number,
|
||
* condensedResinTimes: number,
|
||
* transientResinTimes: number,
|
||
* fragileResinTimes: number
|
||
* }
|
||
*/
|
||
this.calCountByResin = async function () {
|
||
try {
|
||
let countResult = await this.countAllResin();
|
||
let count = 0;
|
||
// 计算可刷取次数
|
||
// 1. 原粹树脂:优先消耗40/次,不满40消耗20/次,不满20不消耗
|
||
let originalResinTimes = 0;
|
||
let remainingOriginalResin = countResult.originalResinCount;
|
||
|
||
// 先计算40树脂的次数
|
||
if (remainingOriginalResin >= 40) {
|
||
const times40 = Math.floor(remainingOriginalResin / 40);
|
||
originalResinTimes += times40;
|
||
remainingOriginalResin = remainingOriginalResin - (times40 * 40);
|
||
}
|
||
|
||
// 再计算20树脂的次数
|
||
if (remainingOriginalResin >= 20) {
|
||
const times20 = Math.floor(remainingOriginalResin / 20);
|
||
originalResinTimes += times20;
|
||
remainingOriginalResin = remainingOriginalResin - (times20 * 20);
|
||
}
|
||
|
||
log.info(`原粹树脂可刷取次数: ${originalResinTimes}`);
|
||
|
||
// 2. 浓缩树脂:每个计算为1次
|
||
let condensedResinTimes = countResult.condensedResinCount;
|
||
log.info(`浓缩树脂可刷取次数: ${condensedResinTimes}`);
|
||
|
||
// 3. 须臾树脂:检查设置是否开启
|
||
let transientResinTimes = 0;
|
||
if (settings.useTransientResin) {
|
||
transientResinTimes = countResult.transientResinCount;
|
||
log.info(`须臾树脂可刷取次数: ${transientResinTimes}`);
|
||
} else {
|
||
log.info(`须臾树脂未开启使用,跳过计算`);
|
||
}
|
||
|
||
// 4. 脆弱树脂:检查设置是否开启
|
||
let fragileResinTimes = 0;
|
||
if (settings.useFragileResin) {
|
||
fragileResinTimes = countResult.fragileResinCount;
|
||
log.info(`脆弱树脂可刷取次数: ${fragileResinTimes}`);
|
||
} else {
|
||
log.info(`脆弱树脂未开启使用,跳过计算`);
|
||
}
|
||
|
||
// 计算总次数
|
||
count = originalResinTimes + condensedResinTimes + transientResinTimes + fragileResinTimes;
|
||
log.info(`总计可刷取次数: ${count}`);
|
||
|
||
let result = {
|
||
count: count,
|
||
originalResinTimes: originalResinTimes,
|
||
condensedResinTimes: condensedResinTimes,
|
||
transientResinTimes: transientResinTimes,
|
||
fragileResinTimes: fragileResinTimes
|
||
}
|
||
|
||
return result;
|
||
} catch (error) {
|
||
log.error(`统计树脂数量时发生异常: ${error.message}`);
|
||
throw error;
|
||
}
|
||
} |