Add 3D level-up effect using LevelUp.m2 spell model

Replace 2D screen-space ding rings with real WoW LevelUp.m2 particle/geometry
effect. Fix FBlock particle color parsing (C3Vector floats, not CImVector bytes)
which was producing blue/red instead of golden yellow. Spell effect models bypass
particle dampeners, glow sprite conversion, Mod→Additive blend override, and all
collision (floor/wall/camera) to prevent camera zoom-in. Other players' level-ups
trigger the 3D effect at their position with group chat notification. F7 hotkey
for testing.
This commit is contained in:
Kelsi 2026-02-19 20:36:25 -08:00
parent 1fb1daea7f
commit da49593268
13 changed files with 321 additions and 128 deletions

View file

@ -595,14 +595,13 @@ void parseFBlock(const std::vector<uint8_t>& data, uint32_t offset,
uint32_t ofsKeys = disk.ofsKeys;
if (valueType == 0) {
// Color: CImVector (4 bytes RGBA) per key. We extract RGB, ignore A.
if (ofsKeys + nKeys * 4 > data.size()) return;
// Color: C3Vector (3 × float per key, values in 0-255 range)
if (ofsKeys + nKeys * 12 > data.size()) return;
fb.vec3Values.reserve(nKeys);
for (uint32_t i = 0; i < nKeys; i++) {
uint8_t r = data[ofsKeys + i * 4 + 0];
uint8_t g = data[ofsKeys + i * 4 + 1];
uint8_t b = data[ofsKeys + i * 4 + 2];
// byte 3 is alpha, handled separately by the alpha FBlock
float r = readValue<float>(data, ofsKeys + i * 12 + 0);
float g = readValue<float>(data, ofsKeys + i * 12 + 4);
float b = readValue<float>(data, ofsKeys + i * 12 + 8);
fb.vec3Values.emplace_back(r / 255.0f, g / 255.0f, b / 255.0f);
}
} else if (valueType == 1) {