feat: 添加round指令支持按轮次激活部分战斗宏脚本 (#2597)

This commit is contained in:
NyaMisty
2026-01-04 22:41:20 +08:00
committed by GitHub
parent d830dea328
commit 2174fc1b04
4 changed files with 85 additions and 2 deletions

View File

@@ -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);

View File

@@ -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();

View File

@@ -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方法的入参格式错误起始回合必须小于等于结束回合且大于0round(1-3)");
throw new ArgumentException("round方法的入参格式错误起始回合必须小于等于结束回合且大于0round(1-3)");
}
for (int i = start; i <= end; i++) {
activatingRounds.Add(i);
}
} else {
// 单个回合
var round = int.Parse(arg);
if (round <= 0) {
Logger.LogError("round方法的入参格式错误回合数必须大于0round(1)");
throw new ArgumentException("round方法的入参格式错误回合数必须大于0round(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);

View File

@@ -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;
}
}