mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-27 10:15:50 +08:00
优化项目结构并新增任务和路径文件 主要更改: - 在 `BetterGenshinImpact.csproj` 文件中,添加了对 `GameTask\Common\Element\Assets\Json\**` 目录的处理,并确保其内容始终复制到输出目录。 - 在 `RecognitionObject.cs` 文件中,新增了多个静态方法 `Ocr` 和一个静态实例 `OcrThis`。 - 在 `PathExecutor.cs` 文件中,优化了路径执行逻辑,新增 `GetPosition` 方法,并调整了超时判断。 - 在 `AutoPickAssets.cs` 文件中,添加了多个 `using` 语句,新增 `_logger` 和 `PickRo` 字段,并在构造函数中添加了自定义拾取按键的处理逻辑。 - 在 `AutoPickTrigger.cs` 文件中,移除了自定义拾取按键的初始化逻辑。 - 在 `OneKeyExpeditionTask.cs` 文件中,注释掉了 `Cv2.ImWrite` 方法的调用。 - 在 `TpTask.cs` 文件中,添加了点位很近时不切换的判断逻辑。 - 在 `BvSimpleOperation.cs` 文件中,新增了多个点击按钮的方法和 `FindF`、`FindFAndPress` 方法。 - 在 `BvStatus.cs` 文件中,新增了多个方法用于判断是否在对话界面并等待对话界面加载完成。 - 在 `GameTaskManager.cs` 文件中,添加了 `MapAssets.DestroyInstance` 方法的调用。 - 在 `HotKeyPageViewModel.cs` 文件中,注释掉了 `ElementalCollectHandler` 的测试代码,并添加了 `GoToAdventurersGuildTask` 的测试代码。 - 在 `TaskSettingsPageViewModel.cs` 文件中,更新了 `OnGoToAutoGeniusInvokationUrlAsync` 方法中的 URL。 - 添加了 `BetterGenshinImpact - Backup.csproj` 文件,配置了项目属性、资源文件和包引用。 - 添加了 `冒险家协会_枫丹.json`、`合成台_枫丹.json` 和 `合成台_璃月.json` 文件,定义了前往相应地点的路径和动作。 - 添加了 `ChooseTalkOptionTask.cs` 文件,实现了选择对话选项的任务。 - 添加了 `GoToAdventurersGuildTask.cs` 文件,实现了前往冒险家协会领取奖励的任务。
218 lines
6.5 KiB
C#
218 lines
6.5 KiB
C#
using BetterGenshinImpact.GameTask.Common.Element.Assets;
|
|
using BetterGenshinImpact.GameTask.Model.Area;
|
|
using BetterGenshinImpact.GameTask.QuickTeleport.Assets;
|
|
using OpenCvSharp;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using BetterGenshinImpact.Core.Recognition;
|
|
using BetterGenshinImpact.Core.Simulator;
|
|
using BetterGenshinImpact.GameTask.AutoFight;
|
|
using Vanara.PInvoke;
|
|
using System.Threading;
|
|
using BetterGenshinImpact.GameTask.AutoSkip.Assets;
|
|
using BetterGenshinImpact.GameTask.GameLoading.Assets;
|
|
|
|
namespace BetterGenshinImpact.GameTask.Common.BgiVision;
|
|
|
|
/// <summary>
|
|
/// 模仿OpenCv的静态类
|
|
/// 用于原神的各类识别与控制操作
|
|
///
|
|
/// 此处主要是对游戏内的一些状态进行识别
|
|
/// </summary>
|
|
public static partial class Bv
|
|
{
|
|
public static string WhichGameUi()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否在主界面
|
|
/// </summary>
|
|
/// <param name="captureRa"></param>
|
|
/// <returns></returns>
|
|
public static bool IsInMainUi(ImageRegion captureRa)
|
|
{
|
|
return captureRa.Find(ElementAssets.Instance.PaimonMenuRo).IsExist();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 等待主界面加载完成
|
|
/// </summary>
|
|
/// <param name="ct"></param>
|
|
/// <param name="retryTimes"></param>
|
|
/// <returns></returns>
|
|
public static async Task<bool> WaitForMainUi(CancellationToken ct, int retryTimes = 10)
|
|
{
|
|
for (var i = 0; i < retryTimes; i++)
|
|
{
|
|
await TaskControl.Delay(1000, ct);
|
|
using var ra3 = TaskControl.CaptureToRectArea();
|
|
if (IsInMainUi(ra3))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否在队伍选择界面
|
|
/// </summary>
|
|
/// <param name="captureRa"></param>
|
|
/// <returns></returns>
|
|
public static bool IsInPartyViewUi(ImageRegion captureRa)
|
|
{
|
|
return captureRa.Find(ElementAssets.Instance.PartyBtnChooseView).IsExist();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 等待队伍选择界面加载完成
|
|
/// </summary>
|
|
/// <param name="ct"></param>
|
|
/// <param name="retryTimes"></param>
|
|
/// <returns></returns>
|
|
public static async Task<bool> WaitForPartyViewUi(CancellationToken ct, int retryTimes = 5)
|
|
{
|
|
return await NewRetry.WaitForAction(() => IsInPartyViewUi(TaskControl.CaptureToRectArea()), ct, retryTimes);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否在大地图界面
|
|
/// </summary>
|
|
/// <param name="captureRa"></param>
|
|
/// <returns></returns>
|
|
public static bool IsInBigMapUi(ImageRegion captureRa)
|
|
{
|
|
return captureRa.Find(QuickTeleportAssets.Instance.MapScaleButtonRo).IsExist();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 大地图界面是否在地底
|
|
/// 鼠标悬浮在地下图标或者处于切换动画的时候可能会误识别
|
|
/// </summary>
|
|
/// <param name="captureRa"></param>
|
|
/// <returns></returns>
|
|
public static bool BigMapIsUnderground(ImageRegion captureRa)
|
|
{
|
|
return captureRa.Find(QuickTeleportAssets.Instance.MapUndergroundSwitchButtonRo).IsExist();
|
|
}
|
|
|
|
public static MotionStatus GetMotionStatus(ImageRegion captureRa)
|
|
{
|
|
var spaceExist = captureRa.Find(ElementAssets.Instance.SpaceKey).IsExist();
|
|
var xExist = captureRa.Find(ElementAssets.Instance.XKey).IsExist();
|
|
if (spaceExist)
|
|
{
|
|
return xExist ? MotionStatus.Climb : MotionStatus.Fly;
|
|
}
|
|
else
|
|
{
|
|
return MotionStatus.Normal;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否出现复苏提示
|
|
/// </summary>
|
|
/// <param name="region"></param>
|
|
/// <returns></returns>
|
|
public static bool IsInRevivePrompt(ImageRegion region)
|
|
{
|
|
using var confirmRectArea = region.Find(AutoFightContext.Instance.FightAssets.ConfirmRa);
|
|
if (!confirmRectArea.IsEmpty())
|
|
{
|
|
var list = region.FindMulti(new RecognitionObject
|
|
{
|
|
RecognitionType = RecognitionTypes.Ocr,
|
|
RegionOfInterest = new Rect(0, 0, region.Width, region.Height / 2)
|
|
});
|
|
if (list.Any(r => r.Text.Contains("复苏")))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否出现全队死亡和复苏提示
|
|
/// </summary>
|
|
/// <param name="region"></param>
|
|
/// <returns></returns>
|
|
public static bool ClickIfInReviveModal(ImageRegion region)
|
|
{
|
|
var list = region.FindMulti(new RecognitionObject
|
|
{
|
|
RecognitionType = RecognitionTypes.Ocr,
|
|
RegionOfInterest = new Rect(0, region.Height / 4 * 3, region.Width, region.Height / 4)
|
|
});
|
|
var r = list.FirstOrDefault(r => r.Text.Contains("复苏"));
|
|
if (r != null)
|
|
{
|
|
r.Click();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 当前角色是否低血量
|
|
/// </summary>
|
|
/// <param name="captureRa"></param>
|
|
/// <returns></returns>
|
|
public static bool CurrentAvatarIsLowHp(ImageRegion captureRa)
|
|
{
|
|
var assetScale = TaskContext.Instance().SystemInfo.AssetScale;
|
|
|
|
// 获取 (808, 1010) 位置的像素颜色
|
|
var pixelColor = captureRa.SrcMat.At<Vec3b>((int)(1010 * assetScale), (int)(808 * assetScale));
|
|
|
|
// 判断颜色是否是 (255, 90, 90)
|
|
return pixelColor is { Item2: 255, Item1: 90, Item0: 90 };
|
|
}
|
|
|
|
/// <summary>
|
|
/// 在空月祝福界面
|
|
/// </summary>
|
|
/// <param name="captureRa"></param>
|
|
/// <returns></returns>
|
|
public static bool IsInBlessingOfTheWelkinMoon(ImageRegion captureRa)
|
|
{
|
|
return captureRa.Find(GameLoadingAssets.Instance.WelkinMoonRo).IsExist();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否在对话界面
|
|
/// </summary>
|
|
/// <param name="captureRa"></param>
|
|
/// <returns></returns>
|
|
public static bool IsInTalkUi(ImageRegion captureRa)
|
|
{
|
|
return captureRa.Find(AutoSkipAssets.Instance.DisabledUiButtonRo).IsExist();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 等到对话界面加载完成
|
|
/// </summary>
|
|
/// <param name="ct"></param>
|
|
/// <param name="retryTimes"></param>
|
|
/// <returns></returns>
|
|
public static async Task<bool> WaitAndSkipForTalkUi(CancellationToken ct, int retryTimes = 5)
|
|
{
|
|
return await NewRetry.WaitForAction(() => IsInTalkUi(TaskControl.CaptureToRectArea()), ct, retryTimes, 500);
|
|
}
|
|
}
|
|
|
|
public enum MotionStatus
|
|
{
|
|
Normal, // 正常
|
|
Fly, // 飞行
|
|
Climb, // 攀爬
|
|
}
|