mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 07:40:14 +00:00
Fix combat facing updates and dead-on-spawn creature pose
This commit is contained in:
parent
8efc21115f
commit
fc0ac6dd0f
3 changed files with 26 additions and 2 deletions
|
|
@ -175,6 +175,7 @@ private:
|
|||
std::unordered_map<uint32_t, FacialHairGeosets> facialHairGeosetMap_;
|
||||
std::unordered_map<uint64_t, uint32_t> creatureInstances_; // guid → render instanceId
|
||||
std::unordered_map<uint64_t, uint32_t> creatureModelIds_; // guid → loaded modelId
|
||||
std::unordered_set<uint64_t> deadCreatureGuids_; // GUIDs that should spawn in corpse/death pose
|
||||
std::unordered_map<uint32_t, uint32_t> displayIdModelCache_; // displayId → modelId (model caching)
|
||||
uint32_t nextCreatureModelId_ = 5000; // Model IDs for online creatures
|
||||
uint32_t gryphonDisplayId_ = 0;
|
||||
|
|
|
|||
|
|
@ -1694,6 +1694,7 @@ void Application::setupUICallbacks() {
|
|||
|
||||
// NPC death callback (online mode) - play death animation
|
||||
gameHandler->setNpcDeathCallback([this](uint64_t guid) {
|
||||
deadCreatureGuids_.insert(guid);
|
||||
auto it = creatureInstances_.find(guid);
|
||||
if (it != creatureInstances_.end() && renderer && renderer->getCharacterRenderer()) {
|
||||
renderer->getCharacterRenderer()->playAnimation(it->second, 1, false); // Death
|
||||
|
|
@ -1702,6 +1703,7 @@ void Application::setupUICallbacks() {
|
|||
|
||||
// NPC respawn callback (online mode) - reset to idle animation
|
||||
gameHandler->setNpcRespawnCallback([this](uint64_t guid) {
|
||||
deadCreatureGuids_.erase(guid);
|
||||
auto it = creatureInstances_.find(guid);
|
||||
if (it != creatureInstances_.end() && renderer && renderer->getCharacterRenderer()) {
|
||||
renderer->getCharacterRenderer()->playAnimation(it->second, 0, true); // Idle
|
||||
|
|
@ -2777,6 +2779,7 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
|
|||
auto* app = this;
|
||||
|
||||
gameHandler->setNpcDeathCallback([cr, app](uint64_t guid) {
|
||||
app->deadCreatureGuids_.insert(guid);
|
||||
auto it = app->creatureInstances_.find(guid);
|
||||
if (it != app->creatureInstances_.end() && cr) {
|
||||
cr->playAnimation(it->second, 1, false); // animation ID 1 = Death
|
||||
|
|
@ -2784,6 +2787,7 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
|
|||
});
|
||||
|
||||
gameHandler->setNpcRespawnCallback([cr, app](uint64_t guid) {
|
||||
app->deadCreatureGuids_.erase(guid);
|
||||
auto it = app->creatureInstances_.find(guid);
|
||||
if (it != app->creatureInstances_.end() && cr) {
|
||||
cr->playAnimation(it->second, 0, true); // animation ID 0 = Idle
|
||||
|
|
@ -3802,8 +3806,13 @@ void Application::spawnOnlineCreature(uint64_t guid, uint32_t displayId, float x
|
|||
}
|
||||
}
|
||||
|
||||
// Play idle animation and fade in
|
||||
charRenderer->playAnimation(instanceId, 0, true);
|
||||
// Spawn in the correct pose. If the server marked this creature dead before
|
||||
// the queued spawn was processed, start directly in death animation.
|
||||
if (deadCreatureGuids_.count(guid)) {
|
||||
charRenderer->playAnimation(instanceId, 1, false); // Death
|
||||
} else {
|
||||
charRenderer->playAnimation(instanceId, 0, true); // Idle
|
||||
}
|
||||
charRenderer->startFadeIn(instanceId, 0.5f);
|
||||
|
||||
// Track instance
|
||||
|
|
@ -4970,6 +4979,7 @@ void Application::despawnOnlineCreature(uint64_t guid) {
|
|||
pendingCreatureSpawnGuids_.erase(guid);
|
||||
creatureSpawnRetryCounts_.erase(guid);
|
||||
creaturePermanentFailureGuids_.erase(guid);
|
||||
deadCreatureGuids_.erase(guid);
|
||||
|
||||
auto it = creatureInstances_.find(guid);
|
||||
if (it == creatureInstances_.end()) return;
|
||||
|
|
|
|||
|
|
@ -766,6 +766,19 @@ void GameHandler::update(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
// Keep active melee attackers visually facing the player as positions change.
|
||||
// Some servers don't stream frequent orientation updates during combat.
|
||||
if (!hostileAttackers_.empty()) {
|
||||
for (uint64_t attackerGuid : hostileAttackers_) {
|
||||
auto attacker = entityManager.getEntity(attackerGuid);
|
||||
if (!attacker) continue;
|
||||
float dx = movementInfo.x - attacker->getX();
|
||||
float dy = movementInfo.y - attacker->getY();
|
||||
if (std::abs(dx) < 0.01f && std::abs(dy) < 0.01f) continue;
|
||||
attacker->setOrientation(std::atan2(-dy, dx));
|
||||
}
|
||||
}
|
||||
|
||||
// Close vendor/gossip/taxi window if player walks too far from NPC
|
||||
if (vendorWindowOpen && currentVendorItems.vendorGuid != 0) {
|
||||
auto npc = entityManager.getEntity(currentVendorItems.vendorGuid);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue