mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: parse MSG_BATTLEGROUND_PLAYER_POSITIONS and show flag carriers on minimap
Replaces the silent consume with full packet parsing: reads two lists of (guid, x, y) positions (typically ally and horde flag carriers) and stores them in bgPlayerPositions_. Renders each as a colored diamond on the minimap (blue=group0, red=group1) with a "Flag carrier" tooltip showing the player's name when available.
This commit is contained in:
parent
48cb7df4b4
commit
113be66314
3 changed files with 76 additions and 3 deletions
|
|
@ -497,6 +497,15 @@ public:
|
||||||
return bgScoreboard_.players.empty() ? nullptr : &bgScoreboard_;
|
return bgScoreboard_.players.empty() ? nullptr : &bgScoreboard_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BG flag carrier / important player positions (MSG_BATTLEGROUND_PLAYER_POSITIONS)
|
||||||
|
struct BgPlayerPosition {
|
||||||
|
uint64_t guid = 0;
|
||||||
|
float wowX = 0.0f; // canonical WoW X (north)
|
||||||
|
float wowY = 0.0f; // canonical WoW Y (west)
|
||||||
|
int group = 0; // 0 = first list (usually ally flag carriers), 1 = second list
|
||||||
|
};
|
||||||
|
const std::vector<BgPlayerPosition>& getBgPlayerPositions() const { return bgPlayerPositions_; }
|
||||||
|
|
||||||
// Network latency (milliseconds, updated each PONG response)
|
// Network latency (milliseconds, updated each PONG response)
|
||||||
uint32_t getLatencyMs() const { return lastLatency; }
|
uint32_t getLatencyMs() const { return lastLatency; }
|
||||||
|
|
||||||
|
|
@ -2780,6 +2789,9 @@ private:
|
||||||
// BG scoreboard (MSG_PVP_LOG_DATA)
|
// BG scoreboard (MSG_PVP_LOG_DATA)
|
||||||
BgScoreboardData bgScoreboard_;
|
BgScoreboardData bgScoreboard_;
|
||||||
|
|
||||||
|
// BG flag carrier / player positions (MSG_BATTLEGROUND_PLAYER_POSITIONS)
|
||||||
|
std::vector<BgPlayerPosition> bgPlayerPositions_;
|
||||||
|
|
||||||
// Instance encounter boss units (slots 0-4 from SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT)
|
// Instance encounter boss units (slots 0-4 from SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT)
|
||||||
std::array<uint64_t, kMaxEncounterSlots> encounterUnitGuids_ = {}; // 0 = empty slot
|
std::array<uint64_t, kMaxEncounterSlots> encounterUnitGuids_ = {}; // 0 = empty slot
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5587,10 +5587,22 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
||||||
addUIError("Battlefield port denied.");
|
addUIError("Battlefield port denied.");
|
||||||
addSystemChatMessage("Battlefield port denied.");
|
addSystemChatMessage("Battlefield port denied.");
|
||||||
break;
|
break;
|
||||||
case Opcode::MSG_BATTLEGROUND_PLAYER_POSITIONS:
|
case Opcode::MSG_BATTLEGROUND_PLAYER_POSITIONS: {
|
||||||
// Optional map position updates for BG objectives/players.
|
bgPlayerPositions_.clear();
|
||||||
packet.setReadPos(packet.getSize());
|
for (int grp = 0; grp < 2; ++grp) {
|
||||||
|
if (packet.getSize() - packet.getReadPos() < 4) break;
|
||||||
|
uint32_t count = packet.readUInt32();
|
||||||
|
for (uint32_t i = 0; i < count && packet.getSize() - packet.getReadPos() >= 16; ++i) {
|
||||||
|
BgPlayerPosition pos;
|
||||||
|
pos.guid = packet.readUInt64();
|
||||||
|
pos.wowX = packet.readFloat();
|
||||||
|
pos.wowY = packet.readFloat();
|
||||||
|
pos.group = grp;
|
||||||
|
bgPlayerPositions_.push_back(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case Opcode::SMSG_REMOVED_FROM_PVP_QUEUE:
|
case Opcode::SMSG_REMOVED_FROM_PVP_QUEUE:
|
||||||
addSystemChatMessage("You have been removed from the PvP queue.");
|
addSystemChatMessage("You have been removed from the PvP queue.");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -17391,6 +17391,55 @@ void GameScreen::renderMinimapMarkers(game::GameHandler& gameHandler) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BG flag carrier / important player positions (MSG_BATTLEGROUND_PLAYER_POSITIONS)
|
||||||
|
{
|
||||||
|
const auto& bgPositions = gameHandler.getBgPlayerPositions();
|
||||||
|
if (!bgPositions.empty()) {
|
||||||
|
ImVec2 mouse = ImGui::GetMousePos();
|
||||||
|
// group 0 = typically ally-held flag / first list; group 1 = enemy
|
||||||
|
static const ImU32 kBgGroupColors[2] = {
|
||||||
|
IM_COL32( 80, 180, 255, 240), // group 0: blue (alliance)
|
||||||
|
IM_COL32(220, 50, 50, 240), // group 1: red (horde)
|
||||||
|
};
|
||||||
|
for (const auto& bp : bgPositions) {
|
||||||
|
// Packet coords: wowX=canonical X (north), wowY=canonical Y (west)
|
||||||
|
glm::vec3 bpRender = core::coords::canonicalToRender(glm::vec3(bp.wowX, bp.wowY, 0.0f));
|
||||||
|
float sx = 0.0f, sy = 0.0f;
|
||||||
|
if (!projectToMinimap(bpRender, sx, sy)) continue;
|
||||||
|
|
||||||
|
ImU32 col = kBgGroupColors[bp.group & 1];
|
||||||
|
|
||||||
|
// Draw a flag-like diamond icon
|
||||||
|
const float r = 5.0f;
|
||||||
|
ImVec2 top (sx, sy - r);
|
||||||
|
ImVec2 right(sx + r, sy );
|
||||||
|
ImVec2 bot (sx, sy + r);
|
||||||
|
ImVec2 left (sx - r, sy );
|
||||||
|
drawList->AddQuadFilled(top, right, bot, left, col);
|
||||||
|
drawList->AddQuad(top, right, bot, left, IM_COL32(255, 255, 255, 180), 1.0f);
|
||||||
|
|
||||||
|
float mdx = mouse.x - sx, mdy = mouse.y - sy;
|
||||||
|
if (mdx * mdx + mdy * mdy < 64.0f) {
|
||||||
|
// Show entity name if available, otherwise guid
|
||||||
|
auto ent = gameHandler.getEntityManager().getEntity(bp.guid);
|
||||||
|
if (ent) {
|
||||||
|
std::string nm;
|
||||||
|
if (ent->getType() == game::ObjectType::PLAYER) {
|
||||||
|
auto pl = std::static_pointer_cast<game::Unit>(ent);
|
||||||
|
nm = pl ? pl->getName() : "";
|
||||||
|
}
|
||||||
|
if (!nm.empty())
|
||||||
|
ImGui::SetTooltip("Flag carrier: %s", nm.c_str());
|
||||||
|
else
|
||||||
|
ImGui::SetTooltip("Flag carrier");
|
||||||
|
} else {
|
||||||
|
ImGui::SetTooltip("Flag carrier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Corpse direction indicator — shown when player is a ghost
|
// Corpse direction indicator — shown when player is a ghost
|
||||||
if (gameHandler.isPlayerGhost()) {
|
if (gameHandler.isPlayerGhost()) {
|
||||||
float corpseCanX = 0.0f, corpseCanY = 0.0f;
|
float corpseCanX = 0.0f, corpseCanY = 0.0f;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue