#pragma once #include "loader/module_loader.hpp" #include "game/game.hpp" #include "utils/hook.hpp" #include "utils/chain.hpp" class scripting final : public module { public: class entity final { public: entity(scripting* environment, unsigned int entity_id); void on_notify(const std::string& event, const std::function&)>& callback, bool is_volatile) const; unsigned int get_entity_id() const; game::native::scr_entref_t get_entity_reference() const; private: scripting* environment_; unsigned int entity_id_; }; class variable final { public: variable(game::native::VariableValue value); ~variable(); operator game::native::VariableValue() const; private: game::native::VariableValue value_; }; class event_listener final { public: std::string event = {}; unsigned int entity_id = 0; std::function&)> callback = {}; bool is_volatile = false; }; void post_start() override; void post_load() override; void pre_destroy() override; static void on_start(const std::function& callback); static void on_stop(const std::function& callback); private: std::unique_ptr chai_; utils::chain event_listeners_; void add_event_listener(const event_listener& listener); void initialize(); void load_scripts() const; chaiscript::Boxed_Value make_boxed(game::native::VariableValue value); static utils::hook start_hook_; static utils::hook stop_hook_; static std::mutex mutex_; static std::vector> start_callbacks_; static std::vector> stop_callbacks_; static void start_execution(); static void stop_execution(); };