JS脚本:禽肉好感 (#3155)
* 提交新的好感任务脚本 * 完善JS脚本:禽肉好感 * 完善JS脚本:禽肉好感 * 完善JS脚本:禽肉好感 * JS脚本:禽肉好感,增加预估剩余时间显示 * 替换JS脚本:鸡腿好感
21
repo/js/AutoFriendshipFowl/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
**简介:**
|
||||
---
|
||||
- 通过完成“动物密友”突发事件,获取角色好感、摩拉、锻造矿。
|
||||
- 完成突发事件每天最多可获得10次奖励。
|
||||
- 脚本会确保游戏模式为单人模式。
|
||||
- 当完成突发事件10次,或事件完成后未获得奖励时,脚本将结束运行。
|
||||
- 测试正常任务时间在8分钟左右
|
||||
---
|
||||
|
||||
|
||||
**使用说明:**
|
||||
|
||||
1. 添加脚本
|
||||
- 在 BGI 配置组中添加“禽肉好感”脚本。请不要在调度器外直接运行。
|
||||
2. 配置组设置
|
||||
- 无需设置
|
||||
3. JS脚本自定义配置(右键点击“禽肉好感”脚本 → 修改JS脚本自定义配置)
|
||||
- 填写好感队的队伍名称
|
||||
- 确保选择的好感队为4人队
|
||||
- 确保背包里“禽肉”充足
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"info": {
|
||||
"name": "到狗盆",
|
||||
"type": "collect",
|
||||
"author": "花火",
|
||||
"version": "1.2",
|
||||
"description": "",
|
||||
"bgi_version": "0.35.1"
|
||||
},
|
||||
"positions": [
|
||||
{
|
||||
"id": 1,
|
||||
"x": -4500.28125,
|
||||
"y": -3116.0146484375,
|
||||
"type": "target",
|
||||
"move_mode": "walk",
|
||||
"action": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"info": {
|
||||
"name": "到甜甜花",
|
||||
"type": "collect",
|
||||
"author": "花火",
|
||||
"version": "1.2",
|
||||
"description": "",
|
||||
"bgi_version": "0.43.5"
|
||||
},
|
||||
"positions": [
|
||||
{
|
||||
"id": 1,
|
||||
"action": "",
|
||||
"move_mode": "walk",
|
||||
"type": "target",
|
||||
"x": -4529.2578125,
|
||||
"y": -3084.009765625
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"info": {
|
||||
"name": "到达甜甜花位置",
|
||||
"type": "collect",
|
||||
"author": "花火",
|
||||
"version": "1.2",
|
||||
"description": "",
|
||||
"bgi_version": "0.43.5"
|
||||
},
|
||||
"positions": [
|
||||
{
|
||||
"id": 1,
|
||||
"action": "",
|
||||
"move_mode": "walk",
|
||||
"type": "teleport",
|
||||
"x": -4402.525390625,
|
||||
"y": -3052.986328125
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"x": -4407.537109375,
|
||||
"y": -3055.0751953125,
|
||||
"type": "path",
|
||||
"move_mode": "walk",
|
||||
"action": ""
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"x": -4480.993107617283,
|
||||
"y": -2996,
|
||||
"type": "path",
|
||||
"move_mode": "fly",
|
||||
"action": ""
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"x": -4500.1015625,
|
||||
"y": -3004.046875,
|
||||
"type": "path",
|
||||
"move_mode": "walk",
|
||||
"action": ""
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"x": -4529.2578125,
|
||||
"y": -3084.009765625,
|
||||
"type": "target",
|
||||
"move_mode": "walk",
|
||||
"action": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
85
repo/js/AutoFriendshipFowl/assets/pathing/鸡腿好感_初始化.json
Normal file
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"info": {
|
||||
"authors": [
|
||||
{
|
||||
"links": "https://github.com/Gedley",
|
||||
"name": "Gedley"
|
||||
}
|
||||
],
|
||||
"bgi_version": "0.45.0",
|
||||
"description": "",
|
||||
"enable_monster_loot_split": false,
|
||||
"last_modified_time": 1776789201832,
|
||||
"map_match_method": "",
|
||||
"map_name": "Teyvat",
|
||||
"name": "禽肉好感_初始化",
|
||||
"tags": [],
|
||||
"type": "collect",
|
||||
"version": "1.0"
|
||||
},
|
||||
"positions": [
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 1,
|
||||
"move_mode": "walk",
|
||||
"type": "teleport",
|
||||
"x": -4492,
|
||||
"y": -3208
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 2,
|
||||
"move_mode": "fly",
|
||||
"type": "path",
|
||||
"x": -4477.25,
|
||||
"y": -3188.93
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 3,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": -4495.12,
|
||||
"y": -3124.78
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 4,
|
||||
"move_mode": "fly",
|
||||
"type": "path",
|
||||
"x": -4510.1,
|
||||
"y": -3108.09
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 5,
|
||||
"move_mode": "jump",
|
||||
"type": "path",
|
||||
"x": -4512.96,
|
||||
"y": -3104.62
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 6,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": -4526.72,
|
||||
"y": -3086.67
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 7,
|
||||
"move_mode": "walk",
|
||||
"type": "path",
|
||||
"x": -4529.26,
|
||||
"y": -3084.01
|
||||
}
|
||||
]
|
||||
}
|
||||
58
repo/js/AutoFriendshipFowl/assets/pathing/鸡腿好感_喂狗.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"info": {
|
||||
"authors": [
|
||||
{
|
||||
"links": "https://github.com/Gedley",
|
||||
"name": "Gedley"
|
||||
}
|
||||
],
|
||||
"bgi_version": "0.45.0",
|
||||
"description": "",
|
||||
"enable_monster_loot_split": false,
|
||||
"last_modified_time": 1777125351967,
|
||||
"map_match_method": "",
|
||||
"map_name": "Teyvat",
|
||||
"name": "禽肉好感_喂狗",
|
||||
"tags": [],
|
||||
"type": "collect",
|
||||
"version": "1.0"
|
||||
},
|
||||
"positions": [
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 1,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": -4512.81,
|
||||
"y": -3105.59
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 2,
|
||||
"move_mode": "jump",
|
||||
"type": "path",
|
||||
"x": -4510.76,
|
||||
"y": -3106.63
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 3,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": -4502.67,
|
||||
"y": -3113.98
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 4,
|
||||
"move_mode": "walk",
|
||||
"type": "path",
|
||||
"x": -4500.11,
|
||||
"y": -3116.63
|
||||
}
|
||||
]
|
||||
}
|
||||
31
repo/js/AutoFriendshipFowl/assets/pathing/鸡腿好感_狗盆点位.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"info": {
|
||||
"authors": [
|
||||
{
|
||||
"links": "https://github.com/Gedley",
|
||||
"name": "Gedley"
|
||||
}
|
||||
],
|
||||
"bgi_version": "0.45.0",
|
||||
"description": "突发事件“动物密友”中狗盆的位置",
|
||||
"enable_monster_loot_split": false,
|
||||
"last_modified_time": 1776787867681,
|
||||
"map_match_method": "",
|
||||
"map_name": "Teyvat",
|
||||
"name": "禽肉好感_狗盆点位",
|
||||
"tags": [],
|
||||
"type": "collect",
|
||||
"version": "1.0"
|
||||
},
|
||||
"positions": [
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 1,
|
||||
"move_mode": "walk",
|
||||
"type": "target",
|
||||
"x": -4500.26,
|
||||
"y": -3116.57
|
||||
}
|
||||
]
|
||||
}
|
||||
31
repo/js/AutoFriendshipFowl/assets/pathing/鸡腿好感_甜甜花点位.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"info": {
|
||||
"authors": [
|
||||
{
|
||||
"links": "https://github.com/Gedley",
|
||||
"name": "Gedley"
|
||||
}
|
||||
],
|
||||
"bgi_version": "0.45.0",
|
||||
"description": "突发事件“动物密友”中甜甜花的位置",
|
||||
"enable_monster_loot_split": false,
|
||||
"last_modified_time": 1776787867681,
|
||||
"map_match_method": "",
|
||||
"map_name": "Teyvat",
|
||||
"name": "禽肉好感_甜甜花点位",
|
||||
"tags": [],
|
||||
"type": "collect",
|
||||
"version": "1.0"
|
||||
},
|
||||
"positions": [
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 1,
|
||||
"move_mode": "walk",
|
||||
"type": "target",
|
||||
"x": -4529.25,
|
||||
"y": -3084.01
|
||||
}
|
||||
]
|
||||
}
|
||||
58
repo/js/AutoFriendshipFowl/assets/pathing/鸡腿好感_返回.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"info": {
|
||||
"authors": [
|
||||
{
|
||||
"links": "https://github.com/Gedley",
|
||||
"name": "Gedley"
|
||||
}
|
||||
],
|
||||
"bgi_version": "0.45.0",
|
||||
"description": "",
|
||||
"enable_monster_loot_split": false,
|
||||
"last_modified_time": 1776787861554,
|
||||
"map_match_method": "",
|
||||
"map_name": "Teyvat",
|
||||
"name": "禽肉好感_返回",
|
||||
"tags": [],
|
||||
"type": "collect",
|
||||
"version": "1.0"
|
||||
},
|
||||
"positions": [
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 1,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": -4510.72,
|
||||
"y": -3107.23
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 2,
|
||||
"move_mode": "jump",
|
||||
"type": "path",
|
||||
"x": -4512.82,
|
||||
"y": -3104.66
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 3,
|
||||
"move_mode": "dash",
|
||||
"type": "path",
|
||||
"x": -4527.63,
|
||||
"y": -3085.92
|
||||
},
|
||||
{
|
||||
"action": "",
|
||||
"action_params": "",
|
||||
"id": 4,
|
||||
"move_mode": "walk",
|
||||
"type": "path",
|
||||
"x": -4529.2,
|
||||
"y": -3084.2
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
repo/js/AutoFriendshipFowl/assets/事件完成.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/动物密友.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/动物密友完成.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/单人模式.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/单人模式确认.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/投喂.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/摩拉.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/确认.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/离开队伍.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/禽肉数量.png
Normal file
|
After Width: | Height: | Size: 669 B |
BIN
repo/js/AutoFriendshipFowl/assets/突发事件.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
repo/js/AutoFriendshipFowl/assets/联机.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
@@ -1,131 +1,310 @@
|
||||
(async function () {
|
||||
const TELEPORT_COORDS = { x: 2297.60, y: -824.45 };
|
||||
async function switchPartyIfNeeded(partyName) {
|
||||
if (!partyName) {
|
||||
await genshin.returnMainUi();
|
||||
return;
|
||||
// 全局变量
|
||||
// 标记任务是否结束
|
||||
let finished = false;
|
||||
// 投喂次数
|
||||
let feedCount = 0;
|
||||
|
||||
//模板与识别对象预加载
|
||||
// “联机”指示图标裁剪范围为346, 29, 30, 30
|
||||
const coOpModeRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/联机.png'), 336, 19, 50, 50);
|
||||
// “回到单人模式”按钮完整范围为1483, 986, 308, 63,图像裁剪范围为1514, 997, 230, 42
|
||||
const singlePlayer1Ro = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/单人模式.png'), 1483, 986, 308, 63);
|
||||
// 单人模式“确认”按钮完整区域为979, 726, 370, 63,裁剪范围为1010, 736, 210, 42
|
||||
const singlePlayer1ConfirmRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/单人模式确认.png'), 979, 726, 370, 63);
|
||||
// “离开队伍”按钮完整范围为1483, 986, 308, 63,图像裁剪范围为1514, 997, 230, 42
|
||||
const singlePlayer2Ro = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/离开队伍.png'), 1483, 986, 308, 63);
|
||||
|
||||
//“动物密友”任务文字图像裁剪范围为83, 253, 84, 21。登陆完成后约500毫秒后可以检测到
|
||||
const friendToAnimalsRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/动物密友.png'), 30, 240, 150, 400);
|
||||
friendToAnimalsRo.Threshold = 0.5;
|
||||
friendToAnimalsRo.InitTemplate();
|
||||
// 完成“动物密友”任务文字图像裁剪范围为83, 253, 84, 21。投喂完成几乎是可以立即检测到,持续时间约3000毫秒。
|
||||
const finishedFriendToAnimalsRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/动物密友完成.png'), 30, 240, 150, 400);
|
||||
// “动物密友突发事件”图像的裁剪范围为892, 167, 136, 37,该图像在登陆完成后的1500-5500毫秒的时间内存在
|
||||
const randomEventRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/突发事件.png'), 832, 151, 256, 69);
|
||||
// “动物密友突发事件”图像的裁剪范围为892, 167, 136, 37。投喂完成后约1500毫秒后可以检测到,持续时间约3500毫秒
|
||||
const finishedRandomEventRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/事件完成.png'), 832, 151, 256, 69);
|
||||
|
||||
// “投喂”图像的裁剪范围为1221, 525, 60, 28
|
||||
const feedRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/投喂.png'), 1215, 523, 72, 32);
|
||||
// “确认”按钮完整裁剪范围为978, 725, 372, 64,图像裁剪范围为1012, 736, 200, 42
|
||||
const confirmRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/确认.png'), 978, 725, 372, 64);
|
||||
// “禽肉数量”裁剪范围为945, 540, 14, 18
|
||||
const zeroFowlRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/禽肉数量.png'), 940, 535, 40, 28);
|
||||
|
||||
// 事件奖励的摩拉图标裁剪范围:124, 602, 21, 21。确认投喂后约2500毫秒后可以检测到,持续时间约2500毫秒
|
||||
const moraRo = RecognitionObject.TemplateMatch(file.ReadImageMatSync('assets/摩拉.png'), 61, 500, 300, 300);
|
||||
|
||||
// 监测是否联机,若联机则退出联机状态
|
||||
async function ensureSinglePlayerMode() {
|
||||
let gameRegion;
|
||||
let result;
|
||||
let exists;
|
||||
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(coOpModeRo);
|
||||
gameRegion.dispose();
|
||||
exists = result.isExist();
|
||||
result.dispose();
|
||||
if (exists) {
|
||||
log.info("单人模式");
|
||||
return true;
|
||||
} else {
|
||||
log.info("多人游戏中,尝试回到单人模式");
|
||||
await genshin.tp(-4492, -3208, "Teyvat", true);
|
||||
await sleep(1500);
|
||||
keyPress("F2");
|
||||
await sleep(1500);
|
||||
gameRegion = captureGameRegion();
|
||||
let result1 = gameRegion.find(singlePlayer1Ro);
|
||||
let result2 = gameRegion.find(singlePlayer2Ro);
|
||||
gameRegion.dispose();
|
||||
if (result1.isExist()) {
|
||||
result1.click();
|
||||
await sleep(1500);
|
||||
gameRegion = captureGameRegion();
|
||||
result1.dispose();
|
||||
result1 = gameRegion.find(singlePlayer1ConfirmRo);
|
||||
gameRegion.dispose();
|
||||
if (result1.isExist()) {
|
||||
result1.click();
|
||||
log.info("回到单人模式");
|
||||
}
|
||||
} else if (result2.isExist()) {
|
||||
result2.click();
|
||||
log.info("回到单人模式");
|
||||
}
|
||||
|
||||
try {
|
||||
await genshin.tp(TELEPORT_COORDS.x, TELEPORT_COORDS.y);
|
||||
await sleep(3000);
|
||||
log.info(`正在尝试切换至:${partyName}`);
|
||||
await genshin.switchParty(partyName);
|
||||
log.info(`队伍切换成功,继续下一步任务`);
|
||||
} catch (error) {
|
||||
log.warn("队伍切换失败,可能处于联机模式或其他不可切换状态");
|
||||
await genshin.returnMainUi();
|
||||
}
|
||||
}
|
||||
async function Feed() {
|
||||
await sleep(500);
|
||||
keyPress("F");
|
||||
await sleep(500);
|
||||
keyPress("F");
|
||||
await sleep(1000);
|
||||
click(1010, 760);
|
||||
await sleep(1000);
|
||||
}
|
||||
|
||||
async function AutoPath(locationName) {
|
||||
try {
|
||||
const filePath = `assets/AutoPath/${locationName}.json`;
|
||||
await pathingScript.runFile(filePath);
|
||||
} catch (error) {
|
||||
log.error(`执行 ${locationName} 路径时发生错误: ${error.message}`);
|
||||
}
|
||||
result1.dispose();
|
||||
result2.dispose();
|
||||
await sleep(2000);
|
||||
}
|
||||
await genshin.returnMainUi();
|
||||
|
||||
async function OcrF() {
|
||||
let capture = await captureGameRegion();
|
||||
let ocr = await capture.find(RecognitionObject.ocrThis);
|
||||
capture.dispose();
|
||||
if (ocr.text.includes('投喂')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function AutoFriendshipDev(times) {
|
||||
|
||||
log.info(`导航至甜甜花位置`);
|
||||
await AutoPath('导航至甜甜花位置');
|
||||
await AutoPath('到甜甜花');
|
||||
await genshin.relogin();
|
||||
log.info(`自动好感开始...`);
|
||||
const startFirstTime = Date.now();
|
||||
for (let i = 0; i < times; i++) {
|
||||
log.info(`自动好感当前次数:${i + 1}/${times}`);
|
||||
await AutoPath('到狗盆');
|
||||
for (let j = 0; j < 3 && !await OcrF(); j++) {
|
||||
await AutoPath('到狗盆');
|
||||
}
|
||||
await Feed();
|
||||
if (i != times - 1) {
|
||||
await AutoPath('到甜甜花');
|
||||
await AutoPath('到甜甜花');
|
||||
await genshin.relogin();
|
||||
} //最后一次不需要返回到甜甜花
|
||||
const estimatedCompletion = CalculateEstimatedCompletion(startFirstTime, i + 1, times);
|
||||
const currentTime = LogTimeTaken(startFirstTime);
|
||||
log.info(`当前进度:${i + 1}/${times} (${((i + 1) / times * 100).toFixed(1)}%)`);
|
||||
log.info(`当前运行总时长:${currentTime}`);
|
||||
log.info(`预计完成时间:${estimatedCompletion}`);
|
||||
//切换队伍
|
||||
async function switchPartyIfNeeded(partyName) {
|
||||
if (!partyName) {
|
||||
await genshin.returnMainUi();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
log.info(`正在尝试切换至: ${partyName}`);
|
||||
if (!(await genshin.switchParty(partyName))) {
|
||||
throw new Error("切换失败");
|
||||
}
|
||||
log.info('自动好感已完成');
|
||||
log.info(`成功切换至: ${partyName}`);
|
||||
} catch {
|
||||
log.error("队伍切换失败,可能处于联机模式或其他不可切换状态");
|
||||
await genshin.returnMainUi();
|
||||
}
|
||||
}
|
||||
|
||||
//判断好感突发事件是否触发
|
||||
async function randomEventTriggered() {
|
||||
let index;
|
||||
let gameRegion;
|
||||
let result;
|
||||
let exists;
|
||||
|
||||
await sleep(300);
|
||||
|
||||
for (index = 0; index < 10; index++) {
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(friendToAnimalsRo);
|
||||
gameRegion.dispose();
|
||||
exists = result.isExist();
|
||||
result.dispose();
|
||||
if (!exists) { await sleep(100); }
|
||||
else { return true; }
|
||||
}
|
||||
for (index = 0; index < 10; index++) {
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(randomEventRo);
|
||||
gameRegion.dispose();
|
||||
exists = result.isExist();
|
||||
result.dispose();
|
||||
if (!exists) { await sleep(400); }
|
||||
else { return true; }
|
||||
}
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(friendToAnimalsRo);
|
||||
gameRegion.dispose();
|
||||
exists = result.isExist();
|
||||
result.dispose();
|
||||
if (exists) { return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 判断投喂后是否完成事件
|
||||
async function finishedEvent() {
|
||||
let index;
|
||||
let gameRegion;
|
||||
let result;
|
||||
let exists;
|
||||
|
||||
for (index = 0; index < 10; index++) {
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(finishedFriendToAnimalsRo);
|
||||
gameRegion.dispose();
|
||||
exists = result.isExist();
|
||||
result.dispose();
|
||||
if (!exists) { await sleep(100); }
|
||||
else { return true; }
|
||||
}
|
||||
|
||||
function LogTimeTaken(startTimeParam) {
|
||||
const currentTime = Date.now();
|
||||
const totalTimeInSeconds = (currentTime - startTimeParam) / 1000;
|
||||
const minutes = Math.floor(totalTimeInSeconds / 60);
|
||||
const seconds = totalTimeInSeconds % 60;
|
||||
const formattedTime = `${minutes} 分 ${seconds.toFixed(0).padStart(2, '0')} 秒`;
|
||||
return formattedTime;
|
||||
for (index = 0; index < 10; index++) {
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(finishedRandomEventRo);
|
||||
gameRegion.dispose();
|
||||
exists = result.isExist();
|
||||
result.dispose();
|
||||
if (!exists) { await sleep(100); }
|
||||
else { return true; }
|
||||
}
|
||||
|
||||
// 计算预估时间
|
||||
function CalculateEstimatedCompletion(startTime, current, total) {
|
||||
if (current === 0) return "计算中...";
|
||||
return false;
|
||||
}
|
||||
|
||||
const elapsedTime = Date.now() - startTime;
|
||||
const timePerTask = elapsedTime / current;
|
||||
const remainingTasks = total - current;
|
||||
const remainingTime = timePerTask * remainingTasks;
|
||||
const completionDate = new Date(Date.now() + remainingTime);
|
||||
return `${completionDate.toLocaleTimeString()} (约 ${Math.round(remainingTime / 60000)} 分钟)`;
|
||||
// 识别奖励
|
||||
async function hasEventReward() {
|
||||
let index;
|
||||
let gameRegion;
|
||||
let result;
|
||||
let exists;
|
||||
|
||||
for (index = 0; index < 50; index++) {
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(moraRo);
|
||||
gameRegion.dispose();
|
||||
exists = result.isExist();
|
||||
result.dispose();
|
||||
if (!exists) { await sleep(100); }
|
||||
else { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 寻找“投喂”,按下F,点击“确认”按钮,完成投喂
|
||||
async function feedDog() {
|
||||
let gameRegion;
|
||||
let result;
|
||||
let exists;
|
||||
let retry;
|
||||
|
||||
retry = 0;
|
||||
await sleep(200); // 等待角色站稳,避免二次调整位置
|
||||
do {
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(feedRo);
|
||||
gameRegion.dispose();
|
||||
exists = result.isExist();
|
||||
result.dispose();
|
||||
if (!exists) {
|
||||
if (++retry > 5) {
|
||||
log.error("多次尝试仍未识别到“投喂”,结束任务");
|
||||
return false;
|
||||
}
|
||||
await pathingScript.runFile("assets/pathing/鸡腿好感_狗盆点位.json");
|
||||
} else { keyPress("F"); }
|
||||
} while (!exists);
|
||||
|
||||
await sleep(1000);
|
||||
gameRegion = captureGameRegion();
|
||||
result = gameRegion.find(confirmRo);
|
||||
try {
|
||||
if (result.isExist()) { result.click(); }
|
||||
else {
|
||||
log.error("未识别到可交互的确认按钮");
|
||||
result.dispose();
|
||||
result = gameRegion.find(zeroFowlRo);
|
||||
keyPress("Escape");
|
||||
await sleep(1000);
|
||||
await genshin.returnMainUi();
|
||||
if (result.isExist()) { log.error("禽肉数量为0,无法完成任务"); }
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
result.dispose();
|
||||
gameRegion.dispose();
|
||||
}
|
||||
|
||||
function isPositiveInteger(value) {
|
||||
value = Number(value);
|
||||
return Number.isInteger(value) && value > 0;
|
||||
}
|
||||
// 启用自动拾取的实时任务
|
||||
const startTime = Date.now();
|
||||
dispatcher.addTimer(new RealtimeTimer("AutoPick"));
|
||||
return true;
|
||||
}
|
||||
|
||||
const messages = [
|
||||
'请确保有足够的鸡腿',
|
||||
'请确保队伍满员',
|
||||
];
|
||||
for (let message of messages) {
|
||||
log.info(message);
|
||||
await sleep(500);
|
||||
// 检查“投喂”的结果
|
||||
async function checkFeed() {
|
||||
if (await finishedEvent()) {
|
||||
feedCount++;
|
||||
log.info("投喂成功");
|
||||
if (feedCount >= 10) {
|
||||
log.info("10次投喂完成");
|
||||
finished = true;
|
||||
return true;
|
||||
}
|
||||
if (!(await hasEventReward())) {
|
||||
log.info("投喂成功后未识别到奖励,当日突发事件奖励已达上限");
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let retry;
|
||||
|
||||
// 等待返回主界面
|
||||
await genshin.returnMainUi();
|
||||
// 强制传送,避免在奇奇怪怪的地方,例如“银月之庭”
|
||||
await genshin.tp(-4492, -3208, "Teyvat", true);
|
||||
// 判断是否为联机模式,通过模拟点击回到单人模式
|
||||
while (!(await ensureSinglePlayerMode())) { await sleep(500); }
|
||||
// 移动到任务刷新点
|
||||
await pathingScript.runFile("assets/pathing/鸡腿好感_初始化.json");
|
||||
// 判断是否设置了好感队,切换队伍
|
||||
await switchPartyIfNeeded(settings.partyName);
|
||||
|
||||
log.info('自动好感开始...');
|
||||
//默认10次自动好感
|
||||
if (isPositiveInteger(settings.times)) {
|
||||
log.info(`自动好感任务开始,运行:${settings.times} 次`);
|
||||
await AutoFriendshipDev(settings.times);
|
||||
} else {
|
||||
log.info(`运行次数输入不合法或者未输入,使用默认值`);
|
||||
times = 10;
|
||||
log.info(`自动好感任务开始,运行:${times} 次`);
|
||||
await AutoFriendshipDev(10);
|
||||
retry = 0;
|
||||
const startTime = Date.now();
|
||||
// 任务循环
|
||||
task: while (!finished) {
|
||||
// 重新登陆,刷新任务
|
||||
await genshin.relogin();
|
||||
// 检测“动物密友”任务是否触发,若未触发则重新登陆触发
|
||||
if (!(await randomEventTriggered())) {
|
||||
if (++retry > 5) {
|
||||
log.error("多次尝试触发突发事件失败,结束任务");
|
||||
break;
|
||||
}
|
||||
await pathingScript.runFile("assets/pathing/鸡腿好感_甜甜花点位.json");
|
||||
continue;
|
||||
} else { retry = 0; }
|
||||
// 前往狗盆
|
||||
await pathingScript.runFile("assets/pathing/鸡腿好感_喂狗.json");
|
||||
// 等待投喂
|
||||
if (!(await feedDog())) { break; }
|
||||
// 异步检查投喂结果
|
||||
const checkFeedPromise = checkFeed();
|
||||
// 返回前判断任务是否已完成,减少时间
|
||||
for (let index = 0; index < 10; index++) {
|
||||
if (finished) { break task; }
|
||||
await sleep(10);
|
||||
}
|
||||
// 返回甜甜花
|
||||
await pathingScript.runFile("assets/pathing/鸡腿好感_返回.json");
|
||||
// 计算剩余时间
|
||||
if (feedCount > 0) {
|
||||
const remainingTime = (Date.now() - startTime) / feedCount * (10 - feedCount) / 1000;
|
||||
const remainingMinutes = Math.floor(remainingTime / 60);
|
||||
const remainingSeconds = remainingTime % 60;
|
||||
log.info(`当前进度:第 ${feedCount}/10 次已完成,预计剩余时间:${remainingMinutes} 分 ${remainingSeconds.toFixed(0)} 秒`);
|
||||
}
|
||||
await checkFeedPromise;
|
||||
}
|
||||
log.info(`自动好感运行总时长:${LogTimeTaken(startTime)}`);
|
||||
})();
|
||||
log.info("好感任务结束");
|
||||
}
|
||||
|
||||
(async function () {
|
||||
await main();
|
||||
})();
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "鸡腿好感",
|
||||
"version": "1.4",
|
||||
"version": "1.5",
|
||||
"tags": [
|
||||
"好感",
|
||||
"突发事件"
|
||||
],
|
||||
"bgi_version": "0.44.0",
|
||||
"description": "通过喂狗突发事件刷好感度,确保队伍满员,4个角色都能刷,每天上限10次",
|
||||
"bgi_version": "0.45.0",
|
||||
"description": "消耗禽肉喂狗,完成“动物密友”好感任务,获取角色好感、摩拉、锻造矿。确保队伍满员,每天最多10次。",
|
||||
"authors": [
|
||||
{
|
||||
"name": "花火"
|
||||
@@ -15,6 +15,10 @@
|
||||
{
|
||||
"name": "秋云",
|
||||
"links": "https://github.com/physligl"
|
||||
},
|
||||
{
|
||||
"name": "Gedley",
|
||||
"link": "https://github.com/Gedley"
|
||||
}
|
||||
],
|
||||
"settings_ui": "settings.json",
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
[
|
||||
{
|
||||
"name": "times",
|
||||
"type": "input-text",
|
||||
"label": "(选填)运行次数【默认10,为避免失败可以酌情添加次数】"
|
||||
},
|
||||
{
|
||||
"name": "partyName",
|
||||
"type": "input-text",
|
||||
"label": "(选填)需要切换的队伍名称【前往设置的七天神像切换好感队】"
|
||||
"label": "好感队的队伍名称,若未设置则使用当前队伍"
|
||||
}
|
||||
]
|
||||