diff --git a/src/core/application.cpp b/src/core/application.cpp index 7b51c8b1..4efc3557 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -5327,19 +5327,26 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float glm::vec3(x, y, z)); float rx = renderSpawn.x, ry = renderSpawn.y, rz = renderSpawn.z; - // Check terrain - if (auto* tm = renderer->getTerrainManager()) { - if (tm->getHeightAt(rx, ry).has_value()) groundReady = true; - } - // Check WMO floor (cities, buildings) - if (!groundReady) { - if (auto* wmo = renderer->getWMORenderer()) { - if (wmo->getFloorHeight(rx, ry, rz + 5.0f).has_value()) groundReady = true; + // Check WMO floor FIRST (cities like Stormwind stand on WMO floors). + // Terrain exists below WMOs but at the wrong height. + if (auto* wmo = renderer->getWMORenderer()) { + auto wmoH = wmo->getFloorHeight(rx, ry, rz + 5.0f); + if (wmoH.has_value() && std::abs(*wmoH - rz) < 15.0f) { + groundReady = true; } } - // After minimum warmup, also accept if enough terrain tiles are loaded - // (player may be on M2 collision or other surface) - if (!groundReady && elapsed >= 8.0f) { + // Check terrain — but only if it's close to spawn Z (within 15 units). + // Terrain far below a WMO city doesn't count as ground. + if (!groundReady) { + if (auto* tm = renderer->getTerrainManager()) { + auto tH = tm->getHeightAt(rx, ry); + if (tH.has_value() && std::abs(*tH - rz) < 15.0f) { + groundReady = true; + } + } + } + // After 10s, accept any loaded terrain (fallback for unusual spawns) + if (!groundReady && elapsed >= 10.0f) { if (auto* tm = renderer->getTerrainManager()) { groundReady = (tm->getLoadedTileCount() >= 4); } diff --git a/src/game/inventory_handler.cpp b/src/game/inventory_handler.cpp index 5c468306..a7602b5d 100644 --- a/src/game/inventory_handler.cpp +++ b/src/game/inventory_handler.cpp @@ -1086,12 +1086,17 @@ void InventoryHandler::useItemBySlot(int backpackIndex) { break; } } + LOG_WARNING("useItemBySlot: item='", slot.item.name, "' entry=", slot.item.itemId, + " guid=0x", std::hex, itemGuid, std::dec, + " spellId=", useSpellId, " spellCount=", info->spells.size()); } auto packet = owner_.packetParsers_ ? owner_.packetParsers_->buildUseItem(0xFF, static_cast(23 + backpackIndex), itemGuid, useSpellId) : UseItemPacket::build(0xFF, static_cast(23 + backpackIndex), itemGuid, useSpellId); owner_.socket->send(packet); } else if (itemGuid == 0) { + LOG_WARNING("useItemBySlot: itemGuid=0 for item='", slot.item.name, + "' entry=", slot.item.itemId, " — cannot use"); owner_.addSystemChatMessage("Cannot use that item right now."); } }