acdream/src/AcDream.Core/Spells/SpellMetadata.cs
Erik 07be994d97 feat: port retail magic lifecycle and retained spell UI
Complete the retail cast-intent, target, component, enchantment, and busy-state paths; mount the DAT-authored spell bar, spellbook, component book, effects panels, and shared panel lifecycle; and add scoped input plus conformance coverage.

Co-Authored-By: Codex <noreply@openai.com>
2026-07-15 10:55:22 +02:00

61 lines
2 KiB
C#

namespace AcDream.Core.Spells;
/// <summary>
/// Per-spell static metadata loaded once at startup from
/// <c>docs/research/data/spells.csv</c> via <see cref="SpellTable"/>.
/// One record per known spell id (3,956 entries in the retail dump).
///
/// <para>
/// Used for:
/// </para>
/// <list type="bullet">
/// <item>Buff / debuff bar labels (<see cref="Name"/>,
/// <see cref="School"/>, <see cref="IconId"/>).</item>
/// <item>Stacking aggregation (<see cref="Family"/> — only one
/// enchantment per family-bucket is active; this is what
/// <c>EnchantmentMath</c> uses to filter out superseded
/// buffs in <c>LocalPlayerState.GetMaxApprox</c>).</item>
/// <item>Spell tooltips (<see cref="Description"/>,
/// <see cref="ManaCost"/>, <see cref="Duration"/>,
/// <see cref="SpellWords"/>).</item>
/// <item>Cast-bar audio + animation cues
/// (<see cref="SpellWords"/> drives the chant).</item>
/// </list>
///
/// <para>
/// Fields not exposed (yet) from the 35-column source CSV: SortKey,
/// Difficulty, Flags, Generation, IsFastWindup, IsIrresistible,
/// IsOffensive, IsUntargetted, Speed, CasterEffect, TargetEffect,
/// TargetMask, Type, plus 10 anonymous Unknown1..10. Add them on
/// demand as panels grow.
/// </para>
/// </summary>
public sealed record SpellMetadata(
uint SpellId,
string Name,
string School,
uint Family,
uint IconId,
string SpellWords,
float Duration,
int ManaCost,
bool IsDebuff,
bool IsFellowship,
string Description,
int SortKey,
int Difficulty,
uint Flags,
int Generation,
bool IsFastWindup,
bool IsOffensive,
bool IsUntargeted,
float Speed,
uint CasterEffect,
uint TargetEffect,
uint TargetMask,
int SpellType)
{
public bool IsSelfTargeted => (Flags & 0x00000008u) != 0;
public bool IsBeneficial => (Flags & 0x00000004u) != 0;
public bool IsProjectile => (Flags & 0x00000100u) != 0;
}