mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Handle SMSG_SUMMON_REQUEST with accept/decline popup
- Parse SMSG_SUMMON_REQUEST (summonerGuid + zoneId + timeoutMs), store summoner name from entity list, show chat notification - acceptSummon() sends CMSG_SUMMON_RESPONSE(1), declineSummon() sends CMSG_SUMMON_RESPONSE(0), SMSG_SUMMON_CANCEL clears pending state - renderSummonRequestPopup(): shows summoner name + countdown timer with Accept/Decline buttons
This commit is contained in:
parent
f369fe9c6e
commit
770ac645d5
4 changed files with 101 additions and 0 deletions
|
|
@ -707,6 +707,13 @@ public:
|
|||
bool hasPendingGroupInvite() const { return pendingGroupInvite; }
|
||||
const std::string& getPendingInviterName() const { return pendingInviterName; }
|
||||
|
||||
// ---- Summon ----
|
||||
bool hasPendingSummonRequest() const { return pendingSummonRequest_; }
|
||||
const std::string& getSummonerName() const { return summonerName_; }
|
||||
float getSummonTimeoutSec() const { return summonTimeoutSec_; }
|
||||
void acceptSummon();
|
||||
void declineSummon();
|
||||
|
||||
// ---- Trade ----
|
||||
enum class TradeStatus : uint8_t {
|
||||
None = 0, PendingIncoming, Open, Accepted, Complete
|
||||
|
|
@ -1280,6 +1287,7 @@ private:
|
|||
|
||||
// ---- Instance lockout handler ----
|
||||
void handleRaidInstanceInfo(network::Packet& packet);
|
||||
void handleSummonRequest(network::Packet& packet);
|
||||
void handleTradeStatus(network::Packet& packet);
|
||||
void handleDuelRequested(network::Packet& packet);
|
||||
void handleDuelComplete(network::Packet& packet);
|
||||
|
|
@ -1638,6 +1646,12 @@ private:
|
|||
bool pendingGroupInvite = false;
|
||||
std::string pendingInviterName;
|
||||
|
||||
// Summon state
|
||||
bool pendingSummonRequest_ = false;
|
||||
uint64_t summonerGuid_ = 0;
|
||||
std::string summonerName_;
|
||||
float summonTimeoutSec_ = 0.0f;
|
||||
|
||||
// Trade state
|
||||
TradeStatus tradeStatus_ = TradeStatus::None;
|
||||
uint64_t tradePeerGuid_= 0;
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ private:
|
|||
void renderDuelRequestPopup(game::GameHandler& gameHandler);
|
||||
void renderLootRollPopup(game::GameHandler& gameHandler);
|
||||
void renderTradeRequestPopup(game::GameHandler& gameHandler);
|
||||
void renderSummonRequestPopup(game::GameHandler& gameHandler);
|
||||
void renderBuffBar(game::GameHandler& gameHandler);
|
||||
void renderLootWindow(game::GameHandler& gameHandler);
|
||||
void renderGossipWindow(game::GameHandler& gameHandler);
|
||||
|
|
|
|||
|
|
@ -1953,6 +1953,13 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
|||
case Opcode::SMSG_LOOT_REMOVED:
|
||||
handleLootRemoved(packet);
|
||||
break;
|
||||
case Opcode::SMSG_SUMMON_REQUEST:
|
||||
handleSummonRequest(packet);
|
||||
break;
|
||||
case Opcode::SMSG_SUMMON_CANCEL:
|
||||
pendingSummonRequest_ = false;
|
||||
addSystemChatMessage("Summon cancelled.");
|
||||
break;
|
||||
case Opcode::SMSG_TRADE_STATUS:
|
||||
case Opcode::SMSG_TRADE_STATUS_EXTENDED:
|
||||
handleTradeStatus(packet);
|
||||
|
|
@ -14995,6 +15002,56 @@ void GameHandler::handleAuctionCommandResult(network::Packet& packet) {
|
|||
" error=", result.errorCode);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// SMSG_SUMMON_REQUEST
|
||||
// uint64 summonerGuid + uint32 zoneId + uint32 timeoutMs
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void GameHandler::handleSummonRequest(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 16) return;
|
||||
|
||||
summonerGuid_ = packet.readUInt64();
|
||||
/*uint32_t zoneId =*/ packet.readUInt32();
|
||||
uint32_t timeoutMs = packet.readUInt32();
|
||||
summonTimeoutSec_ = timeoutMs / 1000.0f;
|
||||
pendingSummonRequest_= true;
|
||||
|
||||
summonerName_.clear();
|
||||
auto entity = entityManager.getEntity(summonerGuid_);
|
||||
if (auto* unit = dynamic_cast<Unit*>(entity.get())) {
|
||||
summonerName_ = unit->getName();
|
||||
}
|
||||
if (summonerName_.empty()) {
|
||||
char tmp[32];
|
||||
std::snprintf(tmp, sizeof(tmp), "0x%llX",
|
||||
static_cast<unsigned long long>(summonerGuid_));
|
||||
summonerName_ = tmp;
|
||||
}
|
||||
|
||||
addSystemChatMessage(summonerName_ + " is summoning you.");
|
||||
LOG_INFO("SMSG_SUMMON_REQUEST: summoner=", summonerName_,
|
||||
" timeout=", summonTimeoutSec_, "s");
|
||||
}
|
||||
|
||||
void GameHandler::acceptSummon() {
|
||||
if (!pendingSummonRequest_ || !socket) return;
|
||||
pendingSummonRequest_ = false;
|
||||
network::Packet pkt(wireOpcode(Opcode::CMSG_SUMMON_RESPONSE));
|
||||
pkt.writeUInt8(1); // 1 = accept
|
||||
socket->send(pkt);
|
||||
addSystemChatMessage("Accepting summon...");
|
||||
LOG_INFO("Accepted summon from ", summonerName_);
|
||||
}
|
||||
|
||||
void GameHandler::declineSummon() {
|
||||
if (!socket) return;
|
||||
pendingSummonRequest_ = false;
|
||||
network::Packet pkt(wireOpcode(Opcode::CMSG_SUMMON_RESPONSE));
|
||||
pkt.writeUInt8(0); // 0 = decline
|
||||
socket->send(pkt);
|
||||
addSystemChatMessage("Summon declined.");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Trade (SMSG_TRADE_STATUS / SMSG_TRADE_STATUS_EXTENDED)
|
||||
// WotLK 3.3.5a status values:
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ void GameScreen::render(game::GameHandler& gameHandler) {
|
|||
renderDuelRequestPopup(gameHandler);
|
||||
renderLootRollPopup(gameHandler);
|
||||
renderTradeRequestPopup(gameHandler);
|
||||
renderSummonRequestPopup(gameHandler);
|
||||
renderGuildInvitePopup(gameHandler);
|
||||
renderGuildRoster(gameHandler);
|
||||
renderBuffBar(gameHandler);
|
||||
|
|
@ -4403,6 +4404,34 @@ void GameScreen::renderDuelRequestPopup(game::GameHandler& gameHandler) {
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
void GameScreen::renderSummonRequestPopup(game::GameHandler& gameHandler) {
|
||||
if (!gameHandler.hasPendingSummonRequest()) return;
|
||||
|
||||
auto* window = core::Application::getInstance().getWindow();
|
||||
float screenW = window ? static_cast<float>(window->getWidth()) : 1280.0f;
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(screenW / 2 - 175, 430), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(ImVec2(350, 0), ImGuiCond_Always);
|
||||
|
||||
if (ImGui::Begin("Summon Request", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize)) {
|
||||
ImGui::Text("%s is summoning you.", gameHandler.getSummonerName().c_str());
|
||||
float t = gameHandler.getSummonTimeoutSec();
|
||||
if (t > 0.0f) {
|
||||
ImGui::Text("Time remaining: %.0fs", t);
|
||||
}
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Accept", ImVec2(130, 30))) {
|
||||
gameHandler.acceptSummon();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Decline", ImVec2(130, 30))) {
|
||||
gameHandler.declineSummon();
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void GameScreen::renderTradeRequestPopup(game::GameHandler& gameHandler) {
|
||||
if (!gameHandler.hasPendingTradeRequest()) return;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue