mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 08:03:50 +00:00
game/rendering: drive player stand-state animation from SMSG_STANDSTATE_UPDATE
Add StandStateCallback to GameHandler, fired when the server confirms a stand state change (SMSG_STANDSTATE_UPDATE). Connect in Application to map the WoW stand state (0-8) to M2 animation IDs on the player character model: - 0 = Stand → anim 0 (Stand) - 1-6 = Sit variants → anim 27 (SitGround) - 7 = Dead → anim 1 (Death) - 8 = Kneel → anim 72 (Kneel) Sit and Kneel animations are looped so the held-pose frame stays visible; Death stays on the final frame.
This commit is contained in:
parent
59c50e3beb
commit
9f3c236c48
3 changed files with 33 additions and 0 deletions
|
|
@ -619,6 +619,11 @@ public:
|
||||||
using NpcRespawnCallback = std::function<void(uint64_t guid)>;
|
using NpcRespawnCallback = std::function<void(uint64_t guid)>;
|
||||||
void setNpcRespawnCallback(NpcRespawnCallback cb) { npcRespawnCallback_ = std::move(cb); }
|
void setNpcRespawnCallback(NpcRespawnCallback cb) { npcRespawnCallback_ = std::move(cb); }
|
||||||
|
|
||||||
|
// Stand state animation callback — fired when SMSG_STANDSTATE_UPDATE confirms a new state
|
||||||
|
// standState: 0=stand, 1-6=sit variants, 7=dead, 8=kneel
|
||||||
|
using StandStateCallback = std::function<void(uint8_t standState)>;
|
||||||
|
void setStandStateCallback(StandStateCallback cb) { standStateCallback_ = std::move(cb); }
|
||||||
|
|
||||||
// Melee swing callback (for driving animation/SFX)
|
// Melee swing callback (for driving animation/SFX)
|
||||||
using MeleeSwingCallback = std::function<void()>;
|
using MeleeSwingCallback = std::function<void()>;
|
||||||
void setMeleeSwingCallback(MeleeSwingCallback cb) { meleeSwingCallback_ = std::move(cb); }
|
void setMeleeSwingCallback(MeleeSwingCallback cb) { meleeSwingCallback_ = std::move(cb); }
|
||||||
|
|
@ -2250,6 +2255,7 @@ private:
|
||||||
NpcDeathCallback npcDeathCallback_;
|
NpcDeathCallback npcDeathCallback_;
|
||||||
NpcAggroCallback npcAggroCallback_;
|
NpcAggroCallback npcAggroCallback_;
|
||||||
NpcRespawnCallback npcRespawnCallback_;
|
NpcRespawnCallback npcRespawnCallback_;
|
||||||
|
StandStateCallback standStateCallback_;
|
||||||
MeleeSwingCallback meleeSwingCallback_;
|
MeleeSwingCallback meleeSwingCallback_;
|
||||||
SpellCastAnimCallback spellCastAnimCallback_;
|
SpellCastAnimCallback spellCastAnimCallback_;
|
||||||
NpcSwingCallback npcSwingCallback_;
|
NpcSwingCallback npcSwingCallback_;
|
||||||
|
|
|
||||||
|
|
@ -2794,6 +2794,30 @@ void Application::setupUICallbacks() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Stand state animation callback — map server stand state to M2 animation on player
|
||||||
|
gameHandler->setStandStateCallback([this](uint8_t standState) {
|
||||||
|
if (!renderer) return;
|
||||||
|
auto* cr = renderer->getCharacterRenderer();
|
||||||
|
if (!cr) return;
|
||||||
|
uint32_t charInstId = renderer->getCharacterInstanceId();
|
||||||
|
if (charInstId == 0) return;
|
||||||
|
// WoW stand state → M2 animation ID mapping
|
||||||
|
// 0=Stand→0, 1-6=Sit variants→27 (SitGround), 7=Dead→1, 8=Kneel→72
|
||||||
|
uint32_t animId = 0;
|
||||||
|
if (standState == 0) {
|
||||||
|
animId = 0; // Stand
|
||||||
|
} else if (standState >= 1 && standState <= 6) {
|
||||||
|
animId = 27; // SitGround (covers sit-chair too; correct visual differs by chair height)
|
||||||
|
} else if (standState == 7) {
|
||||||
|
animId = 1; // Death
|
||||||
|
} else if (standState == 8) {
|
||||||
|
animId = 72; // Kneel
|
||||||
|
}
|
||||||
|
// Non-looping sit/kneel looks wrong frozen; loop them so the held-pose frame shows
|
||||||
|
const bool loop = (animId != 1);
|
||||||
|
cr->playAnimation(charInstId, animId, loop);
|
||||||
|
});
|
||||||
|
|
||||||
// NPC greeting callback - play voice line
|
// NPC greeting callback - play voice line
|
||||||
gameHandler->setNpcGreetingCallback([this](uint64_t guid, const glm::vec3& position) {
|
gameHandler->setNpcGreetingCallback([this](uint64_t guid, const glm::vec3& position) {
|
||||||
if (renderer && renderer->getNpcVoiceManager()) {
|
if (renderer && renderer->getNpcVoiceManager()) {
|
||||||
|
|
|
||||||
|
|
@ -4253,6 +4253,9 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
||||||
LOG_INFO("Stand state updated: ", static_cast<int>(standState_),
|
LOG_INFO("Stand state updated: ", static_cast<int>(standState_),
|
||||||
" (", standState_ == 0 ? "stand" : standState_ == 1 ? "sit"
|
" (", standState_ == 0 ? "stand" : standState_ == 1 ? "sit"
|
||||||
: standState_ == 7 ? "dead" : standState_ == 8 ? "kneel" : "other", ")");
|
: standState_ == 7 ? "dead" : standState_ == 8 ? "kneel" : "other", ")");
|
||||||
|
if (standStateCallback_) {
|
||||||
|
standStateCallback_(standState_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Opcode::SMSG_NEW_TAXI_PATH:
|
case Opcode::SMSG_NEW_TAXI_PATH:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue