mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix MLIQ water parsing, skip interior water, clear movement on teleport
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
- Remove bogus 2-byte skip after materialId in MLIQ parser that shifted all vertex heights and tile flags by 2 bytes (garbage data) - Skip liquid loading for interior WMO groups (flag 0x2000) to prevent indoor water from rendering as outdoor canal water - Clear movement inputs on teleport/portal to prevent auto-running after zone transfer (held keys persist through loading screen)
This commit is contained in:
parent
16daa2baf7
commit
08d40583c9
4 changed files with 15 additions and 11 deletions
|
|
@ -970,6 +970,10 @@ void Application::update(float deltaTime) {
|
||||||
bool onTransportNow = gameHandler && gameHandler->isOnTransport();
|
bool onTransportNow = gameHandler && gameHandler->isOnTransport();
|
||||||
if (worldEntryMovementGraceTimer_ > 0.0f) {
|
if (worldEntryMovementGraceTimer_ > 0.0f) {
|
||||||
worldEntryMovementGraceTimer_ -= deltaTime;
|
worldEntryMovementGraceTimer_ -= deltaTime;
|
||||||
|
// Clear stale movement from before teleport each frame
|
||||||
|
// until grace period expires (keys may still be held)
|
||||||
|
if (renderer && renderer->getCameraController())
|
||||||
|
renderer->getCameraController()->clearMovementInputs();
|
||||||
}
|
}
|
||||||
if (renderer && renderer->getCameraController()) {
|
if (renderer && renderer->getCameraController()) {
|
||||||
const bool externallyDrivenMotion = onTaxi || onTransportNow || chargeActive_;
|
const bool externallyDrivenMotion = onTaxi || onTransportNow || chargeActive_;
|
||||||
|
|
@ -1550,6 +1554,9 @@ void Application::setupUICallbacks() {
|
||||||
worldEntryMovementGraceTimer_ = 2.0f;
|
worldEntryMovementGraceTimer_ = 2.0f;
|
||||||
taxiLandingClampTimer_ = 0.0f;
|
taxiLandingClampTimer_ = 0.0f;
|
||||||
lastTaxiFlight_ = false;
|
lastTaxiFlight_ = false;
|
||||||
|
// Stop any movement that was active before the teleport
|
||||||
|
if (renderer->getCameraController())
|
||||||
|
renderer->getCameraController()->clearMovementInputs();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1565,6 +1572,9 @@ void Application::setupUICallbacks() {
|
||||||
worldEntryMovementGraceTimer_ = 2.0f;
|
worldEntryMovementGraceTimer_ = 2.0f;
|
||||||
taxiLandingClampTimer_ = 0.0f;
|
taxiLandingClampTimer_ = 0.0f;
|
||||||
lastTaxiFlight_ = false;
|
lastTaxiFlight_ = false;
|
||||||
|
// Stop any movement that was active before the teleport
|
||||||
|
if (renderer && renderer->getCameraController())
|
||||||
|
renderer->getCameraController()->clearMovementInputs();
|
||||||
loadOnlineWorldTerrain(mapId, x, y, z);
|
loadOnlineWorldTerrain(mapId, x, y, z);
|
||||||
// loadedMapId_ is set inside loadOnlineWorldTerrain (including
|
// loadedMapId_ is set inside loadOnlineWorldTerrain (including
|
||||||
// any deferred entries it processes), so we must NOT override it here.
|
// any deferred entries it processes), so we must NOT override it here.
|
||||||
|
|
|
||||||
|
|
@ -586,10 +586,6 @@ bool WMOLoader::loadGroup(const std::vector<uint8_t>& groupData,
|
||||||
group.liquid.basePosition.y = read<float>(groupData, parseOffset);
|
group.liquid.basePosition.y = read<float>(groupData, parseOffset);
|
||||||
group.liquid.basePosition.z = read<float>(groupData, parseOffset);
|
group.liquid.basePosition.z = read<float>(groupData, parseOffset);
|
||||||
group.liquid.materialId = read<uint16_t>(groupData, parseOffset);
|
group.liquid.materialId = read<uint16_t>(groupData, parseOffset);
|
||||||
if (parseOffset + sizeof(uint16_t) <= subChunkEnd) {
|
|
||||||
// Reserved/flags in some WMO liquid variants.
|
|
||||||
parseOffset += sizeof(uint16_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep parser resilient across minor format variants:
|
// Keep parser resilient across minor format variants:
|
||||||
// prefer explicit per-vertex floats, otherwise fall back to flat.
|
// prefer explicit per-vertex floats, otherwise fall back to flat.
|
||||||
|
|
|
||||||
|
|
@ -837,10 +837,11 @@ bool TerrainManager::advanceFinalization(FinalizingTile& ft) {
|
||||||
modelMatrix = glm::rotate(modelMatrix, wmoReady.rotation.y, glm::vec3(0.0f, 1.0f, 0.0f));
|
modelMatrix = glm::rotate(modelMatrix, wmoReady.rotation.y, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
modelMatrix = glm::rotate(modelMatrix, wmoReady.rotation.x, glm::vec3(1.0f, 0.0f, 0.0f));
|
modelMatrix = glm::rotate(modelMatrix, wmoReady.rotation.x, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
for (const auto& group : wmoReady.model.groups) {
|
for (const auto& group : wmoReady.model.groups) {
|
||||||
if (group.liquid.hasLiquid()) {
|
if (!group.liquid.hasLiquid()) continue;
|
||||||
waterRenderer->loadFromWMO(group.liquid, modelMatrix, wmoInstId);
|
// Skip interior groups — their liquid is for indoor areas
|
||||||
loadedLiquids++;
|
if (group.flags & 0x2000) continue;
|
||||||
}
|
waterRenderer->loadFromWMO(group.liquid, modelMatrix, wmoInstId);
|
||||||
|
loadedLiquids++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -875,8 +875,6 @@ void WaterRenderer::loadFromWMO([[maybe_unused]] const pipeline::WMOLiquid& liqu
|
||||||
const int vertexCount = gridWidth * gridHeight;
|
const int vertexCount = gridWidth * gridHeight;
|
||||||
|
|
||||||
// WMO liquid base heights sit ~2 units above the visual waterline.
|
// WMO liquid base heights sit ~2 units above the visual waterline.
|
||||||
// Lower them to match surrounding terrain water and prevent clipping
|
|
||||||
// at bridge edges and walkways.
|
|
||||||
constexpr float WMO_WATER_Z_OFFSET = -1.0f;
|
constexpr float WMO_WATER_Z_OFFSET = -1.0f;
|
||||||
float adjustedZ = surface.origin.z + WMO_WATER_Z_OFFSET;
|
float adjustedZ = surface.origin.z + WMO_WATER_Z_OFFSET;
|
||||||
surface.heights.assign(vertexCount, adjustedZ);
|
surface.heights.assign(vertexCount, adjustedZ);
|
||||||
|
|
@ -895,7 +893,6 @@ void WaterRenderer::loadFromWMO([[maybe_unused]] const pipeline::WMOLiquid& liqu
|
||||||
for (size_t t = 0; t < tileCount; t++) {
|
for (size_t t = 0; t < tileCount; t++) {
|
||||||
bool hasLiquid = true;
|
bool hasLiquid = true;
|
||||||
if (t < liquid.flags.size()) {
|
if (t < liquid.flags.size()) {
|
||||||
// In WoW MLIQ format, (flags & 0x0F) == 0x0F means "no liquid" for this tile
|
|
||||||
if ((liquid.flags[t] & 0x0F) == 0x0F) {
|
if ((liquid.flags[t] & 0x0F) == 0x0F) {
|
||||||
hasLiquid = false;
|
hasLiquid = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue