feat: 更新模块目录和缓存路径,添加职责筛选功能

This commit is contained in:
waynebian01
2026-08-15 16:14:15 +08:00
parent c9f7fc1d57
commit be8f97eca8
12 changed files with 160 additions and 24 deletions

View File

@@ -291,10 +291,7 @@ public sealed class ModuleStore
public static string ResolveModuleDirectory()
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
AppInfo.AppName,
"module");
return Path.Combine(AppPaths.UserDataDirectory, "module");
}
public IReadOnlyList<ModuleDefinition> GetModules()

View File

@@ -48,6 +48,16 @@ public enum UnitSelectorKind
HighestHealingAbsorbWithAuraCount
}
/// <summary>最低生命值选择器使用的职责筛选方式。</summary>
public enum UnitRoleFilterKind
{
/// <summary>只包含指定职责。</summary>
Include,
/// <summary>排除指定职责。</summary>
Exclude
}
/// <summary>
/// 模块内定义的命名动态单位。运行时由 <see cref="UnitSelector"/> 解析为 group 槽位("1".."30")。
/// 单光环类用 AuraNames[0]; WithAnyAura 用整个列表。
@@ -65,6 +75,7 @@ public sealed class ModuleUnit
public UnitSelectorKind Kind { get; set; } = UnitSelectorKind.LowestHealth;
public int? HealthThreshold { get; set; }
public string? HealthThresholdField { get; set; }
public UnitRoleFilterKind? RoleFilter { get; set; }
public int? Role { get; set; }
public bool Reverse { get; set; }
public List<string>? AuraNames { get; set; }
@@ -80,6 +91,7 @@ public sealed class ModuleUnit
Kind = Kind,
HealthThreshold = HealthThreshold,
HealthThresholdField = HealthThresholdField,
RoleFilter = RoleFilter,
Role = Role,
Reverse = Reverse,
AuraNames = AuraNames is null ? null : new List<string>(AuraNames),

View File

@@ -25,19 +25,35 @@ public static class UnitSelector
return unit.Kind switch
{
UnitSelectorKind.LowestHealth => LowestHealth(group, threshold, _ => true),
UnitSelectorKind.LowestHealth => LowestHealth(
group,
threshold,
data => MatchesRoleFilter(data, unit.RoleFilter, unit.Role)),
UnitSelectorKind.LowestHealthWithAnyAura => unit.AuraNames is { Count: > 0 } names
? LowestHealth(group, threshold, data => HasAnyAura(data, names))
? LowestHealth(
group,
threshold,
data => MatchesRoleFilter(data, unit.RoleFilter, unit.Role) && HasAnyAura(data, names))
: null,
UnitSelectorKind.LowestHealthWithoutAura => aura is null
? null
: LowestHealth(group, threshold, data => !HasAura(data, aura)),
: LowestHealth(
group,
threshold,
data => MatchesRoleFilter(data, unit.RoleFilter, unit.Role) && !HasAura(data, aura)),
UnitSelectorKind.LowestHealthWithAura => aura is null
? null
: LowestHealth(group, threshold, data => HasAura(data, aura)),
: LowestHealth(
group,
threshold,
data => MatchesRoleFilter(data, unit.RoleFilter, unit.Role) && HasAura(data, aura)),
UnitSelectorKind.LowestHealthWithAuraCount => aura is null || unit.AuraCount is null
? null
: LowestHealth(group, threshold, data => AuraEquals(data, aura, unit.AuraCount.Value)),
: LowestHealth(
group,
threshold,
data => MatchesRoleFilter(data, unit.RoleFilter, unit.Role)
&& AuraEquals(data, aura, unit.AuraCount.Value)),
UnitSelectorKind.UnitWithRole => unit.Role is null
? null
: UnitWithRole(group, unit.Role.Value, unit.Reverse, _ => true),
@@ -314,6 +330,26 @@ public static class UnitSelector
return TryInt(GetField(data, auraName), out var val) && val == target;
}
private static bool MatchesRoleFilter(
IReadOnlyDictionary<string, object?> data,
UnitRoleFilterKind? filter,
int? role)
{
if (filter is null)
{
return true;
}
if (role is null || !TryInt(GetField(data, "职责"), out var actualRole))
{
return false;
}
return filter == UnitRoleFilterKind.Include
? actualRole == role.Value
: actualRole != role.Value;
}
// 职责为 None/无法解析时视为不跳过(返回 true), 与 utils.py 的 _role_not_zero 一致。
private static bool RoleNotZero(IReadOnlyDictionary<string, object?> data)
{