mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-25 00:20:16 +00:00
Add instance support: WDT parser, WMO-only map loading, area triggers, BG queue accept
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
- WDT parser detects WMO-only maps (dungeons/raids/BGs) via MPHD flag 0x01 - WMO-only loading branch in loadOnlineWorldTerrain loads root WMO directly - Area trigger system: loads AreaTrigger.dbc, checks player proximity, sends CMSG_AREATRIGGER - BG queue acceptance via /join command sending CMSG_BATTLEFIELD_PORT - SMSG_INSTANCE_DIFFICULTY handler stub - Map change cleanup (clear old WMO/M2/terrain on map transfer) - 5-second area trigger cooldown after map transfer to prevent ping-pong loops
This commit is contained in:
parent
a559d5944b
commit
d0e8b44866
7 changed files with 750 additions and 109 deletions
110
src/pipeline/wdt_loader.cpp
Normal file
110
src/pipeline/wdt_loader.cpp
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#include "pipeline/wdt_loader.hpp"
|
||||
#include "core/logger.hpp"
|
||||
#include <cstring>
|
||||
|
||||
namespace wowee {
|
||||
namespace pipeline {
|
||||
|
||||
namespace {
|
||||
|
||||
uint32_t readU32(const uint8_t* data, size_t offset) {
|
||||
uint32_t v;
|
||||
std::memcpy(&v, data + offset, 4);
|
||||
return v;
|
||||
}
|
||||
|
||||
uint16_t readU16(const uint8_t* data, size_t offset) {
|
||||
uint16_t v;
|
||||
std::memcpy(&v, data + offset, 2);
|
||||
return v;
|
||||
}
|
||||
|
||||
float readF32(const uint8_t* data, size_t offset) {
|
||||
float v;
|
||||
std::memcpy(&v, data + offset, 4);
|
||||
return v;
|
||||
}
|
||||
|
||||
// Chunk magic constants (little-endian)
|
||||
constexpr uint32_t MVER = 0x5245564D; // "REVM"
|
||||
constexpr uint32_t MPHD = 0x4448504D; // "DHPM"
|
||||
constexpr uint32_t MAIN = 0x4E49414D; // "NIAM"
|
||||
constexpr uint32_t MWMO = 0x4F4D574D; // "OMWM"
|
||||
constexpr uint32_t MODF = 0x46444F4D; // "FDOM"
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
WDTInfo parseWDT(const std::vector<uint8_t>& data) {
|
||||
WDTInfo info;
|
||||
|
||||
if (data.size() < 8) {
|
||||
LOG_WARNING("WDT data too small (", data.size(), " bytes)");
|
||||
return info;
|
||||
}
|
||||
|
||||
size_t offset = 0;
|
||||
|
||||
while (offset + 8 <= data.size()) {
|
||||
uint32_t magic = readU32(data.data(), offset);
|
||||
uint32_t chunkSize = readU32(data.data(), offset + 4);
|
||||
|
||||
if (offset + 8 + chunkSize > data.size()) {
|
||||
LOG_WARNING("WDT chunk extends beyond file at offset ", offset);
|
||||
break;
|
||||
}
|
||||
|
||||
const uint8_t* chunkData = data.data() + offset + 8;
|
||||
|
||||
if (magic == MVER) {
|
||||
if (chunkSize >= 4) {
|
||||
uint32_t version = readU32(chunkData, 0);
|
||||
LOG_DEBUG("WDT version: ", version);
|
||||
}
|
||||
} else if (magic == MPHD) {
|
||||
if (chunkSize >= 4) {
|
||||
info.mphdFlags = readU32(chunkData, 0);
|
||||
LOG_DEBUG("WDT MPHD flags: 0x", std::hex, info.mphdFlags, std::dec);
|
||||
}
|
||||
} else if (magic == MWMO) {
|
||||
// Null-terminated WMO path string(s)
|
||||
if (chunkSize > 0) {
|
||||
const char* str = reinterpret_cast<const char*>(chunkData);
|
||||
size_t len = std::strlen(str);
|
||||
if (len > 0) {
|
||||
info.rootWMOPath = std::string(str, len);
|
||||
LOG_DEBUG("WDT root WMO: ", info.rootWMOPath);
|
||||
}
|
||||
}
|
||||
} else if (magic == MODF) {
|
||||
// MODF entry is 64 bytes (same layout as ADT MODF)
|
||||
if (chunkSize >= 64) {
|
||||
// nameId at offset 0 (unused for WDT — path comes from MWMO)
|
||||
// uniqueId at offset 4
|
||||
info.position[0] = readF32(chunkData, 8);
|
||||
info.position[1] = readF32(chunkData, 12);
|
||||
info.position[2] = readF32(chunkData, 16);
|
||||
info.rotation[0] = readF32(chunkData, 20);
|
||||
info.rotation[1] = readF32(chunkData, 24);
|
||||
info.rotation[2] = readF32(chunkData, 28);
|
||||
// extents at 32-55
|
||||
info.flags = readU16(chunkData, 56);
|
||||
info.doodadSet = readU16(chunkData, 58);
|
||||
LOG_DEBUG("WDT MODF placement: pos=(", info.position[0], ", ",
|
||||
info.position[1], ", ", info.position[2], ") rot=(",
|
||||
info.rotation[0], ", ", info.rotation[1], ", ",
|
||||
info.rotation[2], ") doodadSet=", info.doodadSet);
|
||||
}
|
||||
}
|
||||
|
||||
offset += 8 + chunkSize;
|
||||
}
|
||||
|
||||
LOG_WARNING("WDT parse result: mphdFlags=0x", std::hex, info.mphdFlags, std::dec,
|
||||
" isWMOOnly=", info.isWMOOnly(),
|
||||
" rootWMO='", info.rootWMOPath, "'");
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue