feat: use M2 animation duration for spell visual lifetime

Spell visual effects previously used a fixed 3.5s duration for all
effects, causing some to linger too long and overlap during combat.
Now queries the M2 model's default animation duration via the new
getInstanceAnimDuration() method and clamps it to 0.5-5s. Effects
without animations fall back to a 2s default. This makes spell impacts
feel more responsive and reduces visual clutter.
This commit is contained in:
Kelsi 2026-03-20 05:52:47 -07:00
parent 29c938dec2
commit 90edb3bc07
4 changed files with 28 additions and 5 deletions

View file

@ -323,6 +323,7 @@ public:
void setInstancePosition(uint32_t instanceId, const glm::vec3& position);
void setInstanceTransform(uint32_t instanceId, const glm::mat4& transform);
void setInstanceAnimationFrozen(uint32_t instanceId, bool frozen);
float getInstanceAnimDuration(uint32_t instanceId) const;
void removeInstance(uint32_t instanceId);
void removeInstances(const std::vector<uint32_t>& instanceIds);
void setSkipCollision(uint32_t instanceId, bool skip);

View file

@ -334,7 +334,11 @@ private:
pipeline::AssetManager* cachedAssetManager = nullptr;
// Spell visual effects — transient M2 instances spawned by SMSG_PLAY_SPELL_VISUAL/IMPACT
struct SpellVisualInstance { uint32_t instanceId; float elapsed; };
struct SpellVisualInstance {
uint32_t instanceId;
float elapsed;
float duration; // per-instance lifetime in seconds (from M2 anim or default)
};
std::vector<SpellVisualInstance> activeSpellVisuals_;
std::unordered_map<uint32_t, std::string> spellVisualCastPath_; // visualId → cast M2 path
std::unordered_map<uint32_t, std::string> spellVisualImpactPath_; // visualId → impact M2 path
@ -343,7 +347,8 @@ private:
bool spellVisualDbcLoaded_ = false;
void loadSpellVisualDbc();
void updateSpellVisuals(float deltaTime);
static constexpr float SPELL_VISUAL_DURATION = 3.5f;
static constexpr float SPELL_VISUAL_MAX_DURATION = 5.0f;
static constexpr float SPELL_VISUAL_DEFAULT_DURATION = 2.0f;
uint32_t currentZoneId = 0;
std::string currentZoneName;