mirror of
https://github.com/waynebian01/Shigure.git
synced 2026-09-03 07:15:24 +08:00
Refactor item categories and IDs across multiple class configurations
- Removed unused skill entries and adjusted step numbers in DemonHunter.json. - Updated item categories and added item IDs for healing items in Paladin.json, Priest.json, Shaman.json, Warlock.json, and Warrior.json. - Ensured consistent naming for healing items across classes.
This commit is contained in:
@@ -288,11 +288,13 @@ internal sealed class ModuleDependencyService
|
||||
|
||||
private static void ValidateSnapshot(ModuleDefinition module, ModuleDependencySnapshot snapshot)
|
||||
{
|
||||
if (snapshot.SchemaVersion != ModuleDependencySnapshot.CurrentSchemaVersion)
|
||||
if (snapshot.SchemaVersion is < 1 or > ModuleDependencySnapshot.CurrentSchemaVersion)
|
||||
{
|
||||
throw new InvalidDataException($"不支持依赖快照版本 {snapshot.SchemaVersion}。");
|
||||
}
|
||||
|
||||
UpgradeLegacyItems(snapshot);
|
||||
|
||||
if (module.Match.ClassId != snapshot.ClassId || module.Match.SpecId != snapshot.SpecId)
|
||||
{
|
||||
throw new InvalidDataException("依赖快照的职业/专精与模块匹配条件不一致。");
|
||||
@@ -324,12 +326,57 @@ internal sealed class ModuleDependencyService
|
||||
throw new InvalidDataException("依赖快照包含缺少有效 spellId 的法术。");
|
||||
}
|
||||
|
||||
var items = snapshot.Config.Spec.Items ?? [];
|
||||
var itemReservedNames = new HashSet<string>(StringComparer.Ordinal);
|
||||
foreach (var category in new[]
|
||||
{
|
||||
ClassStateCatalog.CategoryState,
|
||||
ClassStateCatalog.CategoryResource,
|
||||
ClassStateCatalog.CategoryConfig
|
||||
})
|
||||
{
|
||||
itemReservedNames.UnionWith(
|
||||
snapshot.Config.Spec.CategorizedStates.GetValueOrDefault(category) ?? []);
|
||||
}
|
||||
if (items.Any(item => item.ItemId <= 0 || string.IsNullOrWhiteSpace(item.Name))
|
||||
|| items.Select(item => item.ItemId).Distinct().Count() != items.Count
|
||||
|| items.Select(item => item.Name).Distinct(StringComparer.Ordinal).Count() != items.Count
|
||||
|| items.Any(item => itemReservedNames.Contains(item.Name)))
|
||||
{
|
||||
throw new InvalidDataException("依赖快照包含无效或重复的物品 itemId/name。");
|
||||
}
|
||||
|
||||
if ((snapshot.Config.SpellsList ?? []).Any(spell => !IsValidSpellId(spell.SpellId)))
|
||||
{
|
||||
throw new InvalidDataException("依赖快照包含缺少有效 spellId 的技能列表条目。");
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpgradeLegacyItems(ModuleDependencySnapshot snapshot)
|
||||
{
|
||||
if (snapshot.SchemaVersion != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var spec = snapshot.Config.Spec;
|
||||
spec.Items ??= [];
|
||||
if (spec.CategorizedStates.TryGetValue(ClassStateCatalog.CategoryItem, out var legacyNames))
|
||||
{
|
||||
foreach (var name in legacyNames.ToArray())
|
||||
{
|
||||
if (ClassStateCatalog.TryGetLegacyItemId(name, out var itemId)
|
||||
&& spec.Items.All(item => item.ItemId != itemId))
|
||||
{
|
||||
spec.Items.Add(new ModuleItemSnapshot { ItemId = itemId, Name = name });
|
||||
legacyNames.Remove(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snapshot.SchemaVersion = ModuleDependencySnapshot.CurrentSchemaVersion;
|
||||
}
|
||||
|
||||
private static List<RemovedStateField> RemoveUnknownStateFields(ModuleSpecSnapshot spec)
|
||||
{
|
||||
var removed = new List<RemovedStateField>();
|
||||
@@ -410,6 +457,10 @@ internal sealed class ModuleDependencyService
|
||||
pair => pair.Key,
|
||||
pair => new List<string>(pair.Value),
|
||||
StringComparer.Ordinal),
|
||||
Items = spec.Items
|
||||
.Where(item => item.ItemId is > 0 && !string.IsNullOrWhiteSpace(item.Name))
|
||||
.Select(item => new ModuleItemSnapshot { ItemId = item.ItemId!.Value, Name = item.Name })
|
||||
.ToList(),
|
||||
PlayerAuras = spec.PlayerAuras.Select(CaptureAura).ToList(),
|
||||
TargetHarmfulAuras = spec.TargetHarmfulAuras.Select(CaptureAura).ToList(),
|
||||
TargetHelpfulAuras = spec.TargetHelpfulAuras.Select(CaptureAura).ToList(),
|
||||
@@ -466,6 +517,10 @@ internal sealed class ModuleDependencyService
|
||||
{
|
||||
foreach (var category in StateCategories)
|
||||
{
|
||||
if (string.Equals(category, ClassStateCatalog.CategoryItem, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
MergeStrings(local.CategorizedStates[category], incoming.CategorizedStates.GetValueOrDefault(category) ?? [], counters);
|
||||
}
|
||||
}
|
||||
@@ -480,6 +535,10 @@ internal sealed class ModuleDependencyService
|
||||
{
|
||||
foreach (var category in StateCategories)
|
||||
{
|
||||
if (string.Equals(category, ClassStateCatalog.CategoryItem, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
MergeStrings(local.FlatStates, incoming.CategorizedStates.GetValueOrDefault(category) ?? [], counters);
|
||||
}
|
||||
}
|
||||
@@ -489,6 +548,26 @@ internal sealed class ModuleDependencyService
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (local.NestedStates)
|
||||
{
|
||||
var reservedNames = new HashSet<string>(StringComparer.Ordinal);
|
||||
foreach (var category in new[]
|
||||
{
|
||||
ClassStateCatalog.CategoryState,
|
||||
ClassStateCatalog.CategoryResource,
|
||||
ClassStateCatalog.CategoryConfig
|
||||
})
|
||||
{
|
||||
reservedNames.UnionWith(local.CategorizedStates.GetValueOrDefault(category) ?? []);
|
||||
}
|
||||
MergeItems(local.Items, incoming.Items ?? [], reservedNames, counters);
|
||||
}
|
||||
else if ((incoming.Items ?? []).Count > 0)
|
||||
{
|
||||
counters.Conflicts.Add("本地配置仍使用平面 states,无法导入 itemId 物品配置。");
|
||||
}
|
||||
|
||||
MergeAuras(local.PlayerAuras, incoming.PlayerAuras, "玩家光环", counters);
|
||||
MergeAuras(local.TargetHarmfulAuras, incoming.TargetHarmfulAuras, "目标减益", counters);
|
||||
MergeAuras(local.TargetHelpfulAuras, incoming.TargetHelpfulAuras, "目标增益", counters);
|
||||
@@ -715,6 +794,46 @@ internal sealed class ModuleDependencyService
|
||||
}
|
||||
}
|
||||
|
||||
private static void MergeItems(
|
||||
List<ClassBlocksStore.ItemEntry> local,
|
||||
IEnumerable<ModuleItemSnapshot> incoming,
|
||||
IReadOnlySet<string> reservedNames,
|
||||
MergeCounters counters)
|
||||
{
|
||||
foreach (var item in incoming.OrderBy(item => item.ItemId))
|
||||
{
|
||||
var byId = local.FirstOrDefault(existing => existing.ItemId == item.ItemId);
|
||||
if (byId is not null)
|
||||
{
|
||||
if (!string.Equals(byId.Name, item.Name, StringComparison.Ordinal))
|
||||
{
|
||||
counters.Conflicts.Add(
|
||||
$"物品 itemId {item.ItemId} 的名称不同:本地“{byId.Name}”、模块“{item.Name}”,已保留本地。");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
var byName = local.FirstOrDefault(existing => string.Equals(existing.Name, item.Name, StringComparison.Ordinal));
|
||||
if (byName is not null)
|
||||
{
|
||||
counters.Conflicts.Add(
|
||||
$"物品名称“{item.Name}”的 itemId 不同:本地 {byName.ItemId}、模块 {item.ItemId},已保留本地。");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reservedNames.Contains(item.Name))
|
||||
{
|
||||
counters.Conflicts.Add($"物品名称“{item.Name}”与本地状态、能量或配置开关字段重名,已跳过。");
|
||||
continue;
|
||||
}
|
||||
|
||||
local.Add(new ClassBlocksStore.ItemEntry { ItemId = item.ItemId, Name = item.Name });
|
||||
counters.ConfigAdded++;
|
||||
}
|
||||
|
||||
local.Sort((left, right) => (left.ItemId ?? long.MaxValue).CompareTo(right.ItemId ?? long.MaxValue));
|
||||
}
|
||||
|
||||
private static void MergeSpellMetadata(
|
||||
ClassBlocksStore.SpellEntry target,
|
||||
ModuleSpellSnapshot incoming,
|
||||
|
||||
Reference in New Issue
Block a user