mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-24 08:00:14 +00:00
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:
parent
1fb1daea7f
commit
da49593268
13 changed files with 321 additions and 128 deletions
71
src/rendering/levelup_effect.cpp
Normal file
71
src/rendering/levelup_effect.cpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#include "rendering/levelup_effect.hpp"
|
||||
#include "rendering/m2_renderer.hpp"
|
||||
#include "pipeline/m2_loader.hpp"
|
||||
#include "core/logger.hpp"
|
||||
|
||||
namespace wowee {
|
||||
namespace rendering {
|
||||
|
||||
LevelUpEffect::LevelUpEffect() = default;
|
||||
LevelUpEffect::~LevelUpEffect() = default;
|
||||
|
||||
bool LevelUpEffect::loadModel(M2Renderer* m2Renderer,
|
||||
const std::vector<uint8_t>& m2FileData,
|
||||
const std::vector<uint8_t>& skinFileData) {
|
||||
if (!m2Renderer || m2FileData.empty()) return false;
|
||||
|
||||
m2Renderer_ = m2Renderer;
|
||||
|
||||
pipeline::M2Model model = pipeline::M2Loader::load(m2FileData);
|
||||
// Spell effect M2s may have no geometry (particle-only), so don't require isValid()
|
||||
if (model.vertices.empty() && model.particleEmitters.empty()) {
|
||||
LOG_WARNING("LevelUpEffect: M2 has no vertices and no particle emitters");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!skinFileData.empty() && model.version >= 264) {
|
||||
pipeline::M2Loader::loadSkin(skinFileData, model);
|
||||
}
|
||||
|
||||
if (!m2Renderer_->loadModel(model, MODEL_ID)) {
|
||||
LOG_WARNING("LevelUpEffect: failed to load model to GPU");
|
||||
return false;
|
||||
}
|
||||
|
||||
modelLoaded_ = true;
|
||||
LOG_INFO("LevelUpEffect: loaded LevelUp.m2 — vertices=", model.vertices.size(),
|
||||
" indices=", model.indices.size(),
|
||||
" emitters=", model.particleEmitters.size(),
|
||||
" batches=", model.batches.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void LevelUpEffect::trigger(const glm::vec3& position) {
|
||||
if (!modelLoaded_ || !m2Renderer_) return;
|
||||
|
||||
uint32_t instanceId = m2Renderer_->createInstance(MODEL_ID, position,
|
||||
glm::vec3(0.0f), 1.0f);
|
||||
if (instanceId == 0) {
|
||||
LOG_WARNING("LevelUpEffect: failed to create instance");
|
||||
return;
|
||||
}
|
||||
|
||||
activeEffects_.push_back({instanceId, 0.0f});
|
||||
}
|
||||
|
||||
void LevelUpEffect::update(float deltaTime) {
|
||||
if (activeEffects_.empty() || !m2Renderer_) return;
|
||||
|
||||
for (auto it = activeEffects_.begin(); it != activeEffects_.end(); ) {
|
||||
it->elapsed += deltaTime;
|
||||
if (it->elapsed >= EFFECT_DURATION) {
|
||||
m2Renderer_->removeInstance(it->instanceId);
|
||||
it = activeEffects_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rendering
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue