From bc2997d86f661898e631a3dfb6da71dd4240f68d Mon Sep 17 00:00:00 2001 From: Vlad Date: Sat, 11 Apr 2026 16:18:59 +0600 Subject: [PATCH] added activeFunc for active obj --- resources/start.lua | 13 +----- src/Game.cpp | 19 ++++++-- src/ScriptEngine.cpp | 85 +++++++++++++++++++++++----------- src/ScriptEngine.h | 3 ++ src/items/GameObjectLoader.cpp | 12 ++++- src/items/GameObjectLoader.h | 1 + src/items/InteractiveObject.h | 11 +++++ 7 files changed, 97 insertions(+), 47 deletions(-) diff --git a/resources/start.lua b/resources/start.lua index 3780f38..14b93d7 100644 --- a/resources/start.lua +++ b/resources/start.lua @@ -22,18 +22,7 @@ step1() function on_health_pickup() game_api.pickup_item("health_potion") + print("[Lua] Health potion picked up!") end -function on_item_pickup(object_name) - print("========================================") - print("on_item_pickup CALLBACK CALLED!") - print("Player picked up item from: " .. tostring(object_name)) - print("========================================") - - game_api.pickup_item(object_name) - - --game_api.show_inventory() -end - -print("Lua script loaded successfully!") \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp index e8bce5d..6b1ea68 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -174,7 +174,6 @@ namespace ZL npcs = GameObjectLoader::loadAndCreateNpcs("resources/config2/npcs.json", CONST_ZIP_FILE); /* - // === СТАРЫЙ КОД - ЗАКОММЕНТИРОВАНО, НПС ТЕПЕРЬ ГРУЗЯТСЯ ИЗ JSON === auto defaultTexture = std::make_shared(CreateTextureDataFromPng("resources/w/default_skin001.png", CONST_ZIP_FILE)); @@ -214,8 +213,6 @@ namespace ZL npcs.push_back(std::move(npc02)); std::cout << "Load resurces step 12" << std::endl; - - // === КОНЕЦ СТАРОГО КОДА === */ loadingCompleted = true; @@ -459,8 +456,20 @@ namespace ZL std::cout << "[PICKUP] Player reached object! Distance: " << distToObject << std::endl; std::cout << "[PICKUP] Calling Lua callback for: " << targetInteractiveObject->id << std::endl; - // Call Lua callback - scriptEngine.callItemPickupCallback(targetInteractiveObject->id); + // Call custom activate function if specified, otherwise use fallback + try { + if (!targetInteractiveObject->activateFunctionName.empty()) { + std::cout << "[PICKUP] Using custom function: " << targetInteractiveObject->activateFunctionName << std::endl; + scriptEngine.callActivateFunction(targetInteractiveObject->activateFunctionName); + } + else { + std::cout << "[PICKUP] Using fallback callback" << std::endl; + scriptEngine.callItemPickupCallback(targetInteractiveObject->id); + } + } + catch (const std::exception& e) { + std::cerr << "[PICKUP] Error calling function: " << e.what() << std::endl; + } targetInteractiveObject = nullptr; } diff --git a/src/ScriptEngine.cpp b/src/ScriptEngine.cpp index 2afde43..6d2765b 100644 --- a/src/ScriptEngine.cpp +++ b/src/ScriptEngine.cpp @@ -1,6 +1,7 @@ #include "ScriptEngine.h" #include "Game.h" #include +#include #define SOL_ALL_SAFETIES_ON 1 #include @@ -148,6 +149,62 @@ namespace ZL { } } + void ScriptEngine::callActivateFunction(const std::string& functionName) { + if (!impl) { + throw std::runtime_error("[SCRIPT] Engine not initialized!"); + } + + if (functionName.empty()) { + throw std::runtime_error("[SCRIPT] Activate function name is empty!"); + } + + sol::state& lua = impl->lua; + std::cout << "[SCRIPT] Looking for activate function: " << functionName << std::endl; + + sol::function activateFunc = lua[functionName]; + + if (!activateFunc.valid()) { + throw std::runtime_error("[SCRIPT] Lua function not found: " + functionName); + } + + std::cout << "[SCRIPT] Found function! Calling: " << functionName << std::endl; + auto result = activateFunc(); + + if (!result.valid()) { + sol::error err = result; + throw std::runtime_error("[SCRIPT] Error executing " + functionName + ": " + std::string(err.what())); + } + + std::cout << "[SCRIPT] Function executed successfully!" << std::endl; + } + + void ScriptEngine::callItemPickupCallback(const std::string& objectName) { + if (!impl) { + std::cerr << "[SCRIPT] impl is null!" << std::endl; + return; + } + + sol::state& lua = impl->lua; + + // Try to find custom activate function first + sol::function activateFunc = lua["on_item_pickup"]; + + if (activateFunc.valid()) { + std::cout << "[SCRIPT] Callback found! Calling with argument: " << objectName << std::endl; + auto result = activateFunc(objectName); + if (!result.valid()) { + sol::error err = result; + std::cerr << "[SCRIPT] on_item_pickup callback error: " << err.what() << "\n"; + } + else { + std::cout << "[SCRIPT] Callback executed successfully!" << std::endl; + } + } + else { + std::cout << "[SCRIPT] Fallback: on_item_pickup not found" << std::endl; + } + } + void ScriptEngine::showInventory(Game* game) { std::cout << "[script] toggle_inventory called" << std::endl; @@ -157,7 +214,6 @@ namespace ZL { game->inventoryOpen = !isVisible; - // Update UI with current items only if showing if (!isVisible) { const auto& items = game->inventory.getItems(); std::string itemText; @@ -176,31 +232,4 @@ namespace ZL { } } - void ScriptEngine::callItemPickupCallback(const std::string& objectName) { - if (!impl) { - std::cerr << "[SCRIPT] impl is null!" << std::endl; - return; - } - - sol::state& lua = impl->lua; - std::cout << "[SCRIPT] Looking for callback: on_item_pickup" << std::endl; - - sol::function pickup = lua["on_item_pickup"]; - - if (pickup.valid()) { - std::cout << "[SCRIPT] Callback found! Calling with argument: " << objectName << std::endl; - auto result = pickup(objectName); - if (!result.valid()) { - sol::error err = result; - std::cerr << "[SCRIPT] on_item_pickup callback error: " << err.what() << "\n"; - } - else { - std::cout << "[SCRIPT] Callback executed successfully!" << std::endl; - } - } - else { - std::cerr << "[SCRIPT] on_item_pickup callback not found!" << std::endl; - } - } - } // namespace ZL diff --git a/src/ScriptEngine.h b/src/ScriptEngine.h index 3d0bbc6..1709b79 100644 --- a/src/ScriptEngine.h +++ b/src/ScriptEngine.h @@ -18,6 +18,9 @@ public: void runScript(const std::string& path); void callItemPickupCallback(const std::string& objectName); + + void callActivateFunction(const std::string& functionName); + void showInventory(Game* game); private: diff --git a/src/items/GameObjectLoader.cpp b/src/items/GameObjectLoader.cpp index 7cfe2e4..2b3bf85 100644 --- a/src/items/GameObjectLoader.cpp +++ b/src/items/GameObjectLoader.cpp @@ -61,6 +61,8 @@ namespace ZL { data.interactionRadius = itemData.value("radius", 2.0f); } + data.activateFunctionName = item.value("activateFunction", ""); + if (!data.meshPath.empty()) { objects.push_back(data); } @@ -158,9 +160,11 @@ namespace ZL { std::cout << "Loading interactive object: " << objData.name << std::endl; InteractiveObject intObj; - intObj.id = objData.name; + //intObj.id = objData.name; + intObj.id = !objData.itemId.empty() ? objData.itemId : objData.name; intObj.name = objData.name; intObj.interactionRadius = objData.interactionRadius; + intObj.activateFunctionName = objData.activateFunctionName; // Load texture try { @@ -237,7 +241,11 @@ namespace ZL { interactiveObjects.push_back(intObj); - std::cout << "Successfully loaded interactive: " << objData.name << " (item: " << objData.itemName << ")" << std::endl; + std::cout << "Successfully loaded interactive: " << objData.name << " (item: " << objData.itemName; + if (!objData.activateFunctionName.empty()) { + std::cout << ", function: " << objData.activateFunctionName; + } + std::cout << ")" << std::endl; } std::cout << "Total interactive objects loaded: " << interactiveObjects.size() << std::endl; diff --git a/src/items/GameObjectLoader.h b/src/items/GameObjectLoader.h index 454b17e..fa229d7 100644 --- a/src/items/GameObjectLoader.h +++ b/src/items/GameObjectLoader.h @@ -31,6 +31,7 @@ namespace ZL { std::string itemDescription; std::string itemIcon; float interactionRadius = 2.0f; + std::string activateFunctionName; }; struct NpcData { diff --git a/src/items/InteractiveObject.h b/src/items/InteractiveObject.h index b04fc46..f3a46e6 100644 --- a/src/items/InteractiveObject.h +++ b/src/items/InteractiveObject.h @@ -20,6 +20,17 @@ namespace ZL { VertexRenderStruct mesh; Item dropItem; bool isActive = true; + + bool isNpc = false; + std::string npcInteractCallback; + float walkSpeed = 1.5f; + float rotationSpeed = 8.0f; + float modelScale = 0.01f; + std::string animationIdlePath; + std::string animationWalkPath; + std::string texturePath; + + std::string activateFunctionName; InteractiveObject() : interactionRadius(2.0f) {}