Bird and bat doodads appeared frozen mid-flap in the sky because bone
computation stops beyond 150 units (LOD3 distance) but the model was
still rendered in its bind pose. Now classified as sky birds and their
render distance is capped to the bone-update range, fading in smoothly
as the player approaches.
Add complete spell visual pipeline resolving the DBC chain
(Spell → SpellVisual → SpellVisualKit → SpellVisualEffectName → M2)
with precast/cast/impact phases, bone-attached positioning, and
automatic dual-hand mirroring.
Ribbon rendering fixes:
- Parse visibility track as uint8 (was read as float, suppressing
all ribbon edges due to ~1.4e-45 failing the >0.5 check)
- Filter garbage emitters with bone=UINT_MAX unconditionally
- Guard against NaN spine positions from corrupt bone data
- Resolve ribbon textures via direct index, not textureLookup table
- Fall back to bone 0 when ribbon bone index is out of range
Particle rendering fixes:
- Reduce spell particle scale from 5x to 1.5x (was oversized)
- Exempt spell effect instances from position-based deduplication
Spell handler integration:
- Trigger precast visuals on SMSG_SPELL_START with server castTimeMs
- Trigger cast/impact visuals on SMSG_SPELL_GO
- Cancel precast visuals on cast interrupt/failure/movement
M2 classifier expansion:
- Add AmbientEmitterType enum for sound system integration
- Add 20+ foliage tokens, 4 spell effect tokens, isSmallFoliage flag
- Add markModelAsSpellEffect() to override disableAnimation
DBC layouts:
- Add SpellVisualID field to Spell.dbc for all expansion configs
Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>