Fixing inventory and HUD screen

This commit is contained in:
Vladislav Khorev 2026-05-31 21:11:58 +03:00
parent 03681bedaf
commit 5f7e66f765
8 changed files with 294 additions and 7 deletions

View File

@ -0,0 +1,88 @@
{
"root": {
"type": "FrameLayout",
"name": "hud_root",
"width": "match_parent",
"height": "match_parent",
"children": [
{
"type": "Button",
"name": "phoneButton",
"horizontal_gravity": "right",
"vertical_gravity": "bottom",
"x": -46,
"y": -46,
"width": 229,
"height": 229,
"clickZoneWidth": 104,
"clickZoneHeight": 104,
"textures": {
"normal": "resources/w/ui/img/Phone001_State=Default.png",
"hover": "resources/w/ui/img/Phone001_State=Selected.png",
"pressed": "resources/w/ui/img/Phone001_State=Tap.png"
}
},
{
"type": "Button",
"name": "settingsButton",
"horizontal_gravity": "right",
"vertical_gravity": "top",
"x": -23,
"y": -35,
"width": 200,
"height": 200,
"clickZoneWidth": 176,
"clickZoneHeight": 176,
"textures": {
"normal": "resources/w/ui/img/Settings001_State=Default001.png",
"hover": "resources/w/ui/img/Settings001_State=Selected001.png",
"pressed": "resources/w/ui/img/Settings001_State=Tap001.png"
}
},
{
"type": "Button",
"name": "inventoryButton",
"horizontal_gravity": "right",
"vertical_gravity": "top",
"x": 110,
"y": -18,
"width": 165,
"height": 165,
"clickZoneWidth": 151,
"clickZoneHeight": 151,
"textures": {
"normal": "resources/w/ui/img/Inventory001_State=Default001.png",
"hover": "resources/w/ui/img/Inventory001_State=Selected001.png",
"pressed": "resources/w/ui/img/Inventory001_State=Tap001.png"
}
},
{
"type": "Button",
"name": "journalButton",
"horizontal_gravity": "right",
"vertical_gravity": "top",
"x": 220,
"y": -18,
"width": 165,
"height": 165,
"clickZoneWidth": 89,
"clickZoneHeight": 89,
"textures": {
"normal": "resources/w/ui/img/Journal001_State=Default.png",
"hover": "resources/w/ui/img/Journal001_State=Selected.png",
"pressed": "resources/w/ui/img/Journal001_State=Tap.png"
}
},
{
"type": "StaticImage",
"name": "location",
"width": 380,
"height": 64,
"y": 30,
"horizontal_gravity": "center",
"vertical_align": "top",
"texture": "resources/w/ui/img/Location_uni_ext.png"
}
]
}
}

View File

@ -0,0 +1,88 @@
{
"root": {
"type": "FrameLayout",
"name": "hud_root",
"width": "match_parent",
"height": "match_parent",
"children": [
{
"type": "Button",
"name": "phoneButton",
"horizontal_gravity": "right",
"vertical_gravity": "bottom",
"x": -46,
"y": -46,
"width": 229,
"height": 229,
"clickZoneWidth": 104,
"clickZoneHeight": 104,
"textures": {
"normal": "resources/w/ui/img/Phone001_State=Default.png",
"hover": "resources/w/ui/img/Phone001_State=Selected.png",
"pressed": "resources/w/ui/img/Phone001_State=Tap.png"
}
},
{
"type": "Button",
"name": "settingsButton",
"horizontal_gravity": "right",
"vertical_gravity": "top",
"x": -23,
"y": -35,
"width": 200,
"height": 200,
"clickZoneWidth": 176,
"clickZoneHeight": 176,
"textures": {
"normal": "resources/w/ui/img/Settings001_State=Default001.png",
"hover": "resources/w/ui/img/Settings001_State=Selected001.png",
"pressed": "resources/w/ui/img/Settings001_State=Tap001.png"
}
},
{
"type": "Button",
"name": "inventoryButton",
"horizontal_gravity": "right",
"vertical_gravity": "top",
"x": 110,
"y": -18,
"width": 165,
"height": 165,
"clickZoneWidth": 151,
"clickZoneHeight": 151,
"textures": {
"normal": "resources/w/ui/img/Inventory001_State=Default001.png",
"hover": "resources/w/ui/img/Inventory001_State=Selected001.png",
"pressed": "resources/w/ui/img/Inventory001_State=Tap001.png"
}
},
{
"type": "Button",
"name": "journalButton",
"horizontal_gravity": "right",
"vertical_gravity": "top",
"x": 220,
"y": -18,
"width": 165,
"height": 165,
"clickZoneWidth": 89,
"clickZoneHeight": 89,
"textures": {
"normal": "resources/w/ui/img/Journal001_State=Default.png",
"hover": "resources/w/ui/img/Journal001_State=Selected.png",
"pressed": "resources/w/ui/img/Journal001_State=Tap.png"
}
},
{
"type": "StaticImage",
"name": "location",
"width": 380,
"height": 64,
"y": 30,
"horizontal_gravity": "center",
"vertical_align": "top",
"texture": "resources/w/ui/img/Location_uni_int.png"
}
]
}
}

BIN
resources/w/ui/img/Darklands001_State=Default001.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/w/ui/img/Darklands001_State=Hover001.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/w/ui/img/Darklands001_State=Pressed001.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -364,6 +364,7 @@ namespace ZL
}
currentLocation->cameraAzimuth = destRotY;
currentLocation->scriptEngine.callLocationEnterCallback();
menuManager.onLocationChanged(destName);
};
locations["uni_exterior"]->onTeleport = teleportCallback;

View File

@ -81,6 +81,8 @@ namespace ZL {
hudStep5aRoot = loadUiFromFile("resources/w/ui/hud_step5a.json", renderer, zipFile);
hudStep5bRoot = loadUiFromFile("resources/w/ui/hud_step5b.json", renderer, zipFile);
hudStep5abRoot = loadUiFromFile("resources/w/ui/hud_step5ab.json", renderer, zipFile);
hudUniExtRoot = loadUiFromFile("resources/w/ui/hud_uni_ext.json", renderer, zipFile);
hudUniIntRoot = loadUiFromFile("resources/w/ui/hud_uni_int.json", renderer, zipFile);
phoneChatListRoot = loadUiFromFile("resources/w/ui/screen_phone_chat_list.json", renderer, zipFile);
phoneChat1Root = loadUiFromFile("resources/w/ui/screen_phone_chat1.json", renderer, zipFile);
phoneChat2Root = loadUiFromFile("resources/w/ui/screen_phone_chat2.json", renderer, zipFile);
@ -123,12 +125,6 @@ namespace ZL {
uiManager.setButtonCallback("inventoryExitButton", [this](const std::string&) {
closeInventory();
});
/*
uiManager.pushMenuFromSavedRoot(inventoryRoot);
uiManager.setTextButtonCallback("close_inventory_button", [this](const std::string&) {
closeInventory();
});
const auto& items = inventory->getItems();
std::string itemText;
@ -139,11 +135,74 @@ namespace ZL {
itemText = "Inventory (" + std::to_string(items.size()) + " items)\n\n";
for (size_t i = 0; i < items.size(); ++i) {
itemText += std::to_string(i + 1) + ". " + items[i].name + "\n";
const int maxSlots = 7;
for (int i = 0; i < maxSlots; ++i) {
const std::string btnName = "item" + std::to_string(i + 1) + "Button";
if (i < static_cast<int>(items.size())) {
uiManager.setNodeVisible(btnName, true);
auto btn = uiManager.findButton(btnName);
if (btn) {
auto tex = renderer.textureManager.LoadFromPng(items[i].icon, zipFile_, true);
btn->texNormal = btn->texHover = btn->texPressed = tex;
}
uiManager.setButtonCallback(btnName, [this, i](const std::string&) {
selectInventoryItem(i);
});
}
else {
uiManager.setNodeVisible(btnName, false);
}
}
inventorySelectedIndex_ = -1;
if (!items.empty()) {
selectInventoryItem(0);
}
}
}
uiManager.setText("inventory_items_text", itemText);*/
}
void MenuManager::selectInventoryItem(int index) {
const auto& items = inventory->getItems();
if (index < 0 || index >= static_cast<int>(items.size())) return;
// Revert previously selected button to its regular icon
if (inventorySelectedIndex_ >= 0 && inventorySelectedIndex_ < static_cast<int>(items.size())) {
const std::string prevBtnName = "item" + std::to_string(inventorySelectedIndex_ + 1) + "Button";
auto prevBtn = uiManager.findButton(prevBtnName);
if (prevBtn) {
auto tex = renderer.textureManager.LoadFromPng(items[inventorySelectedIndex_].icon, zipFile_, true);
prevBtn->texNormal = prevBtn->texHover = prevBtn->texPressed = tex;
}
}
inventorySelectedIndex_ = index;
const auto& item = items[index];
// Highlight newly selected button with its selected icon
const std::string btnName = "item" + std::to_string(index + 1) + "Button";
auto btn = uiManager.findButton(btnName);
if (btn) {
const std::string& selPath = item.selectedIcon.empty() ? item.icon : item.selectedIcon;
auto tex = renderer.textureManager.LoadFromPng(selPath, zipFile_, true);
btn->texNormal = btn->texHover = btn->texPressed = tex;
}
// Update the large selected picture on the right panel
auto img = uiManager.findStaticImage("selectedItemPic");
if (img) {
const std::string& path = item.selectedIcon.empty() ? item.icon : item.selectedIcon;
img->texture = renderer.textureManager.LoadFromPng(path, zipFile_, true);
}
uiManager.setText("selectedText", item.name);
uiManager.setText("selectedDescription", item.description);
}
void MenuManager::closeInventory() {
state = GameState::Gameplay;
uiManager.popMenu();
@ -267,6 +326,11 @@ namespace ZL {
openPhoneScreen();
});
}
if (uiManager.findButton("inventoryButton")) {
uiManager.setButtonCallback("inventoryButton", [this](const std::string&) {
openInventory();
});
}
if (uiManager.findButton("journalButton")) {
uiManager.setButtonCallback("journalButton", [this](const std::string&) {
openQuestJournal();
@ -274,6 +338,37 @@ namespace ZL {
}
if (tutorialPhoneScreenOpened) uiManager.setNodeVisible("hint6a", false);
if (tutorialJournalScreenOpened) uiManager.setNodeVisible("hint6b", false);
if (tutorialPhoneScreenOpened && tutorialJournalScreenOpened) {
tutorialStep = TutorialStep::Step6;
}
}
void MenuManager::setupGameplayHudCallbacks() {
uiManager.setButtonCallback("phoneButton", [this](const std::string&) {
openPhoneScreen();
});
uiManager.setButtonCallback("inventoryButton", [this](const std::string&) {
openInventory();
});
uiManager.setButtonCallback("journalButton", [this](const std::string&) {
openQuestJournal();
});
}
void MenuManager::onLocationChanged(const std::string& locationName) {
if (state != GameState::Gameplay) return;
if (locationName == "uni_exterior") {
uiManager.replaceRoot(hudUniExtRoot);
setupGameplayHudCallbacks();
} else if (locationName == "uni_interior") {
uiManager.replaceRoot(hudUniIntRoot);
setupGameplayHudCallbacks();
} else {
// Returning to dorm: reuse step5ab, suppress already-completed hints
uiManager.replaceRoot(hudStep5abRoot);
setupStep5Callbacks();
}
}
void MenuManager::advanceTutorialStep() {

View File

@ -28,6 +28,7 @@ namespace ZL {
Step3, // Pinch-zoom hint
Step4, // Pick-up item hint
Step5, // Post-pickup reaction (sub-state: which items were collected)
Step6, // Tutorial complete — both phone and journal opened
};
class MenuManager {
@ -40,6 +41,7 @@ namespace ZL {
void setup(Inventory& inv, const std::string& zipFile);
void openInventory();
void selectInventoryItem(int index);
void closeInventory();
void openQuestJournal();
@ -58,6 +60,7 @@ namespace ZL {
void advanceTutorialStep();
void onItemPickedUp(const std::string& itemId);
void onLocationChanged(const std::string& locationName);
TutorialStep tutorialStep = TutorialStep::Step0;
@ -70,6 +73,7 @@ namespace ZL {
void selectQuestByIndex(int index);
void refreshItemPickupHud();
void setupStep5Callbacks();
void setupGameplayHudCallbacks();
void resetPhoneChatNodes();
void recomputePhoneChatPositions();
void openPhoneChatFromList(std::shared_ptr<UiNode> chatRoot, const std::string& dialogueId);
@ -94,6 +98,8 @@ namespace ZL {
std::shared_ptr<UiNode> hudStep5aRoot;
std::shared_ptr<UiNode> hudStep5bRoot;
std::shared_ptr<UiNode> hudStep5abRoot;
std::shared_ptr<UiNode> hudUniExtRoot;
std::shared_ptr<UiNode> hudUniIntRoot;
std::shared_ptr<UiNode> phoneChatListRoot;
std::shared_ptr<UiNode> phoneChat1Root;
std::shared_ptr<UiNode> phoneChat2Root;