diff --git a/src/global_world_state.cpp b/src/global_world_state.cpp new file mode 100644 index 0000000..b22257b --- /dev/null +++ b/src/global_world_state.cpp @@ -0,0 +1,56 @@ +#include "global_world_state.hpp" +#include "character_actor.hpp" +#include "utils/game_root.hpp" + +namespace godot::goap { +void GlobalWorldState::_bind_methods() { +#define CLASSNAME GlobalWorldState +} + +bool GlobalWorldState::has_singleton() { + return GlobalWorldState::singleton_instance != nullptr; +} + +void GlobalWorldState::_enter_tree() { + if(GlobalWorldState::singleton_instance == nullptr) + GlobalWorldState::singleton_instance = this; +} + +void GlobalWorldState::_ready() { + this->game_mode = GameRoot::get_singleton()->get_game_mode(); +} + +void GlobalWorldState::_exit_tree() { + if(GlobalWorldState::singleton_instance == this) + GlobalWorldState::singleton_instance = nullptr; +} + +void GlobalWorldState::_process(double delta_time) { + global_state_cache.clear(); // invalidate cache +} + +Vector3 GlobalWorldState::get_player_position() { + return this->game_mode->get_player_instance()->get_character()->get_global_position(); +} + +Variant GlobalWorldState::get_world_property(StringName prop_key) { + // check if prop key corresponds to a global key + if(!prop_key.begins_with("g_")) + return nullptr; + // check if the key is cached for this frame + else if(global_state_cache.has(prop_key)) + return global_state_cache[prop_key]; + // fetch by function name + StringName const fn = "get_" + prop_key.right(prop_key.length() - 2); + if(this->has_method(fn)) { + Variant result = this->call(fn); + // cache and return + this->global_state_cache[prop_key] = result; + return result; + } + return nullptr; +} + +GlobalWorldState *GlobalWorldState::singleton_instance{nullptr}; +} + diff --git a/src/global_world_state.hpp b/src/global_world_state.hpp new file mode 100644 index 0000000..a8f1eed --- /dev/null +++ b/src/global_world_state.hpp @@ -0,0 +1,31 @@ +#ifndef GOAP_GLOBAL_WORLD_STATE_HPP +#define GOAP_GLOBAL_WORLD_STATE_HPP + +#include "action.hpp" +#include "tunnels_game_mode.hpp" +#include + +namespace godot::goap { +class GlobalWorldState : public Node { + GDCLASS(GlobalWorldState, Node); + static void _bind_methods(); +public: + static bool has_singleton(); + static GlobalWorldState *get_singleton(); + + virtual void _enter_tree() override; + virtual void _ready() override; + virtual void _exit_tree() override; + virtual void _process(double delta_time) override; + + Vector3 get_player_position(); + + Variant get_world_property(StringName prop_key); +private: + WorldState global_state_cache{}; + Ref game_mode{}; + static GlobalWorldState *singleton_instance; +}; +} + +#endif // !GOAP_GLOBAL_WORLD_STATE_HPP