mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 08:03:50 +00:00
Fix chat focus and spirit healer confirm
This commit is contained in:
parent
c9e7caa938
commit
ff6155e2f3
5 changed files with 40 additions and 19 deletions
|
|
@ -242,6 +242,7 @@ enum class Opcode : uint16_t {
|
||||||
// ---- Death/Respawn ----
|
// ---- Death/Respawn ----
|
||||||
CMSG_REPOP_REQUEST = 0x015A,
|
CMSG_REPOP_REQUEST = 0x015A,
|
||||||
CMSG_SPIRIT_HEALER_ACTIVATE = 0x0176,
|
CMSG_SPIRIT_HEALER_ACTIVATE = 0x0176,
|
||||||
|
SMSG_SPIRIT_HEALER_CONFIRM = 0x0222,
|
||||||
|
|
||||||
// ---- Teleport / Transfer ----
|
// ---- Teleport / Transfer ----
|
||||||
MSG_MOVE_TELEPORT_ACK = 0x0C7,
|
MSG_MOVE_TELEPORT_ACK = 0x0C7,
|
||||||
|
|
|
||||||
|
|
@ -1507,6 +1507,12 @@ public:
|
||||||
static network::Packet build(uint64_t npcGuid);
|
static network::Packet build(uint64_t npcGuid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** CMSG_QUESTGIVER_HELLO packet builder */
|
||||||
|
class QuestgiverHelloPacket {
|
||||||
|
public:
|
||||||
|
static network::Packet build(uint64_t npcGuid);
|
||||||
|
};
|
||||||
|
|
||||||
/** CMSG_GOSSIP_SELECT_OPTION packet builder */
|
/** CMSG_GOSSIP_SELECT_OPTION packet builder */
|
||||||
class GossipSelectOptionPacket {
|
class GossipSelectOptionPacket {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,20 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
||||||
case Opcode::SMSG_GOSSIP_COMPLETE:
|
case Opcode::SMSG_GOSSIP_COMPLETE:
|
||||||
handleGossipComplete(packet);
|
handleGossipComplete(packet);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::SMSG_SPIRIT_HEALER_CONFIRM: {
|
||||||
|
if (packet.getSize() - packet.getReadPos() < 8) {
|
||||||
|
LOG_WARNING("SMSG_SPIRIT_HEALER_CONFIRM too short");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uint64_t healerGuid = packet.readUInt64();
|
||||||
|
LOG_INFO("Spirit healer confirm from 0x", std::hex, healerGuid, std::dec);
|
||||||
|
if (playerDead_ && socket && state == WorldState::IN_WORLD) {
|
||||||
|
auto activate = SpiritHealerActivatePacket::build(healerGuid);
|
||||||
|
socket->send(activate);
|
||||||
|
LOG_INFO("Confirmed spirit healer activation");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Opcode::SMSG_LIST_INVENTORY:
|
case Opcode::SMSG_LIST_INVENTORY:
|
||||||
handleListInventory(packet);
|
handleListInventory(packet);
|
||||||
break;
|
break;
|
||||||
|
|
@ -2667,11 +2681,14 @@ void GameHandler::releaseSpirit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameHandler::activateSpiritHealer(uint64_t npcGuid) {
|
void GameHandler::activateSpiritHealer(uint64_t npcGuid) {
|
||||||
if (!playerDead_) return;
|
|
||||||
if (state != WorldState::IN_WORLD || !socket) return;
|
if (state != WorldState::IN_WORLD || !socket) return;
|
||||||
|
auto gossipPacket = GossipHelloPacket::build(npcGuid);
|
||||||
|
socket->send(gossipPacket);
|
||||||
|
auto questHelloPacket = QuestgiverHelloPacket::build(npcGuid);
|
||||||
|
socket->send(questHelloPacket);
|
||||||
auto packet = SpiritHealerActivatePacket::build(npcGuid);
|
auto packet = SpiritHealerActivatePacket::build(npcGuid);
|
||||||
socket->send(packet);
|
socket->send(packet);
|
||||||
LOG_INFO("Sent CMSG_SPIRIT_HEALER_ACTIVATE to 0x", std::hex, npcGuid, std::dec);
|
LOG_INFO("Sent spirit healer activation sequence to 0x", std::hex, npcGuid, std::dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameHandler::tabTarget(float playerX, float playerY, float playerZ) {
|
void GameHandler::tabTarget(float playerX, float playerY, float playerZ) {
|
||||||
|
|
|
||||||
|
|
@ -2289,6 +2289,12 @@ network::Packet GossipHelloPacket::build(uint64_t npcGuid) {
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
network::Packet QuestgiverHelloPacket::build(uint64_t npcGuid) {
|
||||||
|
network::Packet packet(static_cast<uint16_t>(Opcode::CMSG_QUESTGIVER_HELLO));
|
||||||
|
packet.writeUInt64(npcGuid);
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
network::Packet GossipSelectOptionPacket::build(uint64_t npcGuid, uint32_t menuId, uint32_t optionId, const std::string& code) {
|
network::Packet GossipSelectOptionPacket::build(uint64_t npcGuid, uint32_t menuId, uint32_t optionId, const std::string& code) {
|
||||||
network::Packet packet(static_cast<uint16_t>(Opcode::CMSG_GOSSIP_SELECT_OPTION));
|
network::Packet packet(static_cast<uint16_t>(Opcode::CMSG_GOSSIP_SELECT_OPTION));
|
||||||
packet.writeUInt64(npcGuid);
|
packet.writeUInt64(npcGuid);
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,9 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
||||||
ImGui::SetNextWindowPos(chatWindowPos_, ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowPos(chatWindowPos_, ImGuiCond_FirstUseEver);
|
||||||
}
|
}
|
||||||
ImGuiWindowFlags flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize;
|
ImGuiWindowFlags flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize;
|
||||||
if (chatWindowLocked) flags |= ImGuiWindowFlags_NoMove;
|
if (chatWindowLocked) {
|
||||||
|
flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar;
|
||||||
|
}
|
||||||
ImGui::Begin("Chat", nullptr, flags);
|
ImGui::Begin("Chat", nullptr, flags);
|
||||||
|
|
||||||
if (!chatWindowLocked) {
|
if (!chatWindowLocked) {
|
||||||
|
|
@ -406,6 +408,7 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
||||||
const auto& chatHistory = gameHandler.getChatHistory();
|
const auto& chatHistory = gameHandler.getChatHistory();
|
||||||
|
|
||||||
ImGui::BeginChild("ChatHistory", ImVec2(0, -70), true, ImGuiWindowFlags_HorizontalScrollbar);
|
ImGui::BeginChild("ChatHistory", ImVec2(0, -70), true, ImGuiWindowFlags_HorizontalScrollbar);
|
||||||
|
bool chatHistoryHovered = ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
|
||||||
|
|
||||||
for (const auto& msg : chatHistory) {
|
for (const auto& msg : chatHistory) {
|
||||||
ImVec4 color = getChatTypeColor(msg.type);
|
ImVec4 color = getChatTypeColor(msg.type);
|
||||||
|
|
@ -435,14 +438,10 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
||||||
|
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
|
||||||
// Click on chat history area → focus the input field
|
|
||||||
if (ImGui::IsItemClicked()) {
|
|
||||||
refocusChatInput = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
float controlsTopY = ImGui::GetCursorScreenPos().y;
|
||||||
|
|
||||||
// Lock toggle
|
// Lock toggle
|
||||||
ImGui::Checkbox("Lock", &chatWindowLocked);
|
ImGui::Checkbox("Lock", &chatWindowLocked);
|
||||||
|
|
@ -514,18 +513,10 @@ void GameScreen::renderChatWindow(game::GameHandler& gameHandler) {
|
||||||
chatInputActive = false;
|
chatInputActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Click on empty chat window area (receive panel/background) → focus input
|
// Click in chat history area (received messages) → focus input.
|
||||||
// Ignore title bar (move) and interactive items like Lock.
|
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
if (chatHistoryHovered && ImGui::IsMouseClicked(0)) {
|
||||||
if (ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) &&
|
refocusChatInput = true;
|
||||||
io.MouseClicked[0] &&
|
|
||||||
!ImGui::IsAnyItemHovered()) {
|
|
||||||
ImVec2 winPos = ImGui::GetWindowPos();
|
|
||||||
float titleBarH = ImGui::GetFrameHeight();
|
|
||||||
if (io.MousePos.y > winPos.y + titleBarH) {
|
|
||||||
refocusChatInput = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue