mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix spirit healer resurrection with correct opcodes
Corrected death/resurrection opcode values (SMSG_SPIRIT_HEALER_CONFIRM=0x222, CMSG_SPIRIT_HEALER_ACTIVATE=0x21C, SMSG_RESURRECT_REQUEST=0x15B, CMSG_RESURRECT_RESPONSE=0x15C) and added resurrect dialog UI.
This commit is contained in:
parent
7cd7ac43a9
commit
6d719f2c52
5 changed files with 150 additions and 62 deletions
|
|
@ -404,7 +404,12 @@ public:
|
||||||
|
|
||||||
// Player death state
|
// Player death state
|
||||||
bool isPlayerDead() const { return playerDead_; }
|
bool isPlayerDead() const { return playerDead_; }
|
||||||
|
bool isPlayerGhost() const { return releasedSpirit_; }
|
||||||
|
bool showDeathDialog() const { return playerDead_ && !releasedSpirit_; }
|
||||||
|
bool showResurrectDialog() const { return resurrectRequestPending_; }
|
||||||
void releaseSpirit();
|
void releaseSpirit();
|
||||||
|
void acceptResurrect();
|
||||||
|
void declineResurrect();
|
||||||
|
|
||||||
// ---- Phase 4: Group ----
|
// ---- Phase 4: Group ----
|
||||||
void inviteToGroup(const std::string& playerName);
|
void inviteToGroup(const std::string& playerName);
|
||||||
|
|
@ -912,8 +917,11 @@ private:
|
||||||
float preMountRunSpeed_ = 0.0f;
|
float preMountRunSpeed_ = 0.0f;
|
||||||
float serverRunSpeed_ = 7.0f;
|
float serverRunSpeed_ = 7.0f;
|
||||||
bool playerDead_ = false;
|
bool playerDead_ = false;
|
||||||
|
bool releasedSpirit_ = false;
|
||||||
uint64_t pendingSpiritHealerGuid_ = 0;
|
uint64_t pendingSpiritHealerGuid_ = 0;
|
||||||
bool resurrectPending_ = false;
|
bool resurrectPending_ = false;
|
||||||
|
bool resurrectRequestPending_ = false;
|
||||||
|
uint64_t resurrectCasterGuid_ = 0;
|
||||||
bool repopPending_ = false;
|
bool repopPending_ = false;
|
||||||
uint64_t lastRepopRequestMs_ = 0;
|
uint64_t lastRepopRequestMs_ = 0;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -241,10 +241,10 @@ enum class Opcode : uint16_t {
|
||||||
|
|
||||||
// ---- Death/Respawn ----
|
// ---- Death/Respawn ----
|
||||||
CMSG_REPOP_REQUEST = 0x015A,
|
CMSG_REPOP_REQUEST = 0x015A,
|
||||||
CMSG_SPIRIT_HEALER_ACTIVATE = 0x0176,
|
SMSG_RESURRECT_REQUEST = 0x015B,
|
||||||
SMSG_RESURRECT_REQUEST = 0x0222,
|
CMSG_RESURRECT_RESPONSE = 0x015C,
|
||||||
CMSG_RESURRECT_RESPONSE = 0x0223,
|
CMSG_SPIRIT_HEALER_ACTIVATE = 0x021C,
|
||||||
SMSG_RESURRECT_RESULT = 0x029D,
|
SMSG_SPIRIT_HEALER_CONFIRM = 0x0222,
|
||||||
SMSG_RESURRECT_CANCEL = 0x0390,
|
SMSG_RESURRECT_CANCEL = 0x0390,
|
||||||
|
|
||||||
// ---- Teleport / Transfer ----
|
// ---- Teleport / Transfer ----
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@ private:
|
||||||
void renderVendorWindow(game::GameHandler& gameHandler);
|
void renderVendorWindow(game::GameHandler& gameHandler);
|
||||||
void renderTaxiWindow(game::GameHandler& gameHandler);
|
void renderTaxiWindow(game::GameHandler& gameHandler);
|
||||||
void renderDeathScreen(game::GameHandler& gameHandler);
|
void renderDeathScreen(game::GameHandler& gameHandler);
|
||||||
|
void renderResurrectDialog(game::GameHandler& gameHandler);
|
||||||
void renderEscapeMenu();
|
void renderEscapeMenu();
|
||||||
void renderSettingsWindow();
|
void renderSettingsWindow();
|
||||||
void renderQuestMarkers(game::GameHandler& gameHandler);
|
void renderQuestMarkers(game::GameHandler& gameHandler);
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,19 @@ 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 npcGuid = packet.readUInt64();
|
||||||
|
LOG_INFO("Spirit healer confirm from 0x", std::hex, npcGuid, std::dec);
|
||||||
|
if (npcGuid) {
|
||||||
|
resurrectCasterGuid_ = npcGuid;
|
||||||
|
resurrectRequestPending_ = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Opcode::SMSG_RESURRECT_REQUEST: {
|
case Opcode::SMSG_RESURRECT_REQUEST: {
|
||||||
if (packet.getSize() - packet.getReadPos() < 8) {
|
if (packet.getSize() - packet.getReadPos() < 8) {
|
||||||
LOG_WARNING("SMSG_RESURRECT_REQUEST too short");
|
LOG_WARNING("SMSG_RESURRECT_REQUEST too short");
|
||||||
|
|
@ -514,41 +527,9 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
uint64_t casterGuid = packet.readUInt64();
|
uint64_t casterGuid = packet.readUInt64();
|
||||||
LOG_INFO("Resurrect request from 0x", std::hex, casterGuid, std::dec);
|
LOG_INFO("Resurrect request from 0x", std::hex, casterGuid, std::dec);
|
||||||
if (!playerDead_) {
|
if (casterGuid) {
|
||||||
playerDead_ = true;
|
resurrectCasterGuid_ = casterGuid;
|
||||||
LOG_INFO("Marked player dead due to resurrect request");
|
resurrectRequestPending_ = true;
|
||||||
}
|
|
||||||
if (socket && state == WorldState::IN_WORLD) {
|
|
||||||
uint64_t useGuid = casterGuid ? casterGuid : pendingSpiritHealerGuid_;
|
|
||||||
if (useGuid == 0) {
|
|
||||||
LOG_WARNING("Resurrect request received without a valid guid");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!playerDead_) {
|
|
||||||
LOG_WARNING("Resurrect request while playerDead_ is false; proceeding anyway");
|
|
||||||
}
|
|
||||||
auto response = ResurrectResponsePacket::build(useGuid, true);
|
|
||||||
socket->send(response);
|
|
||||||
LOG_INFO("Sent resurrect response for 0x", std::hex, useGuid, std::dec);
|
|
||||||
resurrectPending_ = true;
|
|
||||||
pendingSpiritHealerGuid_ = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Opcode::SMSG_RESURRECT_RESULT: {
|
|
||||||
if (packet.getSize() - packet.getReadPos() < 1) {
|
|
||||||
LOG_WARNING("SMSG_RESURRECT_RESULT too short");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
uint8_t result = packet.readUInt8();
|
|
||||||
LOG_INFO("Resurrect result: ", static_cast<int>(result));
|
|
||||||
if (result == 0) {
|
|
||||||
playerDead_ = false;
|
|
||||||
LOG_INFO("Player resurrected (result)");
|
|
||||||
}
|
|
||||||
resurrectPending_ = false;
|
|
||||||
if (!playerDead_) {
|
|
||||||
repopPending_ = false;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -559,8 +540,8 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
uint32_t reason = packet.readUInt32();
|
uint32_t reason = packet.readUInt32();
|
||||||
LOG_INFO("Resurrect cancel reason: ", reason);
|
LOG_INFO("Resurrect cancel reason: ", reason);
|
||||||
playerDead_ = true;
|
|
||||||
resurrectPending_ = false;
|
resurrectPending_ = false;
|
||||||
|
resurrectRequestPending_ = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Opcode::SMSG_LIST_INVENTORY:
|
case Opcode::SMSG_LIST_INVENTORY:
|
||||||
|
|
@ -1080,6 +1061,7 @@ void GameHandler::selectCharacter(uint64_t characterGuid) {
|
||||||
castTimeRemaining = 0.0f;
|
castTimeRemaining = 0.0f;
|
||||||
castTimeTotal = 0.0f;
|
castTimeTotal = 0.0f;
|
||||||
playerDead_ = false;
|
playerDead_ = false;
|
||||||
|
releasedSpirit_ = false;
|
||||||
targetGuid = 0;
|
targetGuid = 0;
|
||||||
focusGuid = 0;
|
focusGuid = 0;
|
||||||
lastTargetGuid = 0;
|
lastTargetGuid = 0;
|
||||||
|
|
@ -1443,6 +1425,17 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
playerDead_ = true;
|
playerDead_ = true;
|
||||||
LOG_INFO("Player logged in dead (dynamic flags)");
|
LOG_INFO("Player logged in dead (dynamic flags)");
|
||||||
}
|
}
|
||||||
|
// Detect ghost state on login via PLAYER_FLAGS (field 150)
|
||||||
|
if (block.guid == playerGuid) {
|
||||||
|
constexpr uint32_t PLAYER_FLAGS_IDX = 150; // UNIT_END(148) + 2
|
||||||
|
constexpr uint32_t PLAYER_FLAGS_GHOST = 0x00000010;
|
||||||
|
auto pfIt = block.fields.find(PLAYER_FLAGS_IDX);
|
||||||
|
if (pfIt != block.fields.end() && (pfIt->second & PLAYER_FLAGS_GHOST) != 0) {
|
||||||
|
releasedSpirit_ = true;
|
||||||
|
playerDead_ = true;
|
||||||
|
LOG_INFO("Player logged in as ghost (PLAYER_FLAGS)");
|
||||||
|
}
|
||||||
|
}
|
||||||
// Determine hostility from faction template for online creatures
|
// Determine hostility from faction template for online creatures
|
||||||
if (unit->getFactionTemplate() != 0) {
|
if (unit->getFactionTemplate() != 0) {
|
||||||
unit->setHostile(isHostileFaction(unit->getFactionTemplate()));
|
unit->setHostile(isHostileFaction(unit->getFactionTemplate()));
|
||||||
|
|
@ -1534,6 +1527,7 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
// Player death
|
// Player death
|
||||||
if (block.guid == playerGuid) {
|
if (block.guid == playerGuid) {
|
||||||
playerDead_ = true;
|
playerDead_ = true;
|
||||||
|
releasedSpirit_ = false;
|
||||||
stopAutoAttack();
|
stopAutoAttack();
|
||||||
LOG_INFO("Player died!");
|
LOG_INFO("Player died!");
|
||||||
}
|
}
|
||||||
|
|
@ -1542,10 +1536,14 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
npcDeathCallback_(block.guid);
|
npcDeathCallback_(block.guid);
|
||||||
}
|
}
|
||||||
} else if (oldHealth == 0 && val > 0) {
|
} else if (oldHealth == 0 && val > 0) {
|
||||||
// Player resurrection
|
// Player resurrection or ghost form
|
||||||
if (block.guid == playerGuid) {
|
if (block.guid == playerGuid) {
|
||||||
playerDead_ = false;
|
playerDead_ = false;
|
||||||
LOG_INFO("Player resurrected!");
|
if (!releasedSpirit_) {
|
||||||
|
LOG_INFO("Player resurrected!");
|
||||||
|
} else {
|
||||||
|
LOG_INFO("Player entered ghost form");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Respawn: health went from 0 to >0, reset animation
|
// Respawn: health went from 0 to >0, reset animation
|
||||||
if (entity->getType() == ObjectType::UNIT && npcRespawnCallback_) {
|
if (entity->getType() == ObjectType::UNIT && npcRespawnCallback_) {
|
||||||
|
|
@ -1566,9 +1564,11 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
bool nowDead = (val & UNIT_DYNFLAG_DEAD) != 0;
|
bool nowDead = (val & UNIT_DYNFLAG_DEAD) != 0;
|
||||||
if (!wasDead && nowDead) {
|
if (!wasDead && nowDead) {
|
||||||
playerDead_ = true;
|
playerDead_ = true;
|
||||||
|
releasedSpirit_ = false;
|
||||||
LOG_INFO("Player died (dynamic flags)");
|
LOG_INFO("Player died (dynamic flags)");
|
||||||
} else if (wasDead && !nowDead) {
|
} else if (wasDead && !nowDead) {
|
||||||
playerDead_ = false;
|
playerDead_ = false;
|
||||||
|
releasedSpirit_ = false;
|
||||||
LOG_INFO("Player resurrected (dynamic flags)");
|
LOG_INFO("Player resurrected (dynamic flags)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1637,6 +1637,21 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
playerMoneyCopper_ = val;
|
playerMoneyCopper_ = val;
|
||||||
LOG_INFO("Money updated via VALUES: ", val, " copper");
|
LOG_INFO("Money updated via VALUES: ", val, " copper");
|
||||||
}
|
}
|
||||||
|
else if (key == 150) { // PLAYER_FLAGS (UNIT_END+2)
|
||||||
|
constexpr uint32_t PLAYER_FLAGS_GHOST = 0x00000010;
|
||||||
|
bool wasGhost = releasedSpirit_;
|
||||||
|
bool nowGhost = (val & PLAYER_FLAGS_GHOST) != 0;
|
||||||
|
if (!wasGhost && nowGhost) {
|
||||||
|
releasedSpirit_ = true;
|
||||||
|
LOG_INFO("Player entered ghost form (PLAYER_FLAGS)");
|
||||||
|
} else if (wasGhost && !nowGhost) {
|
||||||
|
releasedSpirit_ = false;
|
||||||
|
playerDead_ = false;
|
||||||
|
repopPending_ = false;
|
||||||
|
resurrectPending_ = false;
|
||||||
|
LOG_INFO("Player resurrected (PLAYER_FLAGS ghost cleared)");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (applyInventoryFields(block.fields)) slotsChanged = true;
|
if (applyInventoryFields(block.fields)) slotsChanged = true;
|
||||||
if (slotsChanged) rebuildOnlineInventory();
|
if (slotsChanged) rebuildOnlineInventory();
|
||||||
|
|
@ -2745,9 +2760,9 @@ void GameHandler::releaseSpirit() {
|
||||||
if (repopPending_ && now - static_cast<int64_t>(lastRepopRequestMs_) < 1000) {
|
if (repopPending_ && now - static_cast<int64_t>(lastRepopRequestMs_) < 1000) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
playerDead_ = true;
|
|
||||||
auto packet = RepopRequestPacket::build();
|
auto packet = RepopRequestPacket::build();
|
||||||
socket->send(packet);
|
socket->send(packet);
|
||||||
|
releasedSpirit_ = true;
|
||||||
repopPending_ = true;
|
repopPending_ = true;
|
||||||
lastRepopRequestMs_ = static_cast<uint64_t>(now);
|
lastRepopRequestMs_ = static_cast<uint64_t>(now);
|
||||||
LOG_INFO("Sent CMSG_REPOP_REQUEST (Release Spirit)");
|
LOG_INFO("Sent CMSG_REPOP_REQUEST (Release Spirit)");
|
||||||
|
|
@ -2757,15 +2772,30 @@ void GameHandler::releaseSpirit() {
|
||||||
void GameHandler::activateSpiritHealer(uint64_t npcGuid) {
|
void GameHandler::activateSpiritHealer(uint64_t npcGuid) {
|
||||||
if (state != WorldState::IN_WORLD || !socket) return;
|
if (state != WorldState::IN_WORLD || !socket) return;
|
||||||
pendingSpiritHealerGuid_ = npcGuid;
|
pendingSpiritHealerGuid_ = npcGuid;
|
||||||
if (!gossipWindowOpen) {
|
auto packet = SpiritHealerActivatePacket::build(npcGuid);
|
||||||
auto gossipPacket = GossipHelloPacket::build(npcGuid);
|
socket->send(packet);
|
||||||
socket->send(gossipPacket);
|
resurrectPending_ = true;
|
||||||
auto questHelloPacket = QuestgiverHelloPacket::build(npcGuid);
|
LOG_INFO("Sent CMSG_SPIRIT_HEALER_ACTIVATE for 0x", std::hex, npcGuid, std::dec);
|
||||||
socket->send(questHelloPacket);
|
}
|
||||||
LOG_INFO("Requested spirit healer confirm from 0x", std::hex, npcGuid, std::dec);
|
|
||||||
} else {
|
void GameHandler::acceptResurrect() {
|
||||||
LOG_INFO("Queued spirit healer confirm for 0x", std::hex, npcGuid, std::dec);
|
if (state != WorldState::IN_WORLD || !socket || !resurrectRequestPending_) return;
|
||||||
}
|
// Send spirit healer activate (correct response to SMSG_SPIRIT_HEALER_CONFIRM)
|
||||||
|
auto activate = SpiritHealerActivatePacket::build(resurrectCasterGuid_);
|
||||||
|
socket->send(activate);
|
||||||
|
LOG_INFO("Sent CMSG_SPIRIT_HEALER_ACTIVATE (0x21C) for 0x",
|
||||||
|
std::hex, resurrectCasterGuid_, std::dec);
|
||||||
|
resurrectRequestPending_ = false;
|
||||||
|
resurrectPending_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameHandler::declineResurrect() {
|
||||||
|
if (state != WorldState::IN_WORLD || !socket || !resurrectRequestPending_) return;
|
||||||
|
auto resp = ResurrectResponsePacket::build(resurrectCasterGuid_, false);
|
||||||
|
socket->send(resp);
|
||||||
|
LOG_INFO("Sent CMSG_RESURRECT_RESPONSE (decline) for 0x",
|
||||||
|
std::hex, resurrectCasterGuid_, std::dec);
|
||||||
|
resurrectRequestPending_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameHandler::tabTarget(float playerX, float playerY, float playerZ) {
|
void GameHandler::tabTarget(float playerX, float playerY, float playerZ) {
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ void GameScreen::render(game::GameHandler& gameHandler) {
|
||||||
renderQuestMarkers(gameHandler);
|
renderQuestMarkers(gameHandler);
|
||||||
renderMinimapMarkers(gameHandler);
|
renderMinimapMarkers(gameHandler);
|
||||||
renderDeathScreen(gameHandler);
|
renderDeathScreen(gameHandler);
|
||||||
|
renderResurrectDialog(gameHandler);
|
||||||
renderEscapeMenu();
|
renderEscapeMenu();
|
||||||
renderSettingsWindow();
|
renderSettingsWindow();
|
||||||
|
|
||||||
|
|
@ -739,7 +740,7 @@ void GameScreen::processTargetInput(game::GameHandler& gameHandler) {
|
||||||
return (name.find("spirit healer") != std::string::npos) ||
|
return (name.find("spirit healer") != std::string::npos) ||
|
||||||
(name.find("spirit guide") != std::string::npos);
|
(name.find("spirit guide") != std::string::npos);
|
||||||
};
|
};
|
||||||
bool allowSpiritInteract = gameHandler.isPlayerDead() && isSpiritNpc();
|
bool allowSpiritInteract = (gameHandler.isPlayerDead() || gameHandler.isPlayerGhost()) && isSpiritNpc();
|
||||||
if (!unit->isHostile() && (unit->isInteractable() || allowSpiritInteract)) {
|
if (!unit->isHostile() && (unit->isInteractable() || allowSpiritInteract)) {
|
||||||
gameHandler.interactWithNpc(target->getGuid());
|
gameHandler.interactWithNpc(target->getGuid());
|
||||||
}
|
}
|
||||||
|
|
@ -2936,19 +2937,13 @@ void GameScreen::renderGossipWindow(game::GameHandler& gameHandler) {
|
||||||
char label[256];
|
char label[256];
|
||||||
snprintf(label, sizeof(label), "%s %s", icon, opt.text.c_str());
|
snprintf(label, sizeof(label), "%s %s", icon, opt.text.c_str());
|
||||||
if (ImGui::Selectable(label)) {
|
if (ImGui::Selectable(label)) {
|
||||||
if (opt.icon == 4) { // Spirit guide
|
gameHandler.selectGossipOption(opt.id);
|
||||||
gameHandler.selectGossipOption(opt.id);
|
|
||||||
gameHandler.activateSpiritHealer(gossip.npcGuid);
|
|
||||||
gameHandler.closeGossip();
|
|
||||||
} else {
|
|
||||||
gameHandler.selectGossipOption(opt.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback: some spirit healers don't send gossip options.
|
// Fallback: some spirit healers don't send gossip options.
|
||||||
if (gossip.options.empty() && gameHandler.isPlayerDead()) {
|
if (gossip.options.empty() && gameHandler.isPlayerGhost()) {
|
||||||
bool isSpirit = false;
|
bool isSpirit = false;
|
||||||
if (npcEntity && npcEntity->getType() == game::ObjectType::UNIT) {
|
if (npcEntity && npcEntity->getType() == game::ObjectType::UNIT) {
|
||||||
auto unit = std::static_pointer_cast<game::Unit>(npcEntity);
|
auto unit = std::static_pointer_cast<game::Unit>(npcEntity);
|
||||||
|
|
@ -3512,7 +3507,7 @@ void GameScreen::renderTaxiWindow(game::GameHandler& gameHandler) {
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
void GameScreen::renderDeathScreen(game::GameHandler& gameHandler) {
|
void GameScreen::renderDeathScreen(game::GameHandler& gameHandler) {
|
||||||
if (!gameHandler.isPlayerDead()) return;
|
if (!gameHandler.showDeathDialog()) return;
|
||||||
|
|
||||||
auto* window = core::Application::getInstance().getWindow();
|
auto* window = core::Application::getInstance().getWindow();
|
||||||
float screenW = window ? static_cast<float>(window->getWidth()) : 1280.0f;
|
float screenW = window ? static_cast<float>(window->getWidth()) : 1280.0f;
|
||||||
|
|
@ -3567,6 +3562,60 @@ void GameScreen::renderDeathScreen(game::GameHandler& gameHandler) {
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameScreen::renderResurrectDialog(game::GameHandler& gameHandler) {
|
||||||
|
if (!gameHandler.showResurrectDialog()) return;
|
||||||
|
|
||||||
|
auto* window = core::Application::getInstance().getWindow();
|
||||||
|
float screenW = window ? static_cast<float>(window->getWidth()) : 1280.0f;
|
||||||
|
float screenH = window ? static_cast<float>(window->getHeight()) : 720.0f;
|
||||||
|
|
||||||
|
float dlgW = 300.0f;
|
||||||
|
float dlgH = 110.0f;
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(screenW / 2 - dlgW / 2, screenH * 0.3f), ImGuiCond_Always);
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(dlgW, dlgH), ImGuiCond_Always);
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 8.0f);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.1f, 0.1f, 0.15f, 0.95f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.4f, 0.4f, 0.8f, 1.0f));
|
||||||
|
|
||||||
|
if (ImGui::Begin("##ResurrectDialog", nullptr,
|
||||||
|
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
|
||||||
|
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar)) {
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
const char* text = "Return to life?";
|
||||||
|
float textW = ImGui::CalcTextSize(text).x;
|
||||||
|
ImGui::SetCursorPosX((dlgW - textW) / 2);
|
||||||
|
ImGui::TextColored(ImVec4(0.8f, 0.9f, 1.0f, 1.0f), "%s", text);
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
float btnW = 100.0f;
|
||||||
|
float spacing = 20.0f;
|
||||||
|
ImGui::SetCursorPosX((dlgW - btnW * 2 - spacing) / 2);
|
||||||
|
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.5f, 0.2f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.3f, 0.7f, 0.3f, 1.0f));
|
||||||
|
if (ImGui::Button("Accept", ImVec2(btnW, 30))) {
|
||||||
|
gameHandler.acceptResurrect();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor(2);
|
||||||
|
|
||||||
|
ImGui::SameLine(0, spacing);
|
||||||
|
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.5f, 0.2f, 0.2f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.7f, 0.3f, 0.3f, 1.0f));
|
||||||
|
if (ImGui::Button("Decline", ImVec2(btnW, 30))) {
|
||||||
|
gameHandler.declineResurrect();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleColor(2);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
ImGui::PopStyleColor(2);
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Settings Window
|
// Settings Window
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue