mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 09:33:51 +00:00
terrain: pre-load bind point tiles during Hearthstone cast
When the player starts casting Hearthstone (spell IDs 6948/8690), trigger background terrain loading at the bind point so tiles are ready when the teleport fires. - Add HearthstonePreloadCallback to GameHandler, called from handleSpellStart when a Hearthstone cast begins. - Application callback enqueues a 5×5 tile grid around the bind point via precacheTiles() (same-map) or starts a file-cache warm via startWorldPreload() (cross-map) during the ~10 s cast time. - On same-map teleport arrival, call processAllReadyTiles() to GPU-upload any tiles that finished parsing during the cast before the first frame at the new position. Fixes: player landing in unloaded terrain and falling after Hearthstone.
This commit is contained in:
parent
0a6f88e8ad
commit
8f0d2cc4ab
3 changed files with 64 additions and 0 deletions
|
|
@ -610,6 +610,12 @@ public:
|
||||||
using BindPointCallback = std::function<void(uint32_t mapId, float x, float y, float z)>;
|
using BindPointCallback = std::function<void(uint32_t mapId, float x, float y, float z)>;
|
||||||
void setBindPointCallback(BindPointCallback cb) { bindPointCallback_ = std::move(cb); }
|
void setBindPointCallback(BindPointCallback cb) { bindPointCallback_ = std::move(cb); }
|
||||||
|
|
||||||
|
// Called when the player starts casting Hearthstone so terrain at the bind
|
||||||
|
// point can be pre-loaded during the cast time.
|
||||||
|
// Parameters: mapId and canonical (x, y, z) of the bind location.
|
||||||
|
using HearthstonePreloadCallback = std::function<void(uint32_t mapId, float x, float y, float z)>;
|
||||||
|
void setHearthstonePreloadCallback(HearthstonePreloadCallback cb) { hearthstonePreloadCallback_ = std::move(cb); }
|
||||||
|
|
||||||
// Creature spawn callback (online mode - triggered when creature enters view)
|
// Creature spawn callback (online mode - triggered when creature enters view)
|
||||||
// Parameters: guid, displayId, x, y, z (canonical), orientation
|
// Parameters: guid, displayId, x, y, z (canonical), orientation
|
||||||
using CreatureSpawnCallback = std::function<void(uint64_t guid, uint32_t displayId, float x, float y, float z, float orientation)>;
|
using CreatureSpawnCallback = std::function<void(uint64_t guid, uint32_t displayId, float x, float y, float z, float orientation)>;
|
||||||
|
|
@ -1683,6 +1689,7 @@ private:
|
||||||
UnstuckCallback unstuckGyCallback_;
|
UnstuckCallback unstuckGyCallback_;
|
||||||
UnstuckCallback unstuckHearthCallback_;
|
UnstuckCallback unstuckHearthCallback_;
|
||||||
BindPointCallback bindPointCallback_;
|
BindPointCallback bindPointCallback_;
|
||||||
|
HearthstonePreloadCallback hearthstonePreloadCallback_;
|
||||||
CreatureSpawnCallback creatureSpawnCallback_;
|
CreatureSpawnCallback creatureSpawnCallback_;
|
||||||
CreatureDespawnCallback creatureDespawnCallback_;
|
CreatureDespawnCallback creatureDespawnCallback_;
|
||||||
PlayerSpawnCallback playerSpawnCallback_;
|
PlayerSpawnCallback playerSpawnCallback_;
|
||||||
|
|
|
||||||
|
|
@ -1710,6 +1710,10 @@ void Application::setupUICallbacks() {
|
||||||
renderer->getCameraController()->clearMovementInputs();
|
renderer->getCameraController()->clearMovementInputs();
|
||||||
renderer->getCameraController()->suppressMovementFor(0.5f);
|
renderer->getCameraController()->suppressMovementFor(0.5f);
|
||||||
}
|
}
|
||||||
|
// Flush any tiles that finished background parsing during the cast
|
||||||
|
// (e.g. Hearthstone pre-loaded them) so they're GPU-uploaded before
|
||||||
|
// the first frame at the new position.
|
||||||
|
renderer->getTerrainManager()->processAllReadyTiles();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1950,6 +1954,51 @@ void Application::setupUICallbacks() {
|
||||||
LOG_INFO("Bindpoint set: mapId=", mapId, " pos=(", x, ", ", y, ", ", z, ")");
|
LOG_INFO("Bindpoint set: mapId=", mapId, " pos=(", x, ", ", y, ", ", z, ")");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Hearthstone preload callback: begin loading terrain at the bind point as soon as
|
||||||
|
// the player starts casting Hearthstone. The ~10 s cast gives enough time for
|
||||||
|
// the background streaming workers to bring tiles into the cache so the player
|
||||||
|
// lands on solid ground instead of falling through un-loaded terrain.
|
||||||
|
gameHandler->setHearthstonePreloadCallback([this](uint32_t mapId, float x, float y, float z) {
|
||||||
|
if (!renderer || !assetManager) return;
|
||||||
|
|
||||||
|
auto* terrainMgr = renderer->getTerrainManager();
|
||||||
|
if (!terrainMgr) return;
|
||||||
|
|
||||||
|
// Resolve map name from the cached Map.dbc table
|
||||||
|
std::string mapName;
|
||||||
|
if (auto it = mapNameById_.find(mapId); it != mapNameById_.end()) {
|
||||||
|
mapName = it->second;
|
||||||
|
} else {
|
||||||
|
mapName = mapIdToName(mapId);
|
||||||
|
}
|
||||||
|
if (mapName.empty()) mapName = "Azeroth";
|
||||||
|
|
||||||
|
if (mapId == loadedMapId_) {
|
||||||
|
// Same map: pre-enqueue tiles around the bind point so workers start
|
||||||
|
// loading them now. Uses render-space coords (canonicalToRender).
|
||||||
|
glm::vec3 renderPos = core::coords::canonicalToRender(glm::vec3(x, y, z));
|
||||||
|
auto [tileX, tileY] = core::coords::worldToTile(renderPos.x, renderPos.y);
|
||||||
|
|
||||||
|
std::vector<std::pair<int,int>> tiles;
|
||||||
|
tiles.reserve(25);
|
||||||
|
for (int dy = -2; dy <= 2; dy++)
|
||||||
|
for (int dx = -2; dx <= 2; dx++)
|
||||||
|
tiles.push_back({tileX + dx, tileY + dy});
|
||||||
|
|
||||||
|
terrainMgr->precacheTiles(tiles);
|
||||||
|
LOG_INFO("Hearthstone preload: enqueued ", tiles.size(),
|
||||||
|
" tiles around bind point (same map) tile=[", tileX, ",", tileY, "]");
|
||||||
|
} else {
|
||||||
|
// Different map: warm the file cache so ADT parsing is fast when
|
||||||
|
// loadOnlineWorldTerrain runs its blocking load loop.
|
||||||
|
// homeBindPos_ is canonical; startWorldPreload expects server coords.
|
||||||
|
glm::vec3 server = core::coords::canonicalToServer(glm::vec3(x, y, z));
|
||||||
|
startWorldPreload(mapId, mapName, server.x, server.y);
|
||||||
|
LOG_INFO("Hearthstone preload: started file cache warm for map '", mapName,
|
||||||
|
"' (id=", mapId, ")");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Faction hostility map is built in buildFactionHostilityMap() when character enters world
|
// Faction hostility map is built in buildFactionHostilityMap() when character enters world
|
||||||
|
|
||||||
// Creature spawn callback (online mode) - spawn creature models
|
// Creature spawn callback (online mode) - spawn creature models
|
||||||
|
|
|
||||||
|
|
@ -12430,6 +12430,14 @@ void GameHandler::handleSpellStart(network::Packet& packet) {
|
||||||
ssm->playPrecast(school, audio::SpellSoundManager::SpellPower::MEDIUM);
|
ssm->playPrecast(school, audio::SpellSoundManager::SpellPower::MEDIUM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hearthstone cast: begin pre-loading terrain at bind point during cast time
|
||||||
|
// so tiles are ready when the teleport fires (avoids falling through un-loaded terrain).
|
||||||
|
// Spell IDs: 6948 = Vanilla Hearthstone (rank 1), 8690 = TBC/WotLK Hearthstone
|
||||||
|
const bool isHearthstone = (data.spellId == 6948 || data.spellId == 8690);
|
||||||
|
if (isHearthstone && hasHomeBind_ && hearthstonePreloadCallback_) {
|
||||||
|
hearthstonePreloadCallback_(homeBindMapId_, homeBindPos_.x, homeBindPos_.y, homeBindPos_.z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue