More work on states, added bot

This commit is contained in:
Vladislav Khorev committed 2026-10-29 22:37:30 +06:00
1 parent 66e93d46f4
commit 5e9a663812
25 files changed
+1595 -740

No files matched your search

+38 -81
View File
@@ -66,9 +66,6 @@ namespace FRG {
std::unordered_map<std::string, sol::protected_function> cutsceneCompleteCallbacks;
std::unordered_map<std::string, sol::protected_function> npcBumpedByPlayerCallbacks;
std::unordered_map<std::string, sol::protected_function> npcBumpsPlayerCallbacks;
std::unordered_map<std::string, int>* globalInts = nullptr;
std::unordered_map<std::string, float>* globalFloats = nullptr;
Quest::QuestJournal* questJournal = nullptr;
sol::protected_function locationInitCallback;
sol::protected_function locationEnterCallback;
sol::protected_function locationExitCallback;
@@ -82,7 +79,7 @@ namespace FRG {
ScriptEngine::ScriptEngine() = default;
ScriptEngine::~ScriptEngine() = default;
void ScriptEngine::init(Location* loc, Inventory* inventory, AudioPlayerAsync* audioPlayer, const std::string& scriptPath) {
void ScriptEngine::init(Location* loc, AudioPlayerAsync* audioPlayer, const std::string& scriptPath) {
impl = std::make_unique<Impl>();
sol::state& lua = impl->lua;
@@ -199,10 +196,10 @@ namespace FRG {
});
api.set_function("has_item", [inventory](const std::string& itemId) {
api.set_function("has_item", [loc](const std::string& itemId) {
const Item* item = ItemRegistry::instance().findById(itemId);
if (item) {
if (inventory->hasItem(itemId)) {
if (loc->hasInventoryItem(itemId)) {
logger() << "[script] has_item: " << item->name << " returns true" << std::endl;
return true;
}
@@ -219,10 +216,10 @@ namespace FRG {
});
// pickup_item(item_id)
api.set_function("pickup_item", [inventory](const std::string& itemId) {
api.set_function("pickup_item", [loc](const std::string& itemId) {
const Item* item = ItemRegistry::instance().findById(itemId);
if (item) {
inventory->addItem(item->id);
loc->addInventoryItem(item->id);
logger() << "[script] pickup_item: " << item->name << std::endl;
} else {
std::cerr << "[script] pickup_item: item '" << itemId << "' not found in ItemRegistry\n";
@@ -230,9 +227,9 @@ namespace FRG {
});
// remove_item(item_id)
api.set_function("remove_item", [loc, inventory](const std::string& id) {
api.set_function("remove_item", [loc](const std::string& id) {
logger() << "[script] remove_item: " << id << std::endl;
inventory->removeItem(id);
loc->removeInventoryItem(id);
});
api.set_function("deactivate_interactive_object", [loc](const std::string& objectId) {
@@ -276,13 +273,13 @@ namespace FRG {
});
// get_inventory_count()
api.set_function("get_inventory_count", [inventory]() {
return inventory->getCount();
api.set_function("get_inventory_count", [loc]() {
return loc->inventoryItemCount();
});
// has_item(item_id)
api.set_function("has_item", [inventory](const std::string& id) {
return inventory->hasItem(id);
api.set_function("has_item", [loc](const std::string& id) {
return loc->hasInventoryItem(id);
});
api.set_function("start_dialogue",
@@ -381,12 +378,12 @@ namespace FRG {
api.set_function("is_night",
[loc]() {
return loc->state.isNight;
return loc->isNight();
});
api.set_function("is_dawn",
[loc]() {
return loc->state.isDawn;
return loc->isDawn();
});
// advance_darklands_hud()
@@ -415,27 +412,26 @@ namespace FRG {
// is_darklands() → bool
api.set_function("is_darklands",
[loc]() { return loc->state.isDarklands; });
[loc]() { return loc->isDarklands(); });
api.set_function("setFloatValue",
[this_impl = impl.get()](const std::string& key, float value) {
if (this_impl->globalFloats)
(*this_impl->globalFloats)[key] = value;
[loc](const std::string& key, float value) {
loc->setGlobalFloat(key, value);
});
api.set_function("getFloatValue",
[this_impl = impl.get()](const std::string& key) -> float {
if (!this_impl->globalFloats) return 0.0f;
auto it = this_impl->globalFloats->find(key);
return it != this_impl->globalFloats->end() ? it->second : 0.0f;
[loc](const std::string& key) -> float {
return loc->globalFloat(key);
});
api.set_function("get_player_x",
[loc]() -> float {
return loc->player ? loc->player->characterState.position.x() : 0.0f;
auto state = loc->player ? loc->player->stateSnapshot() : nullptr;
return state ? state->position.x() : 0.0f;
});
api.set_function("get_player_z",
[loc]() -> float {
return loc->player ? loc->player->characterState.position.z() : 0.0f;
auto state = loc->player ? loc->player->stateSnapshot() : nullptr;
return state ? state->position.z() : 0.0f;
});
// set_player_hp(value) — sets the player's current HP directly.
@@ -462,15 +458,12 @@ namespace FRG {
// Global integer store — shared across all location scripts.
// setIntValue(key, value) / getIntValue(key) → int (0 if not set)
api.set_function("setIntValue",
[this_impl = impl.get()](const std::string& key, int value) {
if (this_impl->globalInts)
(*this_impl->globalInts)[key] = value;
[loc](const std::string& key, int value) {
loc->setGlobalInt(key, value);
});
api.set_function("getIntValue",
[this_impl = impl.get()](const std::string& key) -> int {
if (!this_impl->globalInts) return 0;
auto it = this_impl->globalInts->find(key);
return it != this_impl->globalInts->end() ? it->second : 0;
[loc](const std::string& key) -> int {
return loc->globalInt(key);
});
// set_darklands_callbacks(on_enter, on_exit)
@@ -806,64 +799,40 @@ namespace FRG {
// quest_unlock(quest_id)
api.set_function("quest_unlock",
[this_impl = impl.get()](const std::string& questId) -> bool {
if (!this_impl->questJournal) {
std::cerr << "[script] quest_unlock: QuestJournal not set\n";
return false;
}
return this_impl->questJournal->unlockQuest(questId);
[loc](const std::string& questId) -> bool {
return loc->unlockQuest(questId);
});
// quest_complete(quest_id)
api.set_function("quest_complete",
[this_impl = impl.get()](const std::string& questId) -> bool {
if (!this_impl->questJournal) {
std::cerr << "[script] quest_complete: QuestJournal not set\n";
return false;
}
return this_impl->questJournal->completeQuest(questId);
[loc](const std::string& questId) -> bool {
return loc->completeQuest(questId);
});
// quest_fail(quest_id)
api.set_function("quest_fail",
[this_impl = impl.get()](const std::string& questId) -> bool {
if (!this_impl->questJournal) {
std::cerr << "[script] quest_fail: QuestJournal not set\n";
return false;
}
return this_impl->questJournal->failQuest(questId);
[loc](const std::string& questId) -> bool {
return loc->failQuest(questId);
});
// quest_set_objective_completed(quest_id, objective_id [, completed])
api.set_function("quest_set_objective_completed",
[this_impl = impl.get()](const std::string& questId, const std::string& objId, sol::object completed) -> bool {
if (!this_impl->questJournal) {
std::cerr << "[script] quest_set_objective_completed: QuestJournal not set\n";
return false;
}
[loc](const std::string& questId, const std::string& objId, sol::object completed) -> bool {
const bool val = completed.is<bool>() ? completed.as<bool>() : true;
return this_impl->questJournal->setObjectiveCompleted(questId, objId, val);
return loc->setQuestObjectiveCompleted(questId, objId, val);
});
// quest_set_objective_visible(quest_id, objective_id [, visible])
api.set_function("quest_set_objective_visible",
[this_impl = impl.get()](const std::string& questId, const std::string& objId, sol::object visible) -> bool {
if (!this_impl->questJournal) {
std::cerr << "[script] quest_set_objective_visible: QuestJournal not set\n";
return false;
}
[loc](const std::string& questId, const std::string& objId, sol::object visible) -> bool {
const bool val = visible.is<bool>() ? visible.as<bool>() : true;
return this_impl->questJournal->setObjectiveVisible(questId, objId, val);
return loc->setQuestObjectiveVisible(questId, objId, val);
});
// quest_set_active_objective(quest_id, objective_index)
api.set_function("quest_set_active_objective",
[this_impl = impl.get()](const std::string& questId, int index) -> bool {
if (!this_impl->questJournal) {
std::cerr << "[script] quest_set_active_objective: QuestJournal not set\n";
return false;
}
return this_impl->questJournal->setActiveObjective(questId, index);
[loc](const std::string& questId, int index) -> bool {
return loc->setQuestActiveObjective(questId, index);
});
api.set_function("call_tutorial_taxi_required",
@@ -1033,18 +1002,6 @@ namespace FRG {
}
}
void ScriptEngine::setGlobalStore(std::unordered_map<std::string, int>* store) {
if (impl) impl->globalInts = store;
}
void ScriptEngine::setGlobalFloatStore(std::unordered_map<std::string, float>* store) {
if (impl) impl->globalFloats = store;
}
void ScriptEngine::setQuestJournal(Quest::QuestJournal* journal) {
if (impl) impl->questJournal = journal;
}
void ScriptEngine::callLocationInitCallback() {
if (!impl || !impl->locationInitCallback.valid()) return;
auto result = impl->locationInitCallback();