added inventory & active object
This commit is contained in:
1 parent
e1b491be73
commit
b3fda88784
16 files changed
+793
-98
No files matched your search
+185
-40
@@ -7,55 +7,200 @@
|
||||
|
||||
namespace ZL {
|
||||
|
||||
struct ScriptEngine::Impl {
|
||||
sol::state lua;
|
||||
};
|
||||
struct ScriptEngine::Impl {
|
||||
sol::state lua;
|
||||
};
|
||||
|
||||
ScriptEngine::ScriptEngine() = default;
|
||||
ScriptEngine::~ScriptEngine() = default;
|
||||
ScriptEngine::ScriptEngine() = default;
|
||||
ScriptEngine::~ScriptEngine() = default;
|
||||
|
||||
void ScriptEngine::init(Game* game) {
|
||||
impl = std::make_unique<Impl>();
|
||||
sol::state& lua = impl->lua;
|
||||
void ScriptEngine::init(Game* game) {
|
||||
impl = std::make_unique<Impl>();
|
||||
sol::state& lua = impl->lua;
|
||||
|
||||
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string, sol::lib::table);
|
||||
lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string, sol::lib::table);
|
||||
|
||||
auto api = lua.create_named_table("game_api");
|
||||
auto api = lua.create_named_table("game_api");
|
||||
|
||||
// npc_walk_to(index, x, y, z [, on_arrived])
|
||||
// on_arrived is an optional Lua function called when the NPC reaches the target.
|
||||
// It can call npc_walk_to again (or anything else) to chain behaviour.
|
||||
api.set_function("npc_walk_to",
|
||||
[game](int index, float x, float y, float z, sol::object on_arrived) {
|
||||
auto& npcs = game->npcs;
|
||||
if (index < 0 || index >= static_cast<int>(npcs.size())) {
|
||||
std::cerr << "[script] npc_walk_to: index " << index
|
||||
<< " out of range (0.." << npcs.size() - 1 << ")\n";
|
||||
return;
|
||||
// npc_walk_to(index, x, y, z [, on_arrived])
|
||||
// on_arrived is an optional Lua function called when the NPC reaches the target.
|
||||
// It can call npc_walk_to again (or anything else) to chain behaviour.
|
||||
api.set_function("npc_walk_to",
|
||||
[game](int index, float x, float y, float z, sol::object on_arrived) {
|
||||
auto& npcs = game->npcs;
|
||||
if (index < 0 || index >= static_cast<int>(npcs.size())) {
|
||||
std::cerr << "[script] npc_walk_to: index " << index
|
||||
<< " out of range (0.." << npcs.size() - 1 << ")\n";
|
||||
return;
|
||||
}
|
||||
std::function<void()> cb;
|
||||
if (on_arrived.is<sol::protected_function>()) {
|
||||
sol::protected_function fn = on_arrived.as<sol::protected_function>();
|
||||
cb = [fn]() mutable {
|
||||
auto result = fn();
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
std::cerr << "[script] on_arrived error: " << err.what() << "\n";
|
||||
}
|
||||
};
|
||||
}
|
||||
npcs[index]->setTarget(Eigen::Vector3f(x, y, z), std::move(cb));
|
||||
});
|
||||
|
||||
// pickup_item(object_name)
|
||||
api.set_function("pickup_item", [game](const std::string& objectName) {
|
||||
std::cout << "[script] pickup_item: " << objectName << std::endl;
|
||||
|
||||
for (auto& intObj : game->interactiveObjects) {
|
||||
if (intObj.id == objectName && intObj.isActive) {
|
||||
// Add item to inventory
|
||||
game->inventory.addItem(intObj.dropItem);
|
||||
|
||||
// Deactivate object
|
||||
intObj.isActive = false;
|
||||
|
||||
std::cout << "[script] Item picked up successfully: " << intObj.dropItem.name << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::function<void()> cb;
|
||||
if (on_arrived.is<sol::protected_function>()) {
|
||||
sol::protected_function fn = on_arrived.as<sol::protected_function>();
|
||||
cb = [fn]() mutable {
|
||||
auto result = fn();
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
std::cerr << "[script] on_arrived error: " << err.what() << "\n";
|
||||
}
|
||||
};
|
||||
std::cerr << "[script] Warning: Interactive object not found or already picked up: " << objectName << std::endl;
|
||||
});
|
||||
|
||||
|
||||
// show_inventory()
|
||||
api.set_function("show_inventory", [game]() {
|
||||
std::cout << "[script] show_inventory called" << std::endl;
|
||||
|
||||
game->menuManager.uiManager.setNodeVisible("inventory_items_panel", true);
|
||||
game->menuManager.uiManager.setNodeVisible("close_inventory_button", true);
|
||||
game->inventoryOpen = true;
|
||||
|
||||
// Update UI with current items
|
||||
const auto& items = game->inventory.getItems();
|
||||
std::string itemText;
|
||||
|
||||
if (items.empty()) {
|
||||
itemText = "Inventory (Empty)";
|
||||
}
|
||||
else {
|
||||
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";
|
||||
}
|
||||
}
|
||||
npcs[index]->setTarget(Eigen::Vector3f(x, y, z), std::move(cb));
|
||||
});
|
||||
|
||||
runScript("resources/start.lua");
|
||||
}
|
||||
game->menuManager.uiManager.setText("inventory_items_text", itemText);
|
||||
});
|
||||
|
||||
void ScriptEngine::runScript(const std::string& path) {
|
||||
auto result = impl->lua.safe_script_file(path, sol::script_pass_on_error);
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
std::cerr << "[script] Error in " << path << ": " << err.what() << "\n";
|
||||
// hide_inventory()
|
||||
api.set_function("hide_inventory", [game]() {
|
||||
std::cout << "[script] hide_inventory called" << std::endl;
|
||||
game->menuManager.uiManager.setNodeVisible("inventory_items_panel", false);
|
||||
game->menuManager.uiManager.setNodeVisible("close_inventory_button", false);
|
||||
game->inventoryOpen = false;
|
||||
});
|
||||
|
||||
// add_item(item_id, name, description, icon)
|
||||
api.set_function("add_item", [game](const std::string& id, const std::string& name,
|
||||
const std::string& description, const std::string& icon) {
|
||||
std::cout << "[script] add_item: " << name << std::endl;
|
||||
Item newItem(id, name, description, icon);
|
||||
game->inventory.addItem(newItem);
|
||||
});
|
||||
|
||||
// remove_item(item_id)
|
||||
api.set_function("remove_item", [game](const std::string& id) {
|
||||
std::cout << "[script] remove_item: " << id << std::endl;
|
||||
game->inventory.removeItem(id);
|
||||
});
|
||||
|
||||
// deactivate_interactive_object(object_name)
|
||||
api.set_function("deactivate_interactive_object", [game](const std::string& objectName) {
|
||||
std::cout << "[script] deactivate_interactive_object: " << objectName << std::endl;
|
||||
for (auto& intObj : game->interactiveObjects) {
|
||||
if (intObj.id == objectName) {
|
||||
intObj.isActive = false;
|
||||
std::cout << "[script] Interactive object deactivated: " << objectName << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::cerr << "[script] Warning: Interactive object not found: " << objectName << std::endl;
|
||||
});
|
||||
|
||||
// get_inventory_count()
|
||||
api.set_function("get_inventory_count", [game]() {
|
||||
return game->inventory.getCount();
|
||||
});
|
||||
|
||||
// has_item(item_id)
|
||||
api.set_function("has_item", [game](const std::string& id) {
|
||||
return game->inventory.hasItem(id);
|
||||
});
|
||||
|
||||
lua.script_file("resources/start.lua");
|
||||
}
|
||||
|
||||
void ScriptEngine::runScript(const std::string& path) {
|
||||
auto result = impl->lua.safe_script_file(path, sol::script_pass_on_error);
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
std::cerr << "[script] Error in " << path << ": " << err.what() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::showInventory(Game* game) {
|
||||
std::cout << "[script] toggle_inventory called" << std::endl;
|
||||
|
||||
bool isVisible = game->menuManager.uiManager.getNodeVisible("inventory_items_panel");
|
||||
game->menuManager.uiManager.setNodeVisible("inventory_items_panel", !isVisible);
|
||||
game->menuManager.uiManager.setNodeVisible("close_inventory_button", !isVisible);
|
||||
|
||||
game->inventoryOpen = !isVisible;
|
||||
|
||||
// Update UI with current items only if showing
|
||||
if (!isVisible) {
|
||||
const auto& items = game->inventory.getItems();
|
||||
std::string itemText;
|
||||
|
||||
if (items.empty()) {
|
||||
itemText = "Inventory (Empty)";
|
||||
}
|
||||
else {
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
game->menuManager.uiManager.setText("inventory_items_text", itemText);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
Reference in new issue
Block a user