Merge pull request #1036 from mfkvfhpdx/main

调整“按日锄地摩拉统计”为“按日摩拉收益统计”,并增加统计突发事件委托收益。
This commit is contained in:
辉鸭蛋
2025-01-21 22:47:09 +08:00
committed by GitHub
8 changed files with 156 additions and 8 deletions

View File

@@ -25,6 +25,13 @@ public partial class AutoFightConfig : ObservableObject
/// </summary>
[ObservableProperty]
private bool _fightFinishDetectEnabled = true;
/// <summary>
/// 根据技能CD优化出招人员
/// 根据填入人或人和cd来决定当此人元素战技cd未结束时跳过此人出招来优化战斗流程可填入人名或人名数字用逗号分隔
/// 多种用分号分隔,例如:白术;钟离,12;如果人名则用内置cd检查如果是人名和数字则把数字当做出招cd(秒)。
/// </summary>
[ObservableProperty] private string _actionSchedulerByCd = "";
[Serializable]
public partial class FightFinishDetectConfig : ObservableObject
{

View File

@@ -26,6 +26,7 @@ public class AutoFightParam : BaseTaskParam
FightFinishDetectEnabled = autoFightConfig.FightFinishDetectEnabled;
PickDropsAfterFightEnabled = autoFightConfig.PickDropsAfterFightEnabled;
KazuhaPickupEnabled = autoFightConfig.KazuhaPickupEnabled;
ActionSchedulerByCd = autoFightConfig.ActionSchedulerByCd;
FinishDetectConfig.FastCheckEnabled = autoFightConfig.FinishDetectConfig.FastCheckEnabled;
FinishDetectConfig.FastCheckParams = autoFightConfig.FinishDetectConfig.FastCheckParams;
@@ -47,6 +48,7 @@ public class AutoFightParam : BaseTaskParam
public int Timeout { get; set; } = 120;
public bool KazuhaPickupEnabled = true;
public string ActionSchedulerByCd = "";
}

View File

@@ -202,6 +202,7 @@ public class AutoFightTask : ISoloTask
throw new Exception("识别队伍角色失败");
}
var actionSchedulerByCd = ParseStringToDictionary(_taskParam.ActionSchedulerByCd);
var combatCommands = _combatScriptBag.FindCombatScript(combatScenes.Avatars);
// 新的取消token
@@ -221,7 +222,8 @@ public class AutoFightTask : ISoloTask
return;
}*/
var fightEndFlag = false;
string lastFighttName = "";
string lastFightName = "";
string skipFightName = "";
//统计切换人打架次数
var countFight = 0;
// 战斗操作
@@ -242,6 +244,30 @@ public class AutoFightTask : ISoloTask
break;
}
//根据元素技能冷却事件优化出招流程,只有当人物切换后才会触发检查
double skillCd;
if (lastFightName != command.Name && actionSchedulerByCd.TryGetValue(command.Name,out skillCd))
{
var avatar = combatScenes.Avatars.FirstOrDefault(a => a.Name == command.Name);
if (skillCd < 0)
{
skillCd = FindMax([avatar.SkillCd,avatar.SkillHoldCd]);
}
var dif=(DateTime.UtcNow - avatar.LastSkillTime);
//当技能未冷却时,跳过此次出招
if ((DateTime.UtcNow -avatar.LastSkillTime).TotalSeconds < skillCd)
{
if (skipFightName != command.Name)
{
Logger.LogInformation($"{command.Name}cd冷却为{skillCd}秒,剩余{skillCd-dif.TotalSeconds}秒,跳过此次行动");
}
skipFightName = command.Name;
continue;
}
}
command.Execute(combatScenes);
//统计战斗人次
if (i == combatCommands.Count - 1 || command.Name != combatCommands[i + 1].Name)
@@ -249,7 +275,7 @@ public class AutoFightTask : ISoloTask
countFight++;
}
lastFighttName = command.Name;
lastFightName = command.Name;
if (!fightEndFlag && _taskParam is { FightFinishDetectEnabled: true })
{
//处于最后一个位置,或者当前执行人和下一个人名字不一样的情况,满足一定条件(开启快速检查并且检查时间大于0或人名存在配置)检查战斗
@@ -341,7 +367,7 @@ public class AutoFightTask : ISoloTask
{
var time = DateTime.UtcNow - kazuha.LastSkillTime;
//当万叶cd大于3时或战斗人次少于2时通常无怪物情况下此时不再触发万叶拾取
if (!(countFight < 2 || lastFighttName == "枫原万叶" && time.TotalSeconds > 3))
if (!(countFight < 2 || lastFightName == "枫原万叶" && time.TotalSeconds > 3))
{
Logger.LogInformation("使用枫原万叶长E拾取掉落物");
await Delay(300, ct);
@@ -470,6 +496,53 @@ public class AutoFightTask : ISoloTask
(g >= 240 && g <= 255) &&
(b >= 240 && b <= 255);
}
static double FindMax(double[] numbers)
{
if (numbers == null || numbers.Length == 0)
{
throw new ArgumentException("The array is empty or null.");
}
double max = numbers[0]>10000 ? 0 : numbers[0];
foreach (var num in numbers)
{
var cpnum = numbers[0]>10000 ? 0 : num;
max = Math.Max(max, num);
}
return max;
}
private static Dictionary<string, double> ParseStringToDictionary(string input,double defaultValue=-1)
{
var dictionary = new Dictionary<string, double>();
if (string.IsNullOrEmpty(input))
{
return dictionary; // 返回空字典
}
string[] pairs = input.Split(';', StringSplitOptions.RemoveEmptyEntries);
foreach (var pair in pairs)
{
var parts = pair.Split(',', StringSplitOptions.TrimEntries);
if (parts.Length > 0)
{
string name = parts[0];
double value = defaultValue;
if (parts.Length > 1 && double.TryParse(parts[1], out var parsedValue))
{
value = parsedValue;
}
dictionary[name] = value;
}
}
return dictionary;
}
private bool HasFightFlagByYolo(ImageRegion imageRegion)
{

View File

@@ -325,7 +325,8 @@ namespace LogParse
(name: "最后小怪日期", value: ms => ms.LastSmallTime),
(name: "精英", value: ms => ms.EliteGameStatistics.ToString()),
(name: "精英详细", value: ms => ms.EliteDetails), (name: "最后精英日期", value: ms => ms.LastEliteTime),
(name: "总计锄地摩拉", value: ms => ms.TotalMoraKillingMonstersMora.ToString())
(name: "总计锄地摩拉", value: ms => ms.TotalMoraKillingMonstersMora.ToString()),
(name: "突发事件获取摩拉", value: ms => ms.EmergencyBonus)
];
//锄地部分新曾字段
(string name, Func<MoraStatistics, string> value)[] col2Configs=[..msColConfigs.ToList().Where(item=>item.name!="日期" && item.name!="最后小怪日期" && item.name!="最后精英日期"),
@@ -386,7 +387,7 @@ namespace LogParse
.OrderBy(group => group.Key)
.Reverse().ToList();
html.AppendLine($"<h2>按日锄地摩拉统计</h2>");
html.AppendLine($"<h2>按日摩拉收益统计</h2>");
html.AppendLine("<table>");
html.AppendLine(" <tr>");

View File

@@ -25,6 +25,16 @@ namespace LogParse
public List<ActionItem> SmallMonsterActionItems =>
this.MonsterActionItems.Except(EliteMonsterActionItems).ToList();
public string EmergencyBonus
{
get
{
var ls = this.ActionItems.Where(item => item.ActionId == 28).ToList();
var count = ls.Count();
return ls.Sum(item=>item.Num)+((count==0 || count>=10)?"":$"({count}/10)");
}
}
public string LastEliteTime => EliteMonsterActionItems.MaxBy(item => item?.Time)?.Time ?? null;
public string LastSmallTime => SmallMonsterActionItems.MaxBy(item => item?.Time)?.Time ?? null;

View File

@@ -50,8 +50,8 @@ public class TravelsDiaryDetailManager
var _temp = JsonSerializer.Deserialize<ApiResponse<ActionItem>>(File.ReadAllText(tddfile));
if (_temp != null)
{
//统计杀怪
actionItems.AddRange(_temp.Data.List.Where(item => item.ActionId == 37));
//统计杀怪或突发事件奖励
actionItems.AddRange(_temp.Data.List.Where(item => item.ActionId == 37 || item.ActionId == 28));
}
}
}

View File

@@ -428,7 +428,34 @@
</b:Interaction.Triggers>
</ComboBox>
</Grid>
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="根据技能CD优化出招人员"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="根据填入人或人和cd来决定当此人元素战技cd未结束时跳过此人出招来优化战斗流程可填入人名或人名数字用逗号分隔多种用分号分隔例如:白术;钟离,12;如果人名则用内置cd检查或填入数字也小于0如果是人名和数字则把数字当做出招cd(秒)。"
TextWrapping="Wrap" />
<ui:TextBox Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
MinWidth="180"
MaxWidth="800"
Margin="0,0,36,0"
Text="{Binding Config.AutoFightConfig.ActionSchedulerByCd, Mode=TwoWay}"
TextWrapping="Wrap" />
</Grid>
<!--内嵌的设置-->
<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
<Grid Margin="16,10,52,0">

View File

@@ -370,6 +370,34 @@
</b:Interaction.Triggers>
</ComboBox>
</Grid>
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="根据技能CD优化出招人员"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="根据填入人或人和cd来决定当此人元素战技cd未结束时跳过此人出招来优化战斗流程可填入人名或人名数字用逗号分隔多种用分号分隔例如:白术;钟离,12;如果人名则用内置cd检查或填入数字也小于0如果是人名和数字则把数字当做出招cd(秒)。"
TextWrapping="Wrap" />
<ui:TextBox Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
MinWidth="180"
MaxWidth="800"
Margin="0,0,36,0"
Text="{Binding PathingConfig.AutoFightConfig.ActionSchedulerByCd, Mode=TwoWay}"
TextWrapping="Wrap" />
</Grid>
<Grid Margin="16">
<ui:CardExpander Margin="0,0,0,12"