diff --git a/repo/js/AutoWoodcutting-Pathing/README.md b/repo/js/AutoWoodcutting-Pathing/README.md index dcb0c366b..90879fda2 100644 --- a/repo/js/AutoWoodcutting-Pathing/README.md +++ b/repo/js/AutoWoodcutting-Pathing/README.md @@ -2,6 +2,12 @@ **批量采集前,请对用到的路径进行预测试,避免因线路卡死或其他异常情况导致空跑** +目前脚本已支持识别背包内木材数量(默认关闭),可在自定义配置中指定木材种类进行识别(**存在无法识别的情况**) + +开启背包检测后,会导致自定义配置中填入的砍伐数目**不生效**,且**无法识别的木材不进行采集** + +开启背包检测后,会先去渊下宫-蛇肠之路,这里的识别率相对高一些 + 脚本内置的路径仅供参考,随着软件及地图的更新,可能**并非最佳**采集路径,如有更好的路径,欢迎贡献 目前脚本已支持6.0版本之前的全部木材,清单如下:`桦木 萃华木 松木 垂香木 杉木 竹节 却砂木 梦见木 枫木 孔雀木 御伽木 证悟木 业果木 辉木 刺葵木 柽木 悬铃木 椴木 白梣木 香柏木 炬木 白栗栎木 燃爆木 灰灰楼林木 桃椰子木 银冷衫木 榛木 夏栎木 桤木` diff --git a/repo/js/AutoWoodcutting-Pathing/assets/AutoPath/背包木材检测专用.json b/repo/js/AutoWoodcutting-Pathing/assets/AutoPath/背包木材检测专用.json new file mode 100644 index 000000000..c7a74d418 --- /dev/null +++ b/repo/js/AutoWoodcutting-Pathing/assets/AutoPath/背包木材检测专用.json @@ -0,0 +1,26 @@ +{ + "info": { + "authors": [], + "bgi_version": "0.45.0", + "description": "", + "enable_monster_loot_split": false, + "last_modified_time": 1761330330598, + "map_match_method": "", + "map_name": "Enkanomiya", + "name": "背包木材检测专用", + "tags": [], + "type": "collect", + "version": "1.0" + }, + "positions": [ + { + "action": "", + "action_params": "", + "id": 1, + "move_mode": "walk", + "type": "teleport", + "x": 1581.1136474609375, + "y": -112.44970703125 + } + ] +} \ No newline at end of file diff --git a/repo/js/AutoWoodcutting-Pathing/main.js b/repo/js/AutoWoodcutting-Pathing/main.js index 103829ee5..9a1e83913 100644 --- a/repo/js/AutoWoodcutting-Pathing/main.js +++ b/repo/js/AutoWoodcutting-Pathing/main.js @@ -1,10 +1,4 @@ (async function () { - const woodType = ["桦木", "萃华木", "松木", "却砂木", "竹节", "垂香木", "杉木", "梦见木", "枫木", "孔雀木", "御伽木", "辉木", "业果木", "证悟木", "刺葵木", "柽木", "悬铃木", "椴木", "白梣木", "香柏木", "炬木", "白栗栎木", "灰灰楼林木", "燃爆木", "桃椰子木", "银冷杉木", "榛木", "夏栎木", "桤木"]; - const singleWoodType = ["桦木", "萃华木", "松木", "杉木", "竹节", "却砂木", "梦见木", "枫木", "孔雀木", "御伽木", "证悟木", "业果木", "辉木", "刺葵木", "柽木", "白梣木", "炬木", "白栗栎木", "燃爆木", "灰灰楼林木", "桃椰子木", "银冷杉木", "榛木", "夏栎木", "桤木"]; - - const woodNumberMap = new Map(woodType.map(key => [key, 0])); - let woodNumberMapCopy = new Map(); - // 用于求解 垂香木-萃华木-香柏木 路线次数的线性规划求解器, 暴力求解,加一点点剪枝. function lpsolve1(y1, y2, y3) { let x1max = Math.ceil(y1 / 48); @@ -82,9 +76,9 @@ if (pathing.fileName.length > 1 && pathing.fileName[0].includes('大循环')) { try { log.info(`正在执行 ${pathingName} 大循环路径`); - await fakeLog(`${pathing.fileName}`, false, true, 0); + await fakeLog(`${pathing.fileName[0]}`, false, true, 0); await pathingScript.runFile(filePath); - await fakeLog(`${pathing.fileName}`, false, false, 0); + await fakeLog(`${pathing.fileName[0]}`, false, false, 0); await sleep(1); log.info(`完成 ${pathingName} 大循环路径, 获得${woodCountToStr(woodCount)}`); woodCount.forEach((value, key) => { woodNumberMap.set(key, woodNumberMap.get(key) - value) }); @@ -204,7 +198,7 @@ }); } if (unsupportedWoods.length !== 0) { - log.info(`${unsupportedWoods.join(", ")} 暂不支持`); + log.warn(`${unsupportedWoods.join(", ")} 暂不支持`); } woodNumberMapCopy = new Map([...woodNumberMap]); } @@ -248,6 +242,53 @@ return theElderTreeStatus } + // 调用BGI任务读取背包中的木材数量并返回 + async function woodInventory(woodsArray, numbersArray) { + log.info("先别急,先别动键盘鼠标,要去一个神秘的地方") + await pathingScript.runFile('assets/AutoPath/背包木材检测专用.json'); + moveMouseBy(0, -114514); + moveMouseBy(0, -1919810); + if (woodsArray.length === 0) { + var resultDict = await dispatcher.runTask(new SoloTask("CountInventoryItem", { "gridScreenName": "Materials", "itemNames": woodType })); + } else { + var resultDict = await dispatcher.runTask(new SoloTask("CountInventoryItem", { "gridScreenName": "Materials", "itemNames": woodsArray })); + } + + const keys = []; + const values = []; + + try { + for (const [key, value] of Object.entries(resultDict)) { + // 尝试将值转换为数字 + const numValue = Number(value); + + // 检查是否为有效数字(NaN 表示不是数字) + if (isNaN(numValue)) { + console.warn(`跳过无效值: key=${key}, value=${value}`); + continue; + } + + // 执行计算逻辑 + const diff = 9999 - numValue; + const result = diff > 2000 ? 2000 : diff; + + keys.push(key); + values.push(result); + } + // log.info("成功检测到的木材" + keys.join(",")); + // log.info("成功检测到的木材砍伐数量" + values.join(",")); + if (keys.length === 0) { + log.warn("未识别到任何木材,使用预设数据"); + return [woodsArray, numbersArray]; + } else { + return [keys, values]; + } + } catch (err) { + log.warn("处理故障,使用预设数据") + return [woodsArray, numbersArray]; + } + } + function logTimeTaken(startTime) { const currentTime = Date.now(); const totalTimeInSeconds = (currentTime - startTime) / 1000; @@ -344,9 +385,12 @@ } } - // Set game environment settings - const startTime = Date.now(); - setGameMetrics(1920, 1080, 1); + const woodType = ["桦木", "萃华木", "松木", "却砂木", "竹节", "垂香木", "杉木", "梦见木", "枫木", "孔雀木", "御伽木", "辉木", "业果木", "证悟木", "刺葵木", "柽木", "悬铃木", "椴木", "白梣木", "香柏木", "炬木", "白栗栎木", "灰灰楼林木", "燃爆木", "桃椰子木", "银冷杉木", "榛木", "夏栎木", "桤木"]; + const singleWoodType = ["桦木", "萃华木", "松木", "杉木", "竹节", "却砂木", "梦见木", "枫木", "孔雀木", "御伽木", "证悟木", "业果木", "辉木", "刺葵木", "柽木", "白梣木", "炬木", "白栗栎木", "燃爆木", "灰灰楼林木", "桃椰子木", "银冷杉木", "榛木", "夏栎木", "桤木"]; + + const woodNumberMap = new Map(woodType.map(key => [key, 0])); + let woodNumberMapCopy = new Map(); + // 修改路线:除了 垂香木-萃华木-香柏木,悬铃木-椴木 以外,其他木材基本都是单独路线,可以替换 \assets\AutoPath 中的路径追踪脚本,然后修改 pathingMap 中的文件名即可。 // pathingMap 为木材路径追踪文件路径列表, 键名可以随意命名, 值的 fileName 属性为路线包含路径追踪文件名列表, 文件夹为'assets/AutoPath/', 如果还有子文件夹请添加 folderName 属性. 如果 fileName 数组中有两项以上, 并且第一个文件名包含 '大循环', 则会先执行一次大循环, 剩余的文件名视为循环路径, 将在每次循环中依次执行. // 因为要根据文件名来计算循环次数, 所以文件命名必须包含 '木材种类1-数量1-木材种类2-数量2-...', 说明此文件路线中采集的木材种类和数目. 如果没有采集木材(比如单纯跑路的大循环)也请至少添加一种类型, 数量可以填0. @@ -396,15 +440,20 @@ await sleep(500); } + const startTime = Date.now(); + // 分别将填入的木材名称和数量转成数组 + let woodsArray = settings.woods ? settings.woods.split(/\s+/) : []; + let numbersArray = settings.numbers ? settings.numbers.split(/\s+/).map(Number).map(num => isNaN(num) ? 0 : num) : []; + let hasItto = settings.hasItto ? settings.hasItto : false; let theBoonOfTheElderTreeStatus = settings.theBoonOfTheElderTree ? await theElderTree() : true; + // 判断是否开启背包检测,如果未开启或识别失败,则使用设置填入的数据或默认数据 + const [woodsInventory, woodCountInventory] = settings.woodInventory ? await woodInventory(woodsArray, numbersArray) : [woodsArray, numbersArray]; + + mapWoodsToNumbers(woodsInventory, woodCountInventory, hasItto); + // mapWoodsToNumbers(woodsArray, numbersArray, hasItto); if (theBoonOfTheElderTreeStatus) { log.info('自动伐木开始...'); - - let woodsArray = settings.woods ? settings.woods.split(/\s+/) : []; - let numbersArray = settings.numbers ? settings.numbers.split(/\s+/).map(Number).map(num => isNaN(num) ? 0 : num) : []; - let hasItto = settings.hasItto ? settings.hasItto : false; - mapWoodsToNumbers(woodsArray, numbersArray, hasItto); await woodCutting(); } else { log.error("未装备有王树瑞佑,伐木结束") diff --git a/repo/js/AutoWoodcutting-Pathing/manifest.json b/repo/js/AutoWoodcutting-Pathing/manifest.json index 56ac623ea..151443928 100644 --- a/repo/js/AutoWoodcutting-Pathing/manifest.json +++ b/repo/js/AutoWoodcutting-Pathing/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 1, "name": "自动伐木-地图追踪版", - "version": "2.1.5", + "version": "3.0.0", "description": "基于地图追踪的自动伐木,已支持6.0版本及之前的全部木材\n默认砍伐全部支持木材至2000上限\n自定义设置:\n-可更改砍伐木材种类和数量\n-可以单独设置每个木材数量\n-可设置队伍中是否包含一斗,按保底20%,计算砍伐数量时会除以1.2", "bgi_version": "0.52.0", "tags": [ diff --git a/repo/js/AutoWoodcutting-Pathing/settings.json b/repo/js/AutoWoodcutting-Pathing/settings.json index 779081bc1..ca878450a 100644 --- a/repo/js/AutoWoodcutting-Pathing/settings.json +++ b/repo/js/AutoWoodcutting-Pathing/settings.json @@ -1,4 +1,10 @@ [ + { + "name": "woodInventory", + "type": "checkbox", + "label": "开启背包木材检测,开启后砍伐识别到的木材", + "default": false + }, { "name": "woods", "type": "input-text", @@ -7,7 +13,8 @@ { "name": "numbers", "type": "input-text", - "label": "砍伐数目:空格分隔,不填默认2000,只填一个值表示每种都是" + "label": "砍伐数目:空格分隔,不填默认2000,\n只填一个值表示每种都是,开启背包木材检测后失效", + "default": "2000" }, { "name": "hasItto", @@ -140,5 +147,4 @@ // "type": "checkbox", // "label": "燃爆木" // } - ] \ No newline at end of file