mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-15 07:43:20 +08:00
feat: 添加round指令支持按轮次激活部分战斗宏脚本 (#2597)
This commit is contained in:
@@ -167,9 +167,10 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
|
||||
{
|
||||
return new Task(() =>
|
||||
{
|
||||
Logger.LogInformation("→ {Name}执行宏", activeAvatar.Name);
|
||||
var round = 1;
|
||||
while (!ct.IsCancellationRequested && IsEnabled())
|
||||
{
|
||||
Logger.LogInformation("→ {Name}执行宏 (第{Round}轮)", activeAvatar.Name, round);
|
||||
if (IsHoldOnMode() && !_isKeyDown)
|
||||
{
|
||||
break;
|
||||
@@ -178,8 +179,14 @@ public class OneKeyFightTask : Singleton<OneKeyFightTask>
|
||||
// 通用化战斗策略
|
||||
foreach (var command in combatCommands)
|
||||
{
|
||||
if (command.ActivatingRound != null && command.ActivatingRound.Count > 0 && !command.ActivatingRound.Contains(round))
|
||||
{
|
||||
// 跳过强制首轮指令
|
||||
continue;
|
||||
}
|
||||
command.Execute(activeAvatar);
|
||||
}
|
||||
round++;
|
||||
}
|
||||
|
||||
Logger.LogInformation("→ {Name}停止宏", activeAvatar.Name);
|
||||
|
||||
@@ -14,6 +14,8 @@ public class CombatCommand
|
||||
|
||||
public List<string>? Args { get; set; }
|
||||
|
||||
public List<int> ActivatingRound { get; set; }
|
||||
|
||||
public CombatCommand(string name, string command)
|
||||
{
|
||||
Name = name.Trim();
|
||||
@@ -63,6 +65,11 @@ public class CombatCommand
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"<CombatCommand {Name}, {Method}({Args}) (rounds {ActivatingRound})>";
|
||||
}
|
||||
|
||||
public void Execute(CombatScenes combatScenes, CombatCommand? lastCommand = null)
|
||||
{
|
||||
@@ -264,6 +271,10 @@ public class CombatCommand
|
||||
{
|
||||
avatar.KeyPress(Args![0]);
|
||||
}
|
||||
else if (Method == Method.Round)
|
||||
{
|
||||
// 作为回合标记使用,不做任何操作
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
@@ -131,7 +131,70 @@ public class CombatScriptParser
|
||||
return oneLineCombatCommands;
|
||||
}
|
||||
|
||||
public static List<CombatCommand> ParseLineCommands(string lineWithoutAvatar, string avatarName)
|
||||
public static List<int> ParseRoundCommand(CombatCommand roundCommand) {
|
||||
// 解析round命令的入参,返回一个整数列表,代表在哪些回合执行后续指令
|
||||
// 支持Round(1)、Round(1,3,5)、Round(2-4)、Round(1,3-5)等格式
|
||||
var activatingRounds = new List<int>();
|
||||
if (roundCommand.Args == null || roundCommand.Args.Count == 0) {
|
||||
Logger.LogError("round方法必须有入参,代表在哪些回合执行后续指令,例:round(1)、round(1,3-5)");
|
||||
throw new ArgumentException("round方法必须有入参,代表在哪些回合执行后续指令,例:round(1)、round(1,3-5)");
|
||||
}
|
||||
foreach (var arg in roundCommand.Args) {
|
||||
if (arg.Contains('-')) {
|
||||
// 范围
|
||||
var parts = arg.Split('-', StringSplitOptions.TrimEntries);
|
||||
if (parts.Length != 2) {
|
||||
Logger.LogError("round方法的入参格式错误,例:round(1-3)");
|
||||
throw new ArgumentException("round方法的入参格式错误,例:round(1-3)");
|
||||
}
|
||||
var start = int.Parse(parts[0]);
|
||||
var end = int.Parse(parts[1]);
|
||||
if (start > end || start <= 0) {
|
||||
Logger.LogError("round方法的入参格式错误,起始回合必须小于等于结束回合且大于0,例:round(1-3)");
|
||||
throw new ArgumentException("round方法的入参格式错误,起始回合必须小于等于结束回合且大于0,例:round(1-3)");
|
||||
}
|
||||
for (int i = start; i <= end; i++) {
|
||||
activatingRounds.Add(i);
|
||||
}
|
||||
} else {
|
||||
// 单个回合
|
||||
var round = int.Parse(arg);
|
||||
if (round <= 0) {
|
||||
Logger.LogError("round方法的入参格式错误,回合数必须大于0,例:round(1)");
|
||||
throw new ArgumentException("round方法的入参格式错误,回合数必须大于0,例:round(1)");
|
||||
}
|
||||
activatingRounds.Add(round);
|
||||
}
|
||||
}
|
||||
return activatingRounds;
|
||||
}
|
||||
|
||||
public static List<CombatCommand> ParseLineCommands(string lineWithoutAvatar, string avatarName) {
|
||||
var parts = lineWithoutAvatar.Split("|", StringSplitOptions.RemoveEmptyEntries);
|
||||
var fullCombatCommands = new List<CombatCommand>();
|
||||
foreach (var part in parts)
|
||||
{
|
||||
var combatCommands = ParseLinePart(part, avatarName);
|
||||
if (combatCommands.Count > 0 && combatCommands[0].Method == Method.Round) {
|
||||
// 遇到round指令,作为回合分隔符使用,不加入最终指令列表
|
||||
var roundCommand = combatCommands[0];
|
||||
var activatingRounds = ParseRoundCommand(roundCommand);
|
||||
combatCommands.RemoveAt(0);
|
||||
foreach (var combatCommand in combatCommands) {
|
||||
|
||||
combatCommand.ActivatingRound = activatingRounds;
|
||||
}
|
||||
}
|
||||
fullCombatCommands.AddRange(combatCommands);
|
||||
}
|
||||
foreach (var combatCommand in fullCombatCommands)
|
||||
{
|
||||
Logger.LogDebug("解析战斗脚本命令:{cmd}", combatCommand.ToString());
|
||||
}
|
||||
return fullCombatCommands;
|
||||
}
|
||||
|
||||
public static List<CombatCommand> ParseLinePart(string lineWithoutAvatar, string avatarName)
|
||||
{
|
||||
var oneLineCombatCommands = new List<CombatCommand>();
|
||||
var commandArray = lineWithoutAvatar.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
@@ -31,6 +31,7 @@ public class Method
|
||||
public static readonly Method KeyDown = new(["keydown"]);
|
||||
public static readonly Method KeyUp = new(["keyup"]);
|
||||
public static readonly Method KeyPress = new(["keypress"]);
|
||||
public static readonly Method Round = new(["round"]);
|
||||
|
||||
public static IEnumerable<Method> Values
|
||||
{
|
||||
@@ -60,6 +61,7 @@ public class Method
|
||||
yield return KeyDown;
|
||||
yield return KeyUp;
|
||||
yield return KeyPress;
|
||||
yield return Round;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user