Fix Turtle WoW compatibility: NPC spawning, quests, spells, realm display, and music

- Add TurtlePacketParsers with dedicated movement block parser (Classic format + transport timestamp)
- Fix quest giver status: read uint32 and translate vanilla enum values for Classic/Turtle
- Fix quest accept packet: remove trailing uint32 that vanilla servers reject
- Fix quest details parser: auto-detect vanilla vs WotLK format (informUnit field)
- Fix spellbook and action bar icons: fallback to WotLK DBC field indices when expansion layout fails
- Fix spell cast failure messages: translate vanilla SpellCastResult codes (+1 offset)
- Fix realm list: correct type values (6=RP, 8=RP-PvP) and population thresholds
- Fix music: disable looping for zone music, auto-advance to next random track when finished
- Add music anti-repeat: avoid playing the same track back-to-back
- Make TBC update block parsing resilient (keep parsed blocks on failure instead of aborting)
- Add right-click attack on hostile mobs
- Add name query diagnostic logging
This commit is contained in:
Kelsi 2026-02-17 05:27:03 -08:00
parent d850fe6fc0
commit 36fc1df706
12 changed files with 358 additions and 48 deletions

View file

@ -148,6 +148,15 @@ public:
return GossipMessageParser::parse(packet, data);
}
// --- Quest Giver Status ---
/** Read quest giver status from packet.
* WotLK: uint8, vanilla/classic: uint32 with different enum values.
* Returns the status value normalized to WotLK enum values. */
virtual uint8_t readQuestGiverStatus(network::Packet& packet) {
return packet.readUInt8();
}
// --- Destroy Object ---
/** Parse SMSG_DESTROY_OBJECT */
@ -294,13 +303,31 @@ public:
network::Packet buildMailDelete(uint64_t mailboxGuid, uint32_t mailId, uint32_t mailTemplateId) override;
network::Packet buildItemQuery(uint32_t entry, uint64_t guid) override;
bool parseItemQueryResponse(network::Packet& packet, ItemQueryResponseData& data) override;
uint8_t readQuestGiverStatus(network::Packet& packet) override;
};
/**
* Turtle WoW (build 7234) packet parsers.
*
* Turtle WoW is a heavily modified vanilla server that sends TBC-style
* movement blocks (moveFlags2, transport timestamps, 8 speeds including flight)
* while keeping all other Classic packet formats.
*
* Inherits all Classic overrides (charEnum, chat, gossip, mail, items, etc.)
* but delegates movement block parsing to TBC format.
*/
class TurtlePacketParsers : public ClassicPacketParsers {
public:
uint8_t movementFlags2Size() const override { return 0; }
bool parseMovementBlock(network::Packet& packet, UpdateBlock& block) override;
};
/**
* Factory function to create the right parser set for an expansion.
*/
inline std::unique_ptr<PacketParsers> createPacketParsers(const std::string& expansionId) {
if (expansionId == "classic" || expansionId == "turtle") return std::make_unique<ClassicPacketParsers>();
if (expansionId == "classic") return std::make_unique<ClassicPacketParsers>();
if (expansionId == "turtle") return std::make_unique<TurtlePacketParsers>();
if (expansionId == "tbc") return std::make_unique<TbcPacketParsers>();
return std::make_unique<WotlkPacketParsers>();
}

View file

@ -20,13 +20,14 @@ public:
uint32_t getZoneId(int tileX, int tileY) const;
const ZoneInfo* getZoneInfo(uint32_t zoneId) const;
std::string getRandomMusic(uint32_t zoneId) const;
std::string getRandomMusic(uint32_t zoneId);
std::vector<std::string> getAllMusicPaths() const;
private:
// tile key = tileX * 100 + tileY
std::unordered_map<int, uint32_t> tileToZone;
std::unordered_map<uint32_t, ZoneInfo> zones;
std::string lastPlayedMusic_;
};
} // namespace game