From b536df73216fc1941da26d254ecc9006e5dd832d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8F=90=E7=93=A6=E7=89=B9=E9=92=93=E9=B1=BC=E7=8E=B3?= =?UTF-8?q?=E5=B8=88?= Date: Mon, 26 Jan 2026 16:32:02 +0800 Subject: [PATCH] =?UTF-8?q?JS=E8=84=9A=E6=9C=AC=EF=BC=9AAEscoffier=5Fchef?= =?UTF-8?q?=E3=80=90=E6=9B=B4=E6=96=B0=E3=80=91=20(#2786)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- repo/js/AEscoffier_chef/README.md | 36 +++- .../assets/icons/糖雕·哥伦比娅.png | Bin 0 -> 6704 bytes repo/js/AEscoffier_chef/main.js | 171 ++++++++++++------ repo/js/AEscoffier_chef/manifest.json | 2 +- repo/js/AEscoffier_chef/settings.json | 38 +++- 5 files changed, 187 insertions(+), 60 deletions(-) create mode 100644 repo/js/AEscoffier_chef/assets/icons/糖雕·哥伦比娅.png diff --git a/repo/js/AEscoffier_chef/README.md b/repo/js/AEscoffier_chef/README.md index 81a33b536..7a2bb2a94 100644 --- a/repo/js/AEscoffier_chef/README.md +++ b/repo/js/AEscoffier_chef/README.md @@ -1,7 +1,9 @@ # 🍽️ 一只爱可菲脚本功能说明 基于 **地图追踪 · OCR · 模板匹配** 的自动烹饪脚本,可实现 **一键刷满所有料理熟练度**。 + 若料理已解锁自动烹饪,则不会使用手动烹饪。 -待做功能:特殊料理(支持根据相关概率尽可能制作出指定数目的特殊料理) + +待做功能:不可制作的料理获取、食材加工相关 --- @@ -72,13 +74,39 @@ --- +## ✨ 特殊料理 + +### **选择烹饪数量的应用对象** + +```烹饪次数```:根据填入的```烹饪数量```,填入多少次就烹饪多少次 + +```预期的特殊料理数```:根据填入的```烹饪数量```,计算出“必出”概率 + + - 假设10%的概率出特殊料理,那么```烹饪数量```为5的情况下就烹饪 10 * 5 = 50次 + - 内置的特殊料理爆率如下(游戏内具体爆率未知,以下表格仅供参考) +
+ 点击展开 + + | 星级 | 奇怪 | 普通 | 美味 | + |-----|-------|-------|------| + | 1 | 0.1 | 0.15 | 0.2 | + | 2 | 0.1 | 0.1 | 0.15 | + | 3 | 0.05 | 0.1 | 0.15 | + | 4 | 0.05 | 0.05 | 0.1 | + 注:爱可菲美味15% + +
+ +--- + ## 🛠️ 其他说明 1. 如果在```选择料理```处选择了重复的料理,仍视作选择1次 -2. ```烹饪数量```设置单个数值将应用到所有选择的料理,如果使用空格隔开数值设置多个料理的数量,需要确保数值的数量等于实际选择的料理数(若出现重复项,只计入出现的第一个重复项) +2. 对应的```烹饪数量```设置单个数值将应用到所有选择的料理,如果使用空格隔开数值设置多个料理的数量,需要确保数值的数量等于实际选择的料理数(若出现重复项,只计入出现的第一个重复项) - 例:选择的料理 A B C A B D 设置的数值 1 2 3 4 ,分别代表A: 1, B: 2, C: 3, D: 4 - - 注意:```烹饪数量```的顺序为```选择料理```处从左到右、从上到下 + - 注意:```烹饪数量```的顺序为对应的```选择料理```处从左到右、从上到下 3. JS脚本配置的食谱顺序与游戏内基本一致(可以使用游戏内的筛选功能,快速找到料理) +4. 运行前确保料理不会超过2000上限 --- @@ -94,6 +122,7 @@ | 篝火边的欢腾 | 篝火边的欢腾 | 3 | 提升暴击 | 正常料理 |
队伍中所有角色暴击率提升15%,持续300秒。多人游戏时,仅对自己的角色生效。
|
烹饪获得
【食谱】在挪德卡莱·皮拉米达城正西方的一处哨站与NPC别蕾娜对话并完成她的委托后,开启精致的宝箱获得该食谱。
| 挪德卡莱 | 兽肉(2),火腿(1),香肠(1),胡椒(1) | | 花果草糖 | 花果草糖 | 3 | 生命上限提升 | 正常料理 |
队伍中所有角色生命值上限提升22%,持续300秒。多人游戏时,仅对自己的角色生效。
|
烹饪获得
【食谱】那夏镇「斯佩兰扎」购买
| 挪德卡莱 | 宿影花(2),冬凌草(2),夏槲果(2),白灵果(2) | | 皎月渺渺 | 皎月渺渺 | 3 | 生命上限提升 | 特殊料理 |
队伍中所有角色生命值上限提升30%,持续300秒。多人游戏时,仅对自己的角色生效。
|
烹饪获得
【角色】 哥伦比娅
【食谱】 花果草糖
| 挪德卡莱 | 宿影花(2),冬凌草(2),夏槲果(2),白灵果(2) | +| 糖雕·哥伦比娅 | 糖雕·哥伦比娅 | 2 | 其他,不可制作 | 探索获取,限时 |
好看又好吃,但是几乎没什么用。
|
队伍中有 哥伦比娅 时与那夏镇乌娜亚塔对话获得(每日仅能获得一种糖雕)
| 挪德卡莱 | | | 香辛炸鸡块 | 香辛炸鸡块 | 4 | 持续恢复 | 正常料理 |
立即为选中的角色恢复生命值上限的32%,并在之后的30秒内,每5秒恢复730点生命值。
|
烹饪获得
【食谱】「原神×Duolingo」联动活动第二期连续完成3天任务获取(国际服限定)
| 其他 | 禽肉(4),面粉(3),香辛料(2),薄荷(2) | | 苹果焖肉(初试版) | 苹果焖肉(初试版) | 3 | 恢复血量 | 特殊料理 |
为选中的角色恢复生命值上限的40%,并额外恢复2350点生命值。
|
烹饪获得
【角色】 杜林
【食谱】 北地苹果焖肉
| 蒙德 | 兽肉(3),苹果(3),黄油(1),胡椒(1) | | 「课后作业」 | 「课后作业」 | 3 | 恢复血量 | 特殊料理 |
为选中的角色恢复生命值上限的40%,并额外恢复2350点生命值。
|
烹饪获得
【角色】 雅珂达
【食谱】 双果卷
| 挪德卡莱 | 面粉(3),夏槲果(2),白灵果(2),糖(1) | @@ -497,6 +526,7 @@ | 绝境求生烤鱼 | 绝境求生烤鱼 | 1 | 恢复血量 | 特殊料理 |
为选中的角色恢复生命值上限的16%,并额外恢复1350点生命值。
|
烹饪获得
【角色】 刻晴
【食谱】 烤吃虎鱼
| 璃月 | 鱼肉(1),胡椒(1) | | 果香串烤 | 果香串烤 | 1 | 恢复血量 | 特殊料理 |
为选中的角色恢复生命值上限的16%,并额外恢复1350点生命值。
|
烹饪获得
【角色】 凯亚
【食谱】 野菇鸡肉串
| 蒙德 | 蘑菇(1),禽肉(1) | | 大碗茶 | 大碗茶 | 1 | 持续恢复,不可制作 | 饮品 |
立即为选中的角色恢复生命值上限的14%,并在之后的30秒内,每5秒恢复350点生命值。
|
<茶水摊摊主>凯叔 处购买
<大碗茶摊主>老周叔 处购买
朱老板处购买
| 璃月 | | + --- diff --git a/repo/js/AEscoffier_chef/assets/icons/糖雕·哥伦比娅.png b/repo/js/AEscoffier_chef/assets/icons/糖雕·哥伦比娅.png new file mode 100644 index 0000000000000000000000000000000000000000..f3bab674db3bcc0c8c01003e148bd11d0bbfd212 GIT binary patch literal 6704 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 literal 0 HcmV?d00001 diff --git a/repo/js/AEscoffier_chef/main.js b/repo/js/AEscoffier_chef/main.js index e9b374bbf..30dd83d46 100644 --- a/repo/js/AEscoffier_chef/main.js +++ b/repo/js/AEscoffier_chef/main.js @@ -1,4 +1,4 @@ -(async function () { // 超2000上限未适配,template的dispose需要完善 +(async function () { // 超2000上限条件未适配,OCR特殊字符可能失效,滑块底部时左下角料理文本无法识别 const food_msg = JSON.parse(file.readTextSync("assets/foodMsg.json")); const material_list = ['蘑菇', '黑麦粉', '洋葱', '夏槲果', '卷心菜', '胡萝卜', '土豆', '酸奶油', '兽肉', '火腿', '香肠', '胡椒', '宿影花', '冬凌草', '白灵果', '禽肉', '面粉', '香辛料', '薄荷', '苹果', '黄油', '糖', '鱼肉', '奶油', '秃秃豆', '鸟蛋', '盐', '番茄', '寒涌石', '奶酪', '青蜜莓', '苦种', '虾仁', '颗粒果', '咖啡豆', '墩墩桃', '日落果', '树莓', '牛奶', '汐藻', '泡泡桔', '海露花', '螃蟹', '绯樱绣球', '红果果菇', '堇瓜', '蟹黄', '清心', '烬芯花', '果酱', '澄晶实', '培根', '烛伞蘑菇', '肉龙掌', '发酵果实汁', '茉洁草', '稻米', '白萝卜', '松茸', '沉玉仙茗', '豆腐', '绝云椒椒', '竹笋', '金鱼草', '杏仁', '小麦', '松果', '海草', '琉璃袋', '帕蒂沙兰', '神秘的肉', '莲蓬', '枣椰', '鳗肉', '须弥蔷薇', '钩钩果', '树王圣体菇', '星蕈', '嘟嘟莲', '马尾', '甜甜花', '小灯草', '「冷鲜肉」', '熏禽肉']; const food_category = { @@ -9,11 +9,12 @@ "其他": ["其他", "不可制作"], } // const food_type = ["特殊料理", "正常料理", "活动料理", "饮品", "视觉效果", "购买料理", "探索获取", "角色技能获取", "限时"] - const special_food = { // 各星级下,奇怪,普通,美味的特殊料理爆率(优菈美味10%,爱可菲15%)[特殊料理用] + const special_food = { // 5星仅作占位用,无实际作用 [特殊料理用] "1": [0.1, 0.15, 0.2], "2": [0.1, 0.1, 0.15], "3": [0.05, 0.1, 0.15], - "4": [0.05, 0.05, 0.1] + "4": [0.05, 0.05, 0.1], + "5": [0.05, 0.05, 0.1] } /** @@ -139,7 +140,7 @@ * * @param target 目标字符串 * @param candidates 字符串数组 - * @returns {null} + * @returns {Promise} * @see levenshteinDistance */ async function findClosestMatch(target, candidates) { @@ -376,7 +377,7 @@ } } if (flag) { - log.error(`区域(${x}, ${y}, ${w}, ${h})内未找到文本:${text}`); + log.debug(`区域(${x}, ${y}, ${w}, ${h})内未找到文本:${text}`); return false; } } else { @@ -597,6 +598,7 @@ // 确保滑动到顶部 await scroll_bar_to_side(1282, 112, 13, 838, 131, 930, 124, 936, 1288, "Up"); // 料理制作界面 + log.info(`在当前界面寻找 ${food_name} `); let select_food_category = food_msg[food_name]["category"]; let search_keys = []; // 大类 for (const [c_name, c_detail] of Object.entries(food_category)) { @@ -630,8 +632,9 @@ let ocrResult = await ocr_find_area(104, 108, 1172, 857, await deal_string(food_name)); if (!ocrResult) { while (await scroll_page(1282, 112, 13, 838, 131, 930, 1288, "Down")) { - let ocrResult = await ocr_find_area(104, 108, 1172, 857, await deal_string(food_name)); + ocrResult = await ocr_find_area(104, 108, 1172, 857, await deal_string(food_name)); if (ocrResult) break; + await sleep(300); } } if (ocrResult) { @@ -666,6 +669,8 @@ log.info(`开始获取 ${food_name} 的食材余量...`); + let materialList = Object.keys(food_msg[food_name]["formula"]); // OCR纠错用 + for (let i = 0; i < m_count; i++) { let flag = false; // 点击食材(上) @@ -687,12 +692,19 @@ } } if (flag) { - let ocrName = await Ocr(736, 254, 280, 73); + let ocrName = await Ocr(736, 254, 280, 73); // 文本较少 if (ocrName) { - ocrName = await findClosestMatch(ocrName.text, material_list); // [DEBUG] material_list 或许应该换成 Object.keys(food_msg[food_name]["formula"]) + ocrName = await findClosestMatch(ocrName.text, materialList); // 最大限度避免OCR误差(结合动态调整的materialList[当前料理的食材列表]) + materialList = materialList.filter(item => item !== ocrName); } else { - log.error("OCR错误"); - return false; + ocrName = await Ocr(736, 174, 280, 153); // 文本较多 + if (ocrName) { + ocrName = await findClosestMatch(ocrName.text, Object.keys(food_msg[food_name]["formula"])); + materialList = materialList.filter(item => item !== ocrName); + } else { + log.error("OCR错误"); + return false; + } } let item_num = await get_current_item_num(); if (item_num) { @@ -715,9 +727,10 @@ /** * 根据JS脚本配置的全局设置,在烹饪界面选择角色加成 - * @returns {Promise} + * @param spl 设定为选择特殊料理 + * @returns {Promise} */ - async function check_character_bonus() { + async function check_character_bonus(spl = false) { await sleep(200); click(1779, 254); while (true) { @@ -728,10 +741,12 @@ await sleep(200); let ocrResult = await ocr_find_area(148, 95, 773, 937, "产出"); let flag = false; - if (settings.characterBonus === "12%概率双倍") { - if (ocrResult) ocrResult.Click(); - log.info("选择角色加成: 12%概率双倍"); - } else if (settings.characterBonus === "特殊料理") { + if (settings.characterBonus === "12%概率双倍" && !spl) { + if (ocrResult) { + ocrResult.Click(); + log.info("选择角色加成: 12%概率双倍"); + } + } else if (settings.characterBonus === "特殊料理" || spl) { let checkOcr = await ocr_find_area(148, 95, 773, 937, "特殊"); if (checkOcr) { checkOcr.Click(); @@ -756,7 +771,7 @@ flag = true; } } - if (flag) { + if (flag && !spl) { if (ocrResult) { ocrResult.Click(); log.info("选择角色加成: 12%概率双倍"); @@ -767,6 +782,7 @@ await sleep(500); click(1893, 889); await sleep(500); + return !flag; } /** @@ -778,9 +794,10 @@ * 角色加成选择,特殊料理 [DEBUG]左侧角色选择8人,最多有6条加成,先不加滑块逻辑了 * @param food_name 料理名 * @param food_num 料理数量 + * @param spl 特殊料理 * @returns {Promise} */ - async function escoffier_cook_for_u(food_name, food_num) { + async function escoffier_cook_for_u(food_name, food_num, spl = false) { if (settings.dealInsufficient !== "禁用") { // 食材数量检测 let material_quantity = await get_material_num(food_name); @@ -823,9 +840,23 @@ click(1681, 1019); // 点击 制作 await sleep(800); // 检测角色加成 - await check_character_bonus(); + let resultFlag = await check_character_bonus(spl); + if (!resultFlag) { + let characterName = "未知"; + for (const f_msg of Object.values(food_msg)) { + if (f_msg["belonging"] === food_name) { + characterName = f_msg["character"]; + break; + } + } + log.error(`未找到 ${food_name} 对应的特殊料理角色(${characterName})...`); + return false; + } - let checkOcr = await Ocr(730, 993, 124, 40); + await sleep(200); + click(1893, 889); + await sleep(500); + let checkOcr = await Ocr(730, 993, 524, 40); if (checkOcr) { if (!(checkOcr.text.includes("自动"))) { // 未解锁自动烹饪 // 手动烹饪默认次数 @@ -892,32 +923,60 @@ /** * 根据settings的选择,确定料理名和对应的数量 + * @param spl 特殊料理 * @returns {Promise} 如果成功读取,返回料理名称和料理数量的字典 */ - async function calculate_food() { - let arrays = [ - Array.from(settings.selectRecovery), - Array.from(settings.selectATKBoosting), - Array.from(settings.selectAdventure), - Array.from(settings.selectDEFBoosting), - Array.from(settings.selectOthers) - ] - const uniqueArray = [...new Set(arrays.flat())]; // 合并去重 - - let foodNum = settings.foodNum.trim().split(" "); - + async function calculate_food(spl = false) { let foodDic = {}; + let foodNum, foodList; + + // 读取设置项 + if (spl) { + foodList = Array.from(settings.selectCharacter); + foodNum = settings.characterFoodNum.trim().split(" "); + log.debug(`解析料理数据(spl)\n${foodList.join("|")}\n${foodNum.join("|")}`); + // 将特殊料理名转换为普通料理名 [DEBUG] 未测试 + let tempList = []; + for (let i = 0; i < foodList.length; i++) { + let spl_name = foodList[i].split("(")[0]; + tempList.push(food_msg[spl_name]["belonging"]); + } + foodList = tempList; + } else { + let arrays = [ + Array.from(settings.selectRecovery), + Array.from(settings.selectATKBoosting), + Array.from(settings.selectAdventure), + Array.from(settings.selectDEFBoosting), + Array.from(settings.selectOthers) + ] + foodList = [...new Set(arrays.flat())]; // 合并去重 + foodNum = settings.foodNum.trim().split(" "); + log.debug(`解析料理数据\n${foodList.join("|")}\n${foodNum.join("|")}`); + } + + // 检测并合并数量 if (foodNum.length === 1) { - for (let i = 0; i < uniqueArray.length; i++) { - foodDic[uniqueArray[i]] = parseInt(foodNum[0], 10); + for (let i = 0; i < foodList.length; i++) { + foodDic[foodList[i]] = parseInt(foodNum[0], 10); } } else { - if (uniqueArray.length !== foodNum.length) { + if (foodList.length !== foodNum.length) { log.error("输入的料理数与选择的料理数不一致!"); return false; } - for (let i = 0; i < uniqueArray.length; i++) { - foodDic[uniqueArray[i]] = parseInt(foodNum[i], 10); + for (let i = 0; i < foodList.length; i++) { + foodDic[foodList[i]] = parseInt(foodNum[i], 10); + } + } + + // 根据概率计算大致次数(向上取整)(spl) + if (spl && settings.characterMode === "预期的特殊料理数") { + for (const[f_name, f_num] of Object.entries(foodDic)) { + let probability = special_food[food_msg[f_name]["price"]][2]; + let base = Math.ceil(1 / probability); + foodDic[f_name] = base * f_num; + log.info(`料理(${f_name})的预期烹饪次数发生更改: ${f_num} -> ${base * f_num}`) } } return foodDic; @@ -930,6 +989,9 @@ return null; } + // 返回主界面 + await genshin.returnMainUi(); + // 刷满熟练度 if (settings.unlockAutoCooking) { log.info("当前模式为刷满熟练度..."); @@ -947,24 +1009,31 @@ log.debug("料理熟练度循环..."); } log.info("刷满熟练度 任务结束..."); + // 返回主界面 + await genshin.returnMainUi(); return null; } - // 制作料理 - let food_dic = await calculate_food(); - if (food_dic) { - // 前往锅 - let flag = await go_and_interact("锅"); - if (!flag) { - log.error("未找到锅..."); - return null; - } - for (const [f_name, f_num] of Object.entries(food_dic)) { - // 找到料理 - let findResult = await find_and_click_food(f_name); - if (findResult) { - await escoffier_cook_for_u(f_name, f_num); + // 制作料理和特殊料理 + for (let i = 0; i < 2; i++) { + let food_dic = await calculate_food(i !== 0); + if (Object.keys(food_dic).length !== 0) { + // 前往锅 + let flag = await go_and_interact("锅"); + if (!flag) { + log.error("未找到锅..."); + return null; } + for (const [f_name, f_num] of Object.entries(food_dic)) { + // 找到料理 + let findResult = await find_and_click_food(f_name); + if (findResult) { + await escoffier_cook_for_u(f_name, f_num, i !== 0); + } + } + log.info("全部料理制作完毕..."); + // 返回主界面 + await genshin.returnMainUi(); } } } diff --git a/repo/js/AEscoffier_chef/manifest.json b/repo/js/AEscoffier_chef/manifest.json index 8879c1a39..3ed189de5 100644 --- a/repo/js/AEscoffier_chef/manifest.json +++ b/repo/js/AEscoffier_chef/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "一只爱可菲", - "version": "2.0", + "version": "2.1", "bgi_version": "0.55.0", "description": "专精料理制作的爱可菲(自动烹饪及解锁、特殊料理)", "tags": [ diff --git a/repo/js/AEscoffier_chef/settings.json b/repo/js/AEscoffier_chef/settings.json index 83ec2376c..e59a66cc0 100644 --- a/repo/js/AEscoffier_chef/settings.json +++ b/repo/js/AEscoffier_chef/settings.json @@ -334,10 +334,38 @@ "小小阿夏包" ] }, + { + "type": "separator" + }, + { + "type": "separator" + }, + { + "name": "title_2", + "type": "input-text", + "label": "----------------------------特殊料理----------------------------", + "default": "⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬" + }, + { + "name": "characterMode", + "type": "select", + "label": "选择烹饪数量的应用对象\n注:详见README", + "options": [ + "烹饪次数", + "预期的特殊料理数" + ], + "default": "烹饪次数" + }, + { + "name": "characterFoodNum", + "type": "input-text", + "label": "烹饪数量(1-999)[仅用于特殊料理]\n注:单数字应用到全部,或用单个空格隔开设置每个的数量", + "default": "0" + }, { "name": "selectCharacter", "type": "multi-checkbox", - "label": "【暂不可用】>>> 特色料理 ✨✨✨✨✨✨✨✨✨✨", + "label": "【选择料理】>>> 特殊料理 ✨✨✨✨✨✨✨✨✨✨", "options": [ "果香串烤(凯亚)", "绝境求生烤鱼(刻晴)", @@ -455,7 +483,7 @@ "type": "separator" }, { - "name": "title_2", + "name": "title_3", "type": "input-text", "label": "----------------------------食材加工----------------------------", "default": "⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬" @@ -467,7 +495,7 @@ "type": "separator" }, { - "name": "title_3", + "name": "title_4", "type": "input-text", "label": "-----------------------料理获取(不可制作)-----------------------", "default": "⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬" @@ -479,7 +507,7 @@ "type": "separator" }, { - "name": "title_4", + "name": "title_5", "type": "input-text", "label": "----------------------------全局设置----------------------------", "default": "⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬⏬" @@ -487,7 +515,7 @@ { "name": "dealInsufficient", "type": "select", - "label": "检测到食材不足时\n注::禁用则不检测食材", + "label": "检测到食材不足时\n注:禁用则不检测食材数量", "options": [ "跳过此料理", "用尽食材",