mirror of
https://github.com/waynebian01/Shigure.git
synced 2026-09-03 07:15:24 +08:00
Enhance item management by adding '插入物品' command and integrating item handling into the Fuyutsui framework. Update README to reflect new item insertion functionality and modify class blocks across all character classes to include item insertion. Implement item indexing and retrieval methods in core logic, ensuring consistency with spell handling. Update UI components to support item conditions and improve overall item management experience.
This commit is contained in:
@@ -64,6 +64,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
private readonly Dictionary<string, List<long>> _currentSpecItemIdsByName =
|
||||
new(StringComparer.Ordinal);
|
||||
private readonly List<ConditionSpell> _currentClassConditionSpells = new();
|
||||
private readonly List<ConditionItem> _currentClassConditionItems = new();
|
||||
private HashSet<string>? _availableConditionFields;
|
||||
private HashSet<string>? _availableGroupConditionFields;
|
||||
private Dictionary<string, string>? _conditionFieldDisplayNames;
|
||||
@@ -986,6 +987,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
_spellColumn.Items.Add(string.Empty);
|
||||
_spellColumn.Items.Add(ModuleSpecialActions.PauseSpell);
|
||||
_spellColumn.Items.Add(ModuleSpecialActions.FailedSpell);
|
||||
_spellColumn.Items.Add(ModuleSpecialActions.FailedItem);
|
||||
_spellColumn.Items.Add(ModuleSpecialActions.OneKeySpell);
|
||||
foreach (var spell in _keymapCatalog.GetSpells(classId))
|
||||
{
|
||||
@@ -1065,7 +1067,9 @@ public sealed class ModuleEditorControl : UserControl
|
||||
var classId = ReadMatchCombo(_classBox);
|
||||
var allowed = ModuleSpecialActions.IsFailedSpell(spell)
|
||||
? _keymapCatalog.GetUnitsForSpells(classId, _keymapCatalog.GetFailedSpellNames(classId))
|
||||
: _keymapCatalog.GetUnitsForSpell(classId, spell);
|
||||
: ModuleSpecialActions.IsFailedItem(spell)
|
||||
? _keymapCatalog.GetUnitsForSpells(classId, _keymapCatalog.GetFailedItemNames(classId))
|
||||
: _keymapCatalog.GetUnitsForSpell(classId, spell);
|
||||
|
||||
foreach (var unit in allowed)
|
||||
{
|
||||
@@ -1208,6 +1212,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
_currentClassSpellIdsByName.Clear();
|
||||
_currentSpecItemIdsByName.Clear();
|
||||
_currentClassConditionSpells.Clear();
|
||||
_currentClassConditionItems.Clear();
|
||||
var classId = ReadMatchCombo(_classBox);
|
||||
if (classId is null)
|
||||
{
|
||||
@@ -1245,6 +1250,30 @@ public sealed class ModuleEditorControl : UserControl
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in document.ItemsList
|
||||
.Where(item => item.ItemId > 0 && !string.IsNullOrWhiteSpace(item.Name))
|
||||
.OrderBy(item => item.Index)
|
||||
.ThenBy(item => item.ItemId))
|
||||
{
|
||||
var name = item.Name.Trim();
|
||||
SpellIconCatalog.RegisterItem(item.ItemId, name);
|
||||
if (_currentClassConditionItems.All(entry => entry.ItemId != item.ItemId))
|
||||
{
|
||||
_currentClassConditionItems.Add(new ConditionItem(item.ItemId, item.Index, name));
|
||||
}
|
||||
|
||||
if (!_currentSpecItemIdsByName.TryGetValue(name, out var classItemIds))
|
||||
{
|
||||
classItemIds = [];
|
||||
_currentSpecItemIdsByName[name] = classItemIds;
|
||||
}
|
||||
|
||||
if (!classItemIds.Contains(item.ItemId))
|
||||
{
|
||||
classItemIds.Add(item.ItemId);
|
||||
}
|
||||
}
|
||||
|
||||
var specId = ReadMatchCombo(_specBox);
|
||||
if (specId is not null && document.Specs.TryGetValue(specId.Value, out var spec))
|
||||
{
|
||||
@@ -1440,6 +1469,17 @@ public sealed class ModuleEditorControl : UserControl
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ItemIdConditionFields.Contains(term.Field))
|
||||
{
|
||||
if (!long.TryParse(term.Value.Trim(), out var itemId)
|
||||
|| itemId <= 0
|
||||
|| !_currentClassConditionItems.Any(item => item.ItemId == itemId))
|
||||
{
|
||||
AddUnique(messages, $"{term.Field}不存在 itemId 为 {term.Value.Trim()} 的物品");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
AddMissingStructuredField(term.Field, "条件字段", structuredFields, messages);
|
||||
}
|
||||
}
|
||||
@@ -2185,7 +2225,8 @@ public sealed class ModuleEditorControl : UserControl
|
||||
|
||||
if (!row.IsNewRow
|
||||
&& (GetMissingConditionFields(row).Count > 0
|
||||
|| GetMissingConditionSpells(row).Count > 0))
|
||||
|| GetMissingConditionSpells(row).Count > 0
|
||||
|| GetMissingConditionItems(row).Count > 0))
|
||||
{
|
||||
// 缺失字段或 spellId 会让条件不命中;用整行红色状态提醒用户修复配置。
|
||||
e.CellStyle.BackColor = UiTheme.DangerSoft;
|
||||
@@ -2290,6 +2331,42 @@ public sealed class ModuleEditorControl : UserControl
|
||||
return missing;
|
||||
}
|
||||
|
||||
private IReadOnlyList<string> GetMissingConditionItems(DataGridViewRow row)
|
||||
{
|
||||
var availableItemIds = _currentClassConditionItems
|
||||
.Select(item => item.ItemId)
|
||||
.ToHashSet();
|
||||
var missing = new List<string>();
|
||||
var seen = new HashSet<string>(StringComparer.Ordinal);
|
||||
var metadata = GetRuleMetadata(row);
|
||||
foreach (var expression in new[] { CellText(row, "Condition") }.Concat(metadata.SubConditions))
|
||||
{
|
||||
foreach (var term in ConditionExpression.Parse(expression))
|
||||
{
|
||||
if (!ItemIdConditionFields.Contains(term.Field))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var value = term.Value.Trim();
|
||||
if (long.TryParse(value, out var itemId)
|
||||
&& itemId > 0
|
||||
&& availableItemIds.Contains(itemId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var message = $"{term.Field}不存在 itemId 为 {value} 的物品";
|
||||
if (seen.Add(message))
|
||||
{
|
||||
missing.Add(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return missing;
|
||||
}
|
||||
|
||||
// 字段目录的构造会读取职业配置和动态数值表;缓存后避免每个可见单元格重复做同一份工作。
|
||||
private void EnsureConditionFieldValidationCatalog()
|
||||
{
|
||||
@@ -2421,6 +2498,8 @@ public sealed class ModuleEditorControl : UserControl
|
||||
var field = FormatConditionFieldForDisplay(term.Field);
|
||||
var value = SpellIdConditionFields.Contains(term.Field)
|
||||
? FormatConditionSpellValueForDisplay(term.Value)
|
||||
: ItemIdConditionFields.Contains(term.Field)
|
||||
? FormatConditionItemValueForDisplay(term.Value)
|
||||
: string.Equals(NormalizeConditionFieldName(term.Field), "首领战", StringComparison.Ordinal)
|
||||
? FormatBossValueForDisplay(term.Value)
|
||||
: term.Value;
|
||||
@@ -2468,6 +2547,19 @@ public sealed class ModuleEditorControl : UserControl
|
||||
return string.IsNullOrWhiteSpace(name) ? value : name;
|
||||
}
|
||||
|
||||
private string FormatConditionItemValueForDisplay(string value)
|
||||
{
|
||||
var normalized = value.Trim();
|
||||
if (!long.TryParse(normalized, NumberStyles.Integer, CultureInfo.InvariantCulture, out var itemId)
|
||||
|| itemId <= 0)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
var name = _currentClassConditionItems.FirstOrDefault(item => item.ItemId == itemId)?.Name;
|
||||
return string.IsNullOrWhiteSpace(name) ? value : name;
|
||||
}
|
||||
|
||||
private static string FormatBossValueForDisplay(string value)
|
||||
{
|
||||
var normalized = value.Trim();
|
||||
@@ -2666,7 +2758,8 @@ public sealed class ModuleEditorControl : UserControl
|
||||
|
||||
var missingFields = GetMissingConditionFields(_rulesGrid.Rows[rowIndex]);
|
||||
var missingSpells = GetMissingConditionSpells(_rulesGrid.Rows[rowIndex]);
|
||||
if (missingFields.Count > 0 || missingSpells.Count > 0)
|
||||
var missingItems = GetMissingConditionItems(_rulesGrid.Rows[rowIndex]);
|
||||
if (missingFields.Count > 0 || missingSpells.Count > 0 || missingItems.Count > 0)
|
||||
{
|
||||
var messages = new List<string>();
|
||||
if (missingFields.Count > 0)
|
||||
@@ -2676,6 +2769,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
}
|
||||
|
||||
messages.AddRange(missingSpells);
|
||||
messages.AddRange(missingItems);
|
||||
return string.Join('\n', messages);
|
||||
}
|
||||
|
||||
@@ -3041,7 +3135,9 @@ public sealed class ModuleEditorControl : UserControl
|
||||
current,
|
||||
conditionFieldsProvider: () => RefreshAndBuildConditionFields(),
|
||||
spells: RefreshAndBuildConditionSpells(),
|
||||
conditionSpellsProvider: () => RefreshAndBuildConditionSpells());
|
||||
conditionSpellsProvider: () => RefreshAndBuildConditionSpells(),
|
||||
items: RefreshAndBuildConditionItems(),
|
||||
conditionItemsProvider: () => RefreshAndBuildConditionItems());
|
||||
if (editor.ShowDialog(FindForm()) != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
@@ -3395,6 +3491,7 @@ public sealed class ModuleEditorControl : UserControl
|
||||
var currentMetadata = row.IsNewRow ? new RuleRowMetadata() : GetRuleMetadata(row);
|
||||
var fields = RefreshAndBuildConditionFields(includeRuleSettings: true);
|
||||
var spells = RefreshAndBuildConditionSpells();
|
||||
var items = RefreshAndBuildConditionItems();
|
||||
|
||||
using var editor = new ConditionEditorForm(
|
||||
fields,
|
||||
@@ -3406,7 +3503,9 @@ public sealed class ModuleEditorControl : UserControl
|
||||
allowRuleSettings: true,
|
||||
conditionFieldsProvider: () => RefreshAndBuildConditionFields(includeRuleSettings: true),
|
||||
spells: spells,
|
||||
conditionSpellsProvider: () => RefreshAndBuildConditionSpells());
|
||||
conditionSpellsProvider: () => RefreshAndBuildConditionSpells(),
|
||||
items: items,
|
||||
conditionItemsProvider: () => RefreshAndBuildConditionItems());
|
||||
if (editor.ShowDialog(FindForm()) != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
@@ -3470,6 +3569,12 @@ public sealed class ModuleEditorControl : UserControl
|
||||
return _currentClassConditionSpells.ToArray();
|
||||
}
|
||||
|
||||
private IReadOnlyList<ConditionItem> RefreshAndBuildConditionItems()
|
||||
{
|
||||
ReloadCurrentClassSpellIds();
|
||||
return _currentClassConditionItems.ToArray();
|
||||
}
|
||||
|
||||
private IReadOnlyList<ConditionField> BuildConditionFields(bool includeRuleSettings = false)
|
||||
{
|
||||
var classId = ReadMatchCombo(_classBox);
|
||||
@@ -4366,7 +4471,9 @@ public sealed class ModuleEditorControl : UserControl
|
||||
{
|
||||
var value = persisted?.Trim() ?? string.Empty;
|
||||
if (value.Length == 0 || ModuleSpecialActions.IsPauseSpell(value)
|
||||
|| ModuleSpecialActions.IsFailedSpell(value) || ModuleSpecialActions.IsOneKeySpell(value))
|
||||
|| ModuleSpecialActions.IsFailedSpell(value)
|
||||
|| ModuleSpecialActions.IsFailedItem(value)
|
||||
|| ModuleSpecialActions.IsOneKeySpell(value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user