mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 09:33:51 +00:00
Add MCLQ water, TaxiPathNode transports, and vanilla M2 particles
- Parse MCLQ sub-chunks in vanilla ADTs for water rendering (WotLK uses MH2O) - Load TaxiPathNode.dbc for MO_TRANSPORT world-coordinate paths (vanilla boats) - Parse data[] from SMSG_GAMEOBJECT_QUERY_RESPONSE (taxiPathId for transports) - Support vanilla M2 particle emitters (504-byte struct, different from WotLK 476) - Add character preview texture diagnostic logging - Fix disconnect handling on character screen (show error only when no chars)
This commit is contained in:
parent
cbb3035313
commit
bf31da8c13
14 changed files with 556 additions and 55 deletions
|
|
@ -389,6 +389,10 @@ public:
|
|||
void queryPlayerName(uint64_t guid);
|
||||
void queryCreatureInfo(uint32_t entry, uint64_t guid);
|
||||
void queryGameObjectInfo(uint32_t entry, uint64_t guid);
|
||||
const GameObjectQueryResponseData* getCachedGameObjectInfo(uint32_t entry) const {
|
||||
auto it = gameObjectInfoCache_.find(entry);
|
||||
return (it != gameObjectInfoCache_.end()) ? &it->second : nullptr;
|
||||
}
|
||||
std::string getCachedPlayerName(uint64_t guid) const;
|
||||
std::string getCachedCreatureName(uint32_t entry) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,13 @@ public:
|
|||
return NameQueryResponseParser::parse(packet, data);
|
||||
}
|
||||
|
||||
// --- GameObject Query ---
|
||||
|
||||
/** Parse SMSG_GAMEOBJECT_QUERY_RESPONSE */
|
||||
virtual bool parseGameObjectQueryResponse(network::Packet& packet, GameObjectQueryResponseData& data) {
|
||||
return GameObjectQueryResponseParser::parse(packet, data);
|
||||
}
|
||||
|
||||
// --- Gossip ---
|
||||
|
||||
/** Parse SMSG_GOSSIP_MESSAGE */
|
||||
|
|
@ -233,6 +240,7 @@ public:
|
|||
network::Packet buildCastSpell(uint32_t spellId, uint64_t targetGuid, uint8_t castCount) override;
|
||||
bool parseCastFailed(network::Packet& packet, CastFailedData& data) override;
|
||||
bool parseMessageChat(network::Packet& packet, MessageChatData& data) override;
|
||||
bool parseGameObjectQueryResponse(network::Packet& packet, GameObjectQueryResponseData& data) override;
|
||||
bool parseGossipMessage(network::Packet& packet, GossipMessageData& data) override;
|
||||
bool parseGuildRoster(network::Packet& packet, GuildRosterData& data) override;
|
||||
bool parseGuildQueryResponse(network::Packet& packet, GuildQueryResponseData& data) override;
|
||||
|
|
|
|||
|
|
@ -29,12 +29,14 @@ struct TransportPath {
|
|||
uint32_t durationMs; // Total loop duration in ms (includes wrap segment if added)
|
||||
bool zOnly; // True if path only has Z movement (elevator/bobbing), false if real XY travel
|
||||
bool fromDBC; // True if loaded from TransportAnimation.dbc, false for runtime fallback/custom paths
|
||||
bool worldCoords = false; // True if points are absolute world coords (TaxiPathNode), not local offsets
|
||||
};
|
||||
|
||||
struct ActiveTransport {
|
||||
uint64_t guid; // Entity GUID
|
||||
uint32_t wmoInstanceId; // WMO renderer instance ID
|
||||
uint32_t pathId; // Current path
|
||||
uint32_t entry = 0; // GameObject entry (for MO_TRANSPORT path updates)
|
||||
glm::vec3 basePosition; // Spawn position (base offset for path)
|
||||
glm::vec3 position; // Current world position
|
||||
glm::quat rotation; // Current world rotation
|
||||
|
|
@ -79,7 +81,7 @@ public:
|
|||
void setWMORenderer(rendering::WMORenderer* renderer) { wmoRenderer_ = renderer; }
|
||||
|
||||
void update(float deltaTime);
|
||||
void registerTransport(uint64_t guid, uint32_t wmoInstanceId, uint32_t pathId, const glm::vec3& spawnWorldPos);
|
||||
void registerTransport(uint64_t guid, uint32_t wmoInstanceId, uint32_t pathId, const glm::vec3& spawnWorldPos, uint32_t entry = 0);
|
||||
void unregisterTransport(uint64_t guid);
|
||||
|
||||
ActiveTransport* getTransport(uint64_t guid);
|
||||
|
|
@ -92,6 +94,16 @@ public:
|
|||
// Load transport paths from TransportAnimation.dbc
|
||||
bool loadTransportAnimationDBC(pipeline::AssetManager* assetMgr);
|
||||
|
||||
// Load transport paths from TaxiPathNode.dbc (world-coordinate paths for MO_TRANSPORT)
|
||||
bool loadTaxiPathNodeDBC(pipeline::AssetManager* assetMgr);
|
||||
|
||||
// Check if a TaxiPathNode path exists for a given taxiPathId
|
||||
bool hasTaxiPath(uint32_t taxiPathId) const;
|
||||
|
||||
// Assign a TaxiPathNode path to an existing transport (called when GO query response arrives)
|
||||
// Returns true if the transport was updated
|
||||
bool assignTaxiPathToTransport(uint32_t entry, uint32_t taxiPathId);
|
||||
|
||||
// Check if a path exists for a given GameObject entry
|
||||
bool hasPathForEntry(uint32_t entry) const;
|
||||
// Check if a path has meaningful XY travel (used to reject near-stationary false positives).
|
||||
|
|
@ -126,7 +138,8 @@ private:
|
|||
void updateTransformMatrices(ActiveTransport& transport);
|
||||
|
||||
std::unordered_map<uint64_t, ActiveTransport> transports_;
|
||||
std::unordered_map<uint32_t, TransportPath> paths_; // Indexed by transportEntry (pathId from TransportAnimation.dbc)
|
||||
std::unordered_map<uint32_t, TransportPath> paths_; // Indexed by transportEntry (pathId from TransportAnimation.dbc)
|
||||
std::unordered_map<uint32_t, TransportPath> taxiPaths_; // Indexed by TaxiPath.dbc ID (world-coord paths for MO_TRANSPORT)
|
||||
rendering::WMORenderer* wmoRenderer_ = nullptr;
|
||||
bool clientSideAnimation_ = false; // DISABLED - use server positions instead of client prediction
|
||||
float elapsedTime_ = 0.0f; // Total elapsed time (seconds)
|
||||
|
|
|
|||
|
|
@ -1356,7 +1356,10 @@ public:
|
|||
struct GameObjectQueryResponseData {
|
||||
uint32_t entry = 0;
|
||||
std::string name;
|
||||
uint32_t type = 0; // GameObjectType (e.g. 3=chest, 2=questgiver)
|
||||
uint32_t type = 0; // GameObjectType (e.g. 3=chest, 2=questgiver, 15=MO_TRANSPORT)
|
||||
uint32_t displayId = 0;
|
||||
uint32_t data[24] = {}; // Type-specific data fields (e.g. data[0]=taxiPathId for MO_TRANSPORT)
|
||||
bool hasData = false; // Whether data[] was parsed
|
||||
|
||||
bool isValid() const { return entry != 0 && !name.empty(); }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -206,6 +206,8 @@ private:
|
|||
static void parseMCLY(const uint8_t* data, size_t size, MapChunk& chunk);
|
||||
static void parseMCAL(const uint8_t* data, size_t size, MapChunk& chunk);
|
||||
static void parseMH2O(const uint8_t* data, size_t size, ADTTerrain& terrain);
|
||||
static void parseMCLQ(const uint8_t* data, size_t size, int chunkIndex,
|
||||
uint32_t mcnkFlags, ADTTerrain& terrain);
|
||||
};
|
||||
|
||||
} // namespace pipeline
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue