mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-08-04 11:55:07 -04:00
The map worked out the player's zone from geometry alone: of the WorldMapArea boxes containing them, take the one they sit deepest inside. Those boxes are axis-aligned rectangles around irregular zones, so neighbours overlap heavily — the comment on that code already says as much — and the answer is a guess. It guessed wrong often enough to open on a zone the player was merely near. The server says which zone the player is in, in SMSG_INIT_WORLD_STATES, and the client has been tracking it as worldStateZoneId_ for other things all along. It is the same AreaTable id space WorldMapArea keys on, so it names a zone directly. Use it, and keep the geometry only for when the server has not said — before the first world-state packet, or for a zone that is not on the map currently displayed. Threaded to the exploration tracker and the player marker as well as the zone the map opens on. All three answered this question separately, so leaving any of them on the guess would show as a marker or a revealed area disagreeing with the zone in front of you. Tests cover the id winning over the geometry, the id winning even where the player's own zone box does not reach them, and the fallback for an id that names nothing on this map.
57 lines
2.1 KiB
C++
57 lines
2.1 KiB
C++
// exploration_state.hpp — Fog of war / exploration tracking (pure domain logic).
|
|
// Extracted from WorldMap::updateExploration (Phase 3 of refactoring plan).
|
|
// No rendering or GPU dependencies — fully testable standalone.
|
|
#pragma once
|
|
|
|
#include "rendering/world_map/world_map_types.hpp"
|
|
#include <glm/glm.hpp>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
#include <vector>
|
|
|
|
namespace wowee {
|
|
namespace rendering {
|
|
namespace world_map {
|
|
|
|
class ExplorationState {
|
|
public:
|
|
void setServerMask(const std::vector<uint32_t>& masks, bool hasData);
|
|
bool hasServerMask() const { return hasServerMask_; }
|
|
|
|
/// Recompute explored zones and overlays for given player position.
|
|
/// @param zones All loaded zones
|
|
/// @param playerRenderPos Player position in render-space
|
|
/// @param currentZoneIdx Currently viewed zone index
|
|
/// @param exploreFlagByAreaId AreaID → ExploreFlag mapping from AreaTable.dbc
|
|
/// @param playerZoneId The zone the server says the player is in (0 if unknown),
|
|
/// used in preference to deriving it from overlapping map geometry.
|
|
void update(const std::vector<Zone>& zones,
|
|
const glm::vec3& playerRenderPos,
|
|
int currentZoneIdx,
|
|
const std::unordered_map<uint32_t, uint32_t>& exploreFlagByAreaId,
|
|
uint32_t playerZoneId = 0);
|
|
|
|
const std::unordered_set<int>& exploredZones() const { return exploredZones_; }
|
|
const std::unordered_set<int>& exploredOverlays() const { return exploredOverlays_; }
|
|
|
|
/// Returns true if the explored overlay set changed since last update.
|
|
bool overlaysChanged() const { return overlaysChanged_; }
|
|
|
|
/// Clear accumulated local exploration data.
|
|
void clearLocal() { locallyExploredZones_.clear(); }
|
|
|
|
private:
|
|
bool isBitSet(uint32_t bitIndex) const;
|
|
|
|
std::vector<uint32_t> serverMask_;
|
|
bool hasServerMask_ = false;
|
|
std::unordered_set<int> exploredZones_;
|
|
std::unordered_set<int> exploredOverlays_;
|
|
std::unordered_set<int> locallyExploredZones_;
|
|
bool overlaysChanged_ = false;
|
|
};
|
|
|
|
} // namespace world_map
|
|
} // namespace rendering
|
|
} // namespace wowee
|