mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-02 15:53:51 +00:00
Refactor instance loading: extract initializeRenderers, fix deferred state transition
- Extract initializeRenderers() from loadTestTerrain() so WMO-only maps (dungeons/raids) initialize renderers directly without a dummy ADT path - Defer setState(IN_GAME) until after processing any pending deferred world entry, preventing brief IN_GAME flicker on the wrong map - Remove verbose area trigger debug logging (every-second position spam)
This commit is contained in:
parent
48eb0b70a3
commit
3c55b09a3f
4 changed files with 80 additions and 88 deletions
|
|
@ -71,6 +71,12 @@ public:
|
|||
*/
|
||||
bool loadTestTerrain(pipeline::AssetManager* assetManager, const std::string& adtPath);
|
||||
|
||||
/**
|
||||
* Initialize all sub-renderers (WMO, M2, Character, terrain, water, minimap, etc.)
|
||||
* without loading any ADT tile. Used by WMO-only maps (dungeons/raids/BGs).
|
||||
*/
|
||||
bool initializeRenderers(pipeline::AssetManager* assetManager, const std::string& mapName);
|
||||
|
||||
/**
|
||||
* Enable/disable terrain rendering
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3430,19 +3430,14 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
|
|||
// Initialize renderers if they don't exist yet (first login to a WMO-only map).
|
||||
// On map change, renderers already exist from the previous map.
|
||||
if (!renderer->getWMORenderer() || !renderer->getTerrainManager()) {
|
||||
auto [tileX, tileY] = core::coords::canonicalToTile(spawnCanonical.x, spawnCanonical.y);
|
||||
std::string dummyAdtPath = "World\\Maps\\" + mapName + "\\" + mapName + "_" +
|
||||
std::to_string(tileX) + "_" + std::to_string(tileY) + ".adt";
|
||||
LOG_WARNING("WMO-only: calling loadTestTerrain to create renderers");
|
||||
renderer->loadTestTerrain(assetManager.get(), dummyAdtPath);
|
||||
renderer->initializeRenderers(assetManager.get(), mapName);
|
||||
}
|
||||
|
||||
// Set map name on WMO and terrain renderers
|
||||
// Set map name on WMO renderer and disable terrain streaming (no ADT tiles for instances)
|
||||
if (renderer->getWMORenderer()) {
|
||||
renderer->getWMORenderer()->setMapName(mapName);
|
||||
}
|
||||
if (renderer->getTerrainManager()) {
|
||||
renderer->getTerrainManager()->setMapName(mapName);
|
||||
renderer->getTerrainManager()->setStreamingEnabled(false);
|
||||
}
|
||||
|
||||
|
|
@ -3635,14 +3630,10 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
|
|||
LOG_INFO("Online world terrain loading initiated");
|
||||
}
|
||||
|
||||
// Set map name on the newly-created WMO/terrain renderers
|
||||
// (loadTestTerrain creates them, so the earlier setMapName at line ~3296 was a no-op)
|
||||
// Set map name on WMO renderer (initializeRenderers handles terrain/minimap/worldMap)
|
||||
if (renderer->getWMORenderer()) {
|
||||
renderer->getWMORenderer()->setMapName(mapName);
|
||||
}
|
||||
if (renderer->getTerrainManager()) {
|
||||
renderer->getTerrainManager()->setMapName(mapName);
|
||||
}
|
||||
|
||||
// Character renderer is created inside loadTestTerrain(), so spawn the
|
||||
// player model now that the renderer actually exists.
|
||||
|
|
@ -3873,9 +3864,6 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
|
|||
// Track which map we actually loaded (used by same-map teleport check).
|
||||
loadedMapId_ = mapId;
|
||||
|
||||
// Set game state
|
||||
setState(AppState::IN_GAME);
|
||||
|
||||
// Clear loading flag and process any deferred world entry.
|
||||
// A deferred entry occurs when SMSG_NEW_WORLD arrived during our warmup
|
||||
// (e.g., an area trigger in a dungeon immediately teleporting the player out).
|
||||
|
|
@ -3887,9 +3875,13 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float
|
|||
worldEntryMovementGraceTimer_ = 2.0f;
|
||||
taxiLandingClampTimer_ = 0.0f;
|
||||
lastTaxiFlight_ = false;
|
||||
// Recursive call — sets loadedMapId_ to entry.mapId inside.
|
||||
// Recursive call — sets loadedMapId_ and IN_GAME state for the final map.
|
||||
loadOnlineWorldTerrain(entry.mapId, entry.x, entry.y, entry.z);
|
||||
return; // The recursive call handles setState(IN_GAME).
|
||||
}
|
||||
|
||||
// Only enter IN_GAME when this is the final map (no deferred entry pending).
|
||||
setState(AppState::IN_GAME);
|
||||
}
|
||||
|
||||
void Application::buildCreatureDisplayLookups() {
|
||||
|
|
|
|||
|
|
@ -8795,33 +8795,6 @@ void GameHandler::checkAreaTriggers() {
|
|||
const float py = movementInfo.y;
|
||||
const float pz = movementInfo.z;
|
||||
|
||||
// Debug: log player position periodically to verify trigger proximity
|
||||
static int debugCounter = 0;
|
||||
if (++debugCounter >= 4) { // every ~1s at 0.25s interval
|
||||
debugCounter = 0;
|
||||
int mapTriggerCount = 0;
|
||||
float closestDist = 999999.0f;
|
||||
uint32_t closestId = 0;
|
||||
float closestR = 0, closestBoxL = 0, closestBoxW = 0, closestBoxH = 0;
|
||||
bool closestActive = false;
|
||||
for (const auto& at : areaTriggers_) {
|
||||
if (at.mapId != currentMapId_) continue;
|
||||
mapTriggerCount++;
|
||||
float dx = px - at.x, dy = py - at.y, dz = pz - at.z;
|
||||
float dist = std::sqrt(dx*dx + dy*dy + dz*dz);
|
||||
if (dist < closestDist) {
|
||||
closestDist = dist; closestId = at.id;
|
||||
closestR = at.radius; closestBoxL = at.boxLength; closestBoxW = at.boxWidth; closestBoxH = at.boxHeight;
|
||||
closestActive = activeAreaTriggers_.count(at.id) > 0;
|
||||
}
|
||||
}
|
||||
LOG_WARNING("AreaTrigger check: player=(", px, ", ", py, ", ", pz,
|
||||
") map=", currentMapId_, " closest=AT", closestId,
|
||||
" dist=", closestDist, " r=", closestR,
|
||||
" box=(", closestBoxL, ",", closestBoxW, ",", closestBoxH,
|
||||
") active=", closestActive);
|
||||
}
|
||||
|
||||
// On first check after map transfer, just mark which triggers we're inside
|
||||
// without firing them — prevents exit portal from immediately sending us back
|
||||
bool suppressFirst = areaTriggerSuppressFirst_;
|
||||
|
|
|
|||
|
|
@ -3344,13 +3344,13 @@ void Renderer::renderWorld(game::World* world, game::GameHandler* gameHandler) {
|
|||
// initPostProcess(), resizePostProcess(), shutdownPostProcess() removed —
|
||||
// post-process pipeline is now handled by Vulkan (Phase 6 cleanup).
|
||||
|
||||
bool Renderer::loadTestTerrain(pipeline::AssetManager* assetManager, const std::string& adtPath) {
|
||||
bool Renderer::initializeRenderers(pipeline::AssetManager* assetManager, const std::string& mapName) {
|
||||
if (!assetManager) {
|
||||
LOG_ERROR("Asset manager is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("Loading test terrain: ", adtPath);
|
||||
LOG_INFO("Initializing renderers for map: ", mapName);
|
||||
|
||||
// Create terrain renderer if not already created
|
||||
if (!terrainRenderer) {
|
||||
|
|
@ -3466,49 +3466,12 @@ bool Renderer::loadTestTerrain(pipeline::AssetManager* assetManager, const std::
|
|||
}
|
||||
}
|
||||
|
||||
// Parse tile coordinates from ADT path
|
||||
// Format: World\Maps\{MapName}\{MapName}_{X}_{Y}.adt
|
||||
int tileX = 32, tileY = 49; // defaults
|
||||
{
|
||||
// Find last path separator
|
||||
size_t lastSep = adtPath.find_last_of("\\/");
|
||||
if (lastSep != std::string::npos) {
|
||||
std::string filename = adtPath.substr(lastSep + 1);
|
||||
// Find first underscore after map name
|
||||
size_t firstUnderscore = filename.find('_');
|
||||
if (firstUnderscore != std::string::npos) {
|
||||
size_t secondUnderscore = filename.find('_', firstUnderscore + 1);
|
||||
if (secondUnderscore != std::string::npos) {
|
||||
size_t dot = filename.find('.', secondUnderscore);
|
||||
if (dot != std::string::npos) {
|
||||
tileX = std::stoi(filename.substr(firstUnderscore + 1, secondUnderscore - firstUnderscore - 1));
|
||||
tileY = std::stoi(filename.substr(secondUnderscore + 1, dot - secondUnderscore - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Extract map name
|
||||
std::string mapName = filename.substr(0, firstUnderscore != std::string::npos ? firstUnderscore : filename.size());
|
||||
terrainManager->setMapName(mapName);
|
||||
if (minimap) {
|
||||
minimap->setMapName(mapName);
|
||||
}
|
||||
if (worldMap) {
|
||||
worldMap->setMapName(mapName);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set map name on sub-renderers
|
||||
if (terrainManager) terrainManager->setMapName(mapName);
|
||||
if (minimap) minimap->setMapName(mapName);
|
||||
if (worldMap) worldMap->setMapName(mapName);
|
||||
|
||||
LOG_INFO("Enqueuing initial tile [", tileX, ",", tileY, "] via terrain manager");
|
||||
|
||||
// Enqueue the initial tile for async loading (avoids long sync stalls)
|
||||
if (!terrainManager->enqueueTile(tileX, tileY)) {
|
||||
LOG_ERROR("Failed to enqueue initial tile [", tileX, ",", tileY, "]");
|
||||
return false;
|
||||
}
|
||||
|
||||
terrainLoaded = true;
|
||||
|
||||
// Initialize music manager with asset manager
|
||||
// Initialize audio managers
|
||||
if (musicManager && assetManager && !cachedAssetManager) {
|
||||
audio::AudioEngine::instance().setAssetManager(assetManager);
|
||||
musicManager->initialize(assetManager);
|
||||
|
|
@ -3569,11 +3532,69 @@ bool Renderer::loadTestTerrain(pipeline::AssetManager* assetManager, const std::
|
|||
cachedAssetManager = assetManager;
|
||||
}
|
||||
|
||||
// Snap camera to ground now that terrain is loaded
|
||||
// Snap camera to ground
|
||||
if (cameraController) {
|
||||
cameraController->reset();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Renderer::loadTestTerrain(pipeline::AssetManager* assetManager, const std::string& adtPath) {
|
||||
if (!assetManager) {
|
||||
LOG_ERROR("Asset manager is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("Loading test terrain: ", adtPath);
|
||||
|
||||
// Extract map name from ADT path for renderer initialization
|
||||
std::string mapName;
|
||||
{
|
||||
size_t lastSep = adtPath.find_last_of("\\/");
|
||||
if (lastSep != std::string::npos) {
|
||||
std::string filename = adtPath.substr(lastSep + 1);
|
||||
size_t firstUnderscore = filename.find('_');
|
||||
mapName = filename.substr(0, firstUnderscore != std::string::npos ? firstUnderscore : filename.size());
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize all sub-renderers
|
||||
if (!initializeRenderers(assetManager, mapName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse tile coordinates from ADT path
|
||||
// Format: World\Maps\{MapName}\{MapName}_{X}_{Y}.adt
|
||||
int tileX = 32, tileY = 49; // defaults
|
||||
{
|
||||
size_t lastSep = adtPath.find_last_of("\\/");
|
||||
if (lastSep != std::string::npos) {
|
||||
std::string filename = adtPath.substr(lastSep + 1);
|
||||
size_t firstUnderscore = filename.find('_');
|
||||
if (firstUnderscore != std::string::npos) {
|
||||
size_t secondUnderscore = filename.find('_', firstUnderscore + 1);
|
||||
if (secondUnderscore != std::string::npos) {
|
||||
size_t dot = filename.find('.', secondUnderscore);
|
||||
if (dot != std::string::npos) {
|
||||
tileX = std::stoi(filename.substr(firstUnderscore + 1, secondUnderscore - firstUnderscore - 1));
|
||||
tileY = std::stoi(filename.substr(secondUnderscore + 1, dot - secondUnderscore - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INFO("Enqueuing initial tile [", tileX, ",", tileY, "] via terrain manager");
|
||||
|
||||
// Enqueue the initial tile for async loading (avoids long sync stalls)
|
||||
if (!terrainManager->enqueueTile(tileX, tileY)) {
|
||||
LOG_ERROR("Failed to enqueue initial tile [", tileX, ",", tileY, "]");
|
||||
return false;
|
||||
}
|
||||
|
||||
terrainLoaded = true;
|
||||
|
||||
LOG_INFO("Test terrain loaded successfully!");
|
||||
LOG_INFO(" Chunks: ", terrainRenderer->getChunkCount());
|
||||
LOG_INFO(" Triangles: ", terrainRenderer->getTriangleCount());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue