From 41e15349c5157277a90f689d2eb6fe6c1e279b88 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 18 Mar 2026 12:26:23 -0700 Subject: [PATCH] feat: improve arena team UI with names, types, and roster requests Store team name and type (2v2/3v3/5v5) from SMSG_ARENA_TEAM_QUERY_RESPONSE. Display proper team labels instead of raw IDs. Add Load/Refresh roster buttons and CMSG_ARENA_TEAM_ROSTER request support. --- include/game/game_handler.hpp | 3 +++ src/game/game_handler.cpp | 45 ++++++++++++++++++++++++++++------- src/ui/game_screen.cpp | 21 ++++++++++++---- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 9f362cb0..7221e85b 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1431,8 +1431,11 @@ public: uint32_t seasonGames = 0; uint32_t seasonWins = 0; uint32_t rank = 0; + std::string teamName; + uint32_t teamType = 0; // 2, 3, or 5 }; const std::vector& getArenaTeamStats() const { return arenaTeamStats_; } + void requestArenaTeamRoster(uint32_t teamId); // ---- Arena Team Roster ---- struct ArenaTeamMember { diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index a9b9262e..660c9d0a 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -17000,7 +17000,25 @@ void GameHandler::handleArenaTeamQueryResponse(network::Packet& packet) { if (packet.getSize() - packet.getReadPos() < 4) return; uint32_t teamId = packet.readUInt32(); std::string teamName = packet.readString(); - LOG_INFO("Arena team query response: id=", teamId, " name=", teamName); + uint32_t teamType = 0; + if (packet.getSize() - packet.getReadPos() >= 4) + teamType = packet.readUInt32(); + LOG_INFO("Arena team query response: id=", teamId, " name=", teamName, " type=", teamType); + + // Store name and type in matching ArenaTeamStats entry + for (auto& s : arenaTeamStats_) { + if (s.teamId == teamId) { + s.teamName = teamName; + s.teamType = teamType; + return; + } + } + // No stats entry yet — create a placeholder so we can show the name + ArenaTeamStats stub; + stub.teamId = teamId; + stub.teamName = teamName; + stub.teamType = teamType; + arenaTeamStats_.push_back(std::move(stub)); } void GameHandler::handleArenaTeamRoster(network::Packet& packet) { @@ -17144,18 +17162,29 @@ void GameHandler::handleArenaTeamStats(network::Packet& packet) { stats.seasonWins = packet.readUInt32(); stats.rank = packet.readUInt32(); - // Update or insert for this team + // Update or insert for this team (preserve name/type from query response) for (auto& s : arenaTeamStats_) { if (s.teamId == stats.teamId) { - s = stats; - LOG_INFO("SMSG_ARENA_TEAM_STATS: teamId=", stats.teamId, - " rating=", stats.rating, " rank=", stats.rank); + stats.teamName = std::move(s.teamName); + stats.teamType = s.teamType; + s = std::move(stats); + LOG_INFO("SMSG_ARENA_TEAM_STATS: teamId=", s.teamId, + " rating=", s.rating, " rank=", s.rank); return; } } - arenaTeamStats_.push_back(stats); - LOG_INFO("SMSG_ARENA_TEAM_STATS: teamId=", stats.teamId, - " rating=", stats.rating, " rank=", stats.rank); + arenaTeamStats_.push_back(std::move(stats)); + LOG_INFO("SMSG_ARENA_TEAM_STATS: teamId=", arenaTeamStats_.back().teamId, + " rating=", arenaTeamStats_.back().rating, + " rank=", arenaTeamStats_.back().rank); +} + +void GameHandler::requestArenaTeamRoster(uint32_t teamId) { + if (!socket) return; + network::Packet pkt(wireOpcode(Opcode::CMSG_ARENA_TEAM_ROSTER)); + pkt.writeUInt32(teamId); + socket->send(pkt); + LOG_INFO("Requesting arena team roster for teamId=", teamId); } void GameHandler::handleArenaError(network::Packet& packet) { diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 7c2cd196..c8250564 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -14755,10 +14755,15 @@ void GameScreen::renderSocialFrame(game::GameHandler& gameHandler) { const auto& ts = arenaStats[ai]; ImGui::PushID(static_cast(ai)); - // Team header with rating - char teamLabel[48]; - snprintf(teamLabel, sizeof(teamLabel), "Team #%u", ts.teamId); - ImGui::TextColored(ImVec4(1.0f, 0.85f, 0.2f, 1.0f), "%s", teamLabel); + // Team header: "2v2: Team Name" or fallback "Team #id" + std::string teamLabel; + if (ts.teamType > 0) + teamLabel = std::to_string(ts.teamType) + "v" + std::to_string(ts.teamType) + ": "; + if (!ts.teamName.empty()) + teamLabel += ts.teamName; + else + teamLabel += "Team #" + std::to_string(ts.teamId); + ImGui::TextColored(ImVec4(1.0f, 0.85f, 0.2f, 1.0f), "%s", teamLabel.c_str()); ImGui::Indent(8.0f); // Rating and rank @@ -14784,6 +14789,10 @@ void GameScreen::renderSocialFrame(game::GameHandler& gameHandler) { ImGui::Spacing(); ImGui::TextDisabled("-- Roster (%zu members) --", roster->members.size()); + ImGui::SameLine(); + if (ImGui::SmallButton("Refresh")) + gameHandler.requestArenaTeamRoster(ts.teamId); + // Column headers ImGui::Columns(4, "##arenaRosterCols", false); ImGui::SetColumnWidth(0, 110.0f); @@ -14819,6 +14828,10 @@ void GameScreen::renderSocialFrame(game::GameHandler& gameHandler) { ImGui::NextColumn(); } ImGui::Columns(1); + } else { + ImGui::Spacing(); + if (ImGui::SmallButton("Load Roster")) + gameHandler.requestArenaTeamRoster(ts.teamId); } ImGui::Unindent(8.0f);