Working on messenger

This commit is contained in:
Vladislav Khorev committed 2026-06-05 12:13:02 +03:00
1 parent 9221ab68ac
commit 1fc8120ee0
25 files changed
+445 -259

No files matched your search

+72 -18
View File
@@ -122,6 +122,18 @@ namespace ZL {
questJournal.loadFromFile("resources/quests/quests.json", zipFile);
const std::string imgDir = "resources/w/ui/img/phone/";
texBubbleInCenter_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_in_center.png", zipFile, true);
texBubbleInLT_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_in_corner_left_top.png", zipFile, true);
texBubbleInLB_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_in_corner_left_bottom.png", zipFile, true);
texBubbleInRT_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_in_corner_right_top.png", zipFile, true);
texBubbleInRB_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_in_corner_right_bottom.png",zipFile, true);
texBubbleOutCenter_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_out_center.png", zipFile, true);
texBubbleOutLT_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_out_corner_left_top.png", zipFile, true);
texBubbleOutLB_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_out_corner_left_bottom.png",zipFile, true);
texBubbleOutRT_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_out_corner_right_top.png", zipFile, true);
texBubbleOutRB_ = renderer.textureManager.LoadFromPng(imgDir + "bubble_out_corner_right_bottom.png",zipFile, true);
enterGameplay();
}
@@ -335,15 +347,15 @@ namespace ZL {
uiManager.setButtonCallback("phoneMain", [this](const std::string&) {});
uiManager.setTextButtonCallback("chat1button", [this](const std::string&) {
chatUnread_[0] = false;
openPhoneChatFromList(phoneChat1Root, "dialog_chat_aiperi001");
openPhoneChatFromList(0, phoneChat1Root, "dialog_chat_aiperi001");
});
uiManager.setTextButtonCallback("chat2button", [this](const std::string&) {
chatUnread_[1] = false;
openPhoneChatFromList(phoneChat2Root, "dialog_chat_parents001");
openPhoneChatFromList(1, phoneChat2Root, "dialog_chat_parents001");
});
uiManager.setTextButtonCallback("chat3button", [this](const std::string&) {
chatUnread_[2] = false;
openPhoneChatFromList(phoneChat3Root, "dialog_chat_news001");
openPhoneChatFromList(2, phoneChat3Root, "dialog_chat_news001");
});
}
@@ -424,14 +436,14 @@ namespace ZL {
});
}
void MenuManager::openPhoneChatFromList(std::shared_ptr<UiNode> chatRoot, const std::string& dialogueId) {
void MenuManager::openPhoneChatFromList(int chatIndex, std::shared_ptr<UiNode> chatRoot, const std::string& dialogueId) {
activeChatIndex_ = chatIndex;
phoneChatVisibleBubbles_.clear();
uiManager.pushMenuFromSavedRoot(chatRoot);
const bool firstOpen = dialogueId.empty() || startedDialogues_.find(dialogueId) == startedDialogues_.end();
if (firstOpen) {
resetPhoneChatNodes();
}
rebuildChatBubblesFromHistory(chatIndex);
uiManager.setButtonCallback("phoneExitButton", [this](const std::string&) {
closePhoneScreenFromChat();
@@ -448,12 +460,14 @@ namespace ZL {
}
void MenuManager::returnToPhoneChatList() {
activeChatIndex_ = -1;
phoneChatVisibleBubbles_.clear();
uiManager.popMenu();
refreshChatUnreadIndicators();
}
void MenuManager::closePhoneEntirely() {
activeChatIndex_ = -1;
state = GameState::Gameplay;
phoneChatVisibleBubbles_.clear();
const int depth = uiManager.menuStackSize();
@@ -754,19 +768,59 @@ namespace ZL {
uiManager.updateAllLayouts();
}
void MenuManager::revealPhoneChatBubble(const std::string& slotName) {
if (state != GameState::PhoneScreen) return;
auto node = uiManager.findNode(slotName);
if (!node) return;
void MenuManager::rebuildChatBubblesFromHistory(int chatIndex) {
uiManager.clearChatBubbles("chatMessagesContainer");
phoneChatVisibleBubbles_.clear();
// Zero scale before making visible to avoid a one-frame flash at full size
node->scaleX = 0.0f;
node->scaleY = 0.0f;
phoneChatVisibleBubbles_.push_back({slotName, node->height});
uiManager.setNodeVisible(slotName, true);
if (chatIndex < 0 || chatIndex > 2) return;
for (const auto& msg : chatHistory_[chatIndex]) {
const bool inc = msg.incoming;
const std::string nodeName = uiManager.addChatBubble(
"chatMessagesContainer", msg.text, inc,
inc ? texBubbleInCenter_ : texBubbleOutCenter_,
inc ? texBubbleInLT_ : texBubbleOutLT_,
inc ? texBubbleInLB_ : texBubbleOutLB_,
inc ? texBubbleInRT_ : texBubbleOutRT_,
inc ? texBubbleInRB_ : texBubbleOutRB_,
renderer, "resources/fonts/DroidSans.ttf", 20, zipFile_);
if (!nodeName.empty()) {
auto n = uiManager.findNode(nodeName);
phoneChatVisibleBubbles_.push_back({ nodeName, n ? n->height : 60.0f });
}
}
recomputePhoneChatPositions();
uiManager.startPopIn(slotName, 300.0f);
}
void MenuManager::onChatBubbleReady(const std::string& text, bool incoming) {
if (activeChatIndex_ < 0) return;
auto& history = chatHistory_[activeChatIndex_];
if (static_cast<int>(history.size()) >= 5) {
history.erase(history.begin());
}
history.push_back({ text, incoming });
if (state != GameState::PhoneScreen) return;
const std::string nodeName = uiManager.addChatBubble(
"chatMessagesContainer", text, incoming,
incoming ? texBubbleInCenter_ : texBubbleOutCenter_,
incoming ? texBubbleInLT_ : texBubbleOutLT_,
incoming ? texBubbleInLB_ : texBubbleOutLB_,
incoming ? texBubbleInRT_ : texBubbleOutRT_,
incoming ? texBubbleInRB_ : texBubbleOutRB_,
renderer, "resources/fonts/DroidSans.ttf", 20, zipFile_);
if (nodeName.empty()) return;
auto node = uiManager.findNode(nodeName);
if (node) {
node->scaleX = 0.0f;
node->scaleY = 0.0f;
phoneChatVisibleBubbles_.push_back({ nodeName, node->height });
}
recomputePhoneChatPositions();
uiManager.startPopIn(nodeName, 300.0f);
}
void MenuManager::setDarklandsMode(bool enabled)