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

@ -2802,16 +2802,26 @@ network::Packet QuestgiverAcceptQuestPacket::build(uint64_t npcGuid, uint32_t qu
network::Packet packet(wireOpcode(Opcode::CMSG_QUESTGIVER_ACCEPT_QUEST));
packet.writeUInt64(npcGuid);
packet.writeUInt32(questId);
packet.writeUInt32(0); // unused
return packet;
}
bool QuestDetailsParser::parse(network::Packet& packet, QuestDetailsData& data) {
if (packet.getSize() < 28) return false;
if (packet.getSize() < 20) return false;
data.npcGuid = packet.readUInt64();
// WotLK has informUnit(u64) before questId; Vanilla/TBC do not.
// Detect: try WotLK first (read informUnit + questId), then check if title
// string looks valid. If not, rewind and try vanilla (questId directly).
size_t preInform = packet.getReadPos();
/*informUnit*/ packet.readUInt64();
data.questId = packet.readUInt32();
data.title = packet.readString();
if (data.title.empty() || data.questId > 100000) {
// Likely vanilla format — rewind past informUnit
packet.setReadPos(preInform);
data.questId = packet.readUInt32();
data.title = packet.readString();
}
data.details = packet.readString();
data.objectives = packet.readString();