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>
This commit is contained in:
Erik 2026-07-15 10:55:22 +02:00
parent 7b7ffcd278
commit 07be994d97
84 changed files with 17822 additions and 1051 deletions

View file

@ -131,6 +131,7 @@ public sealed class WorldSession : IDisposable
string? PluralName = null,
uint? PetOwnerId = null,
ushort? AmmoType = null,
uint? SpellId = null,
PhysicsSpawnData? Physics = null);
/// <summary>
@ -191,6 +192,7 @@ public sealed class WorldSession : IDisposable
PluralName: parsed.PluralName,
PetOwnerId: parsed.PetOwnerId,
AmmoType: parsed.AmmoType,
SpellId: parsed.SpellId,
Physics: parsed.Physics);
/// <summary>Fires when the session finishes parsing a CreateObject.</summary>
@ -1451,6 +1453,45 @@ public sealed class WorldSession : IDisposable
seq, componentId: 0u, amount: uint.MaxValue));
}
public void SendSetDesiredComponentLevel(uint componentId, uint amount)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSetDesiredComponentLevel(
seq, componentId, amount));
}
public void SendAddSpellFavorite(uint spellId, int position, int tabIndex)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildAddSpellFavorite(
seq, spellId, position, tabIndex));
}
public void SendRemoveSpellFavorite(uint spellId, int tabIndex)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildRemoveSpellFavorite(
seq, spellId, tabIndex));
}
public void SendSpellbookFilter(uint filters)
{
uint seq = NextGameActionSequence();
SendGameAction(ClientCommandRequests.BuildSpellbookFilter(seq, filters));
}
public void SendCastUntargetedSpell(uint spellId)
{
uint seq = NextGameActionSequence();
SendGameAction(CastSpellRequest.BuildUntargeted(seq, spellId));
}
public void SendCastTargetedSpell(uint targetGuid, uint spellId)
{
uint seq = NextGameActionSequence();
SendGameAction(CastSpellRequest.BuildTargeted(seq, targetGuid, spellId));
}
/// <summary>Send retail ChangeCombatMode (0x0053).</summary>
public void SendChangeCombatMode(CombatMode mode)
{