mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
fix: use expansion-aware explored zone count to prevent fog-of-war corruption
Classic 1.12 and Turtle WoW have only 64 PLAYER_EXPLORED_ZONES uint32 fields (zone IDs pack into 2048 bits). TBC and WotLK use 128 (needed for Outland/Northrend zone IDs up to bit 4095). The hardcoded PLAYER_EXPLORED_ZONES_COUNT=128 caused extractExploredZoneFields to read 64 extra fields beyond the actual zone block in Classic/Turtle — consuming PLAYER_REST_STATE_EXPERIENCE, PLAYER_FIELD_COINAGE, and character- points fields as zone flags. On the world map, this could mark zones as explored based on random bit patterns in those unrelated fields. Add `exploredZonesCount()` virtual method to PacketParsers (default=128, Classic/Turtle override=64) and use it in extractExploredZoneFields to limit reads to the correct block and zero-fill remaining slots.
This commit is contained in:
parent
1b55ebb387
commit
3a7ff71262
2 changed files with 22 additions and 1 deletions
|
|
@ -207,6 +207,11 @@ public:
|
|||
* WotLK: 5 fields per slot, Classic/Vanilla: 3. */
|
||||
virtual uint8_t questLogStride() const { return 5; }
|
||||
|
||||
/** Number of PLAYER_EXPLORED_ZONES uint32 fields in update-object blocks.
|
||||
* Classic/Vanilla/Turtle: 64 (bit-packs up to zone ID 2047).
|
||||
* TBC/WotLK: 128 (covers Outland/Northrend zone IDs up to 4095). */
|
||||
virtual uint8_t exploredZonesCount() const { return 128; }
|
||||
|
||||
// --- Quest Giver Status ---
|
||||
|
||||
/** Read quest giver status from packet.
|
||||
|
|
@ -407,6 +412,9 @@ public:
|
|||
network::Packet buildAcceptQuestPacket(uint64_t npcGuid, uint32_t questId) override;
|
||||
// parseQuestDetails inherited from TbcPacketParsers (same format as TBC 2.4.3)
|
||||
uint8_t questLogStride() const override { return 3; }
|
||||
// Classic 1.12 has 64 explored-zone uint32 fields (zone IDs fit in 2048 bits).
|
||||
// TBC/WotLK use 128 (needed for Outland/Northrend zone IDs up to 4095).
|
||||
uint8_t exploredZonesCount() const override { return 64; }
|
||||
bool parseMonsterMove(network::Packet& packet, MonsterMoveData& data) override {
|
||||
return MonsterMoveParser::parseVanilla(packet, data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17556,18 +17556,31 @@ void GameHandler::extractSkillFields(const std::map<uint16_t, uint32_t>& fields)
|
|||
}
|
||||
|
||||
void GameHandler::extractExploredZoneFields(const std::map<uint16_t, uint32_t>& fields) {
|
||||
// Number of explored-zone uint32 fields varies by expansion:
|
||||
// Classic/Turtle = 64, TBC/WotLK = 128. Always allocate 128 for world-map
|
||||
// bit lookups, but only read the expansion-specific count to avoid reading
|
||||
// player money or rest-XP fields as zone flags.
|
||||
const size_t zoneCount = packetParsers_
|
||||
? static_cast<size_t>(packetParsers_->exploredZonesCount())
|
||||
: PLAYER_EXPLORED_ZONES_COUNT;
|
||||
|
||||
if (playerExploredZones_.size() != PLAYER_EXPLORED_ZONES_COUNT) {
|
||||
playerExploredZones_.assign(PLAYER_EXPLORED_ZONES_COUNT, 0u);
|
||||
}
|
||||
|
||||
bool foundAny = false;
|
||||
for (size_t i = 0; i < PLAYER_EXPLORED_ZONES_COUNT; i++) {
|
||||
for (size_t i = 0; i < zoneCount; i++) {
|
||||
const uint16_t fieldIdx = static_cast<uint16_t>(fieldIndex(UF::PLAYER_EXPLORED_ZONES_START) + i);
|
||||
auto it = fields.find(fieldIdx);
|
||||
if (it == fields.end()) continue;
|
||||
playerExploredZones_[i] = it->second;
|
||||
foundAny = true;
|
||||
}
|
||||
// Zero out slots beyond the expansion's zone count to prevent stale data
|
||||
// from polluting the fog-of-war display.
|
||||
for (size_t i = zoneCount; i < PLAYER_EXPLORED_ZONES_COUNT; i++) {
|
||||
playerExploredZones_[i] = 0u;
|
||||
}
|
||||
|
||||
if (foundAny) {
|
||||
hasPlayerExploredZones_ = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue