Files
better-genshin-impact/BetterGenshinImpact/GameTask/AutoPathing/Handler/PickUpCollectHandler.cs

239 lines
9.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Threading;
using System.Threading.Tasks;
using BetterGenshinImpact.GameTask.AutoPathing.Model;
using Microsoft.Extensions.Logging;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
using BetterGenshinImpact.GameTask.AutoFight.Model;
using BetterGenshinImpact.GameTask.AutoFight.Script;
using System.Linq;
using System.Collections.Generic;
using BetterGenshinImpact.GameTask.AutoFight.Config;
namespace BetterGenshinImpact.GameTask.AutoPathing.Handler;
/// <summary>
/// 使用万叶或琴团通过战技吸取拾取物品,优先万叶,如果没有万叶则使用琴团
/// </summary>
public class PickUpCollectHandler : IActionHandler
{
/// <summary>
/// 新增命令时,以角色名称开头(必填),“-”后定义动作(必填,用于预解析,不能单写角色名称),空格后定义参数(必填)
/// 1、"action": "pick_up_collect","action_params":为空或不填在队伍中寻找CharacterNames中第一个找到的角色找到就会执行PickUpActions第一个找到的相关角色命令。
/// 2、"action": "pick_up_collect","action_params":"琴"只填角色名称或别名会执行PickUpActions第一个找到的相关角色命令。
/// 3、"action": "pick_up_collect","action_params":"琴-短E"填了具体角色和动作直接找PickUpActions找到该命令执行。
/// </summary>
public static readonly string[] PickUpActions =
[
"枫原万叶-长E keydown(E),wait(0.7),keyup(E),attack(0.2),wait(0.5)",
"枫原万叶-短E e,attack(0.15)",
"琴-短E wait(0.1),keydown(E),wait(0.4),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,0),wait(0.2),moveby(1000,-3500),wait(1.8),keyup(E),wait(0.3),click(middle)",
"琴-长E wait(0.1),click(middle),keydown(E),click(middle),wait(0.4),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1)," +
"moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1)," +
"moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1)," +
"moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1)," +
"moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1)," +
"moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1)," +
"moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1)," +
"moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),wait(0.1)," +
"moveby(500,0),wait(0.1),moveby(500,0),wait(0.1),moveby(500,0),moveby(1000,3500),wait(1.8),keyup(E),wait(0.3),click(middle),wait(0.3)",
];
// 预解析所有角色名
private static readonly HashSet<string> CharacterNames = new HashSet<string>(
PickUpActions
.Select(action => action.Split(' ')[0])
.Select(GetBaseCharacterName)
.Distinct()
);
public async Task RunAsync(CancellationToken ct, WaypointForTrack? waypointForTrack = null, object? config = null)
{
Logger.LogInformation("简易策略:执行 {Nhd} 动作","聚集材料");
var combatScenes = await RunnerContext.Instance.GetCombatScenes(ct);
if (combatScenes == null)
{
Logger.LogError("队伍识别未初始化成功!");
return;
}
Avatar? picker = null;
var commandsList = new List<string>();
if (waypointForTrack != null)
{
if (!string.IsNullOrEmpty(waypointForTrack.ActionParams))
{
var commands = waypointForTrack.ActionParams.Split(',');
foreach (var command in commands)
{
try
{
var alias = DefaultAutoFightConfig.AvatarAliasToStandardName(command);
commandsList.Add(!string.IsNullOrEmpty(alias) ? alias : command);
}
catch (Exception e)
{
commandsList.Add(command);
Console.WriteLine(e);
}
}
}
else
{
// 1、ActionParams没填参数尝试选择如果找到后续会执行第一个找到该角色的相关命令
foreach (var characterName in CharacterNames)
{
var pickerNull = combatScenes.SelectAvatar(characterName);
if (pickerNull is null)
{
continue;
}
commandsList.Add(characterName);
break;
}
}
}
foreach (var commands in commandsList)
{
if (CharacterNames.Contains(commands))
{
picker = combatScenes.SelectAvatar(commands);
}
else
{
var characterName = GetCharacterName(commands);
picker = combatScenes.SelectAvatar(characterName);
}
if (picker is not null)
{
picker.TrySwitch();
await picker.WaitSkillCd(ct);
}
else
{
continue;
}
PickUpMaterial(combatScenes,commands); // 开始执行动作
}
}
/// <summary>
/// 执行聚集材料动作
/// <param name="combatScenes"></param>
/// <param name="pickerName"></param>
/// </summary>
private void PickUpMaterial(CombatScenes combatScenes, string? pickerName = null)
{
try
{
var foundAvatar = false;
string[] actionsToUse;
var characterName = string.Empty;
if (pickerName != null)
{
actionsToUse = PickUpActions.Where(action =>
action.StartsWith(pickerName + " ", StringComparison.OrdinalIgnoreCase)).ToArray();
if (actionsToUse.Length == 0)
{
if (CharacterNames.Contains(pickerName)) //2.只填了角色名则用基础角色名筛选执行pickerName相关的第一个命令
{
var actions = PickUpActions.FirstOrDefault(action => action.StartsWith(pickerName, StringComparison.OrdinalIgnoreCase));
actionsToUse = actions == null ? new string[0] : new string[] {actions};
// 替换第一个空格前的字符为 pickerName
if (actionsToUse.Length > 0 && actionsToUse[0].Contains(' '))
{
string action = actionsToUse[0];
int firstSpaceIndex = action.IndexOf(' ');
actionsToUse[0] = pickerName + action.Substring(firstSpaceIndex);
}
}
else
{
Logger.LogError($"未找到角色 {pickerName} 对应的动作");
return;
}
}
else
{
// 提取角色名称
characterName = GetCharacterName(pickerName);
// 3.填了具体命令,则用具体命令筛选,并将命令中的角色替换为角色名称
actionsToUse = actionsToUse
.Select(action => action.Replace(pickerName + " ", characterName + " ", StringComparison.OrdinalIgnoreCase))
.ToArray();
}
}
else
{
Logger.LogError("未找到ActionParams");
return;
}
foreach (var pickUpActionStr in actionsToUse)
{
var pickUpAction = CombatScriptParser.ParseContext(pickUpActionStr);
foreach (var command in pickUpAction.CombatCommands)
{
var avatar = combatScenes.SelectAvatar(command.Name);
if (avatar != null)
{
command.Execute(combatScenes);
foundAvatar = true;
}
}
if (foundAvatar)
{
var selectedAvatar = combatScenes.SelectAvatar(characterName);
if (selectedAvatar is not null)
{
Sleep(200);//等待CD显示
selectedAvatar.AfterUseSkill();
}
break;
}
}
}
catch (Exception ex)
{
// 处理异常
Console.WriteLine($"PickUpCollectHandler 异常: {ex.Message}");
}
}
// 直接匹配预解析的角色名
private static string GetCharacterName(string pickerName)
{
foreach (var name in CharacterNames)
{
if (pickerName.StartsWith(name))
return name;
}
return pickerName;
}
/// <summary>
/// 从完整动作名提取基础角色名
/// </summary>
private static string GetBaseCharacterName(string fullActionName)
{
// 找到第一个"-"号的位置
var dashIndex = fullActionName.IndexOf('-');
// 如果存在"-"号,则返回"-"号前的部分
return dashIndex > 0 ? fullActionName.Substring(0, dashIndex) : string.Empty;
}
}