feat: swapped from godot:: to utils:: namespace
This commit is contained in:
		
							parent
							
								
									54fcbcbb6b
								
							
						
					
					
						commit
						3cad3af3fe
					
				|  | @ -5,25 +5,25 @@ | |||
| #include "utils/godot_macros.h" | ||||
| #include "game_state.hpp" | ||||
| 
 | ||||
| namespace godot { | ||||
| namespace utils { | ||||
| void GameMode::_bind_methods() { | ||||
| #define CLASSNAME GameMode | ||||
|     GDPROPERTY_HINTED(game_state, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "GameState"); | ||||
|     GDPROPERTY_HINTED(player_scene, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); | ||||
|     GDPROPERTY_HINTED(game_state, gd::Variant::OBJECT, gd::PROPERTY_HINT_RESOURCE_TYPE, "GameState"); | ||||
|     GDPROPERTY_HINTED(player_scene, gd::Variant::OBJECT, gd::PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); | ||||
| } | ||||
| 
 | ||||
| void GameMode::_begin() {} | ||||
| void GameMode::_end() {} | ||||
| 
 | ||||
| void GameMode::set_player_scene(Ref<PackedScene> scene) { | ||||
| void GameMode::set_player_scene(gd::Ref<gd::PackedScene> scene) { | ||||
|     this->player_scene = scene; | ||||
| } | ||||
| 
 | ||||
| Ref<PackedScene> GameMode::get_player_scene() const { | ||||
| gd::Ref<gd::PackedScene> GameMode::get_player_scene() const { | ||||
|     return this->player_scene; | ||||
| } | ||||
| 
 | ||||
| void GameMode::set_game_state(Ref<GameState> state) { | ||||
| void GameMode::set_game_state(gd::Ref<GameState> state) { | ||||
|     if(state.is_null() || !state.is_valid()) { | ||||
|         this->game_state.unref(); | ||||
|         return; | ||||
|  | @ -31,7 +31,7 @@ void GameMode::set_game_state(Ref<GameState> state) { | |||
|     this->game_state = state; | ||||
| } | ||||
| 
 | ||||
| Ref<GameState> GameMode::get_game_state() { | ||||
| gd::Ref<GameState> GameMode::get_game_state() { | ||||
|     return this->game_state; | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -1,26 +1,28 @@ | |||
| #ifndef GAME_MODE_H | ||||
| #define GAME_MODE_H | ||||
| #ifndef GAME_MODE_HPP | ||||
| #define GAME_MODE_HPP | ||||
| 
 | ||||
| #include <godot_cpp/classes/packed_scene.hpp> | ||||
| #include <godot_cpp/classes/resource.hpp> | ||||
| #include "game_state.hpp" | ||||
| 
 | ||||
| namespace godot { | ||||
| class GameMode : public Resource { | ||||
|     GDCLASS(GameMode, Resource); | ||||
| namespace gd = godot; | ||||
| 
 | ||||
| namespace utils { | ||||
| class GameMode : public gd::Resource { | ||||
|     GDCLASS(GameMode, gd::Resource); | ||||
|     static void _bind_methods(); | ||||
| public: | ||||
|     virtual void _begin(); | ||||
|     virtual void _end(); | ||||
| 
 | ||||
|     void set_player_scene(Ref<PackedScene> scene); | ||||
|     Ref<PackedScene> get_player_scene() const; | ||||
|     void set_game_state(Ref<GameState> state); | ||||
|     Ref<GameState> get_game_state(); | ||||
|     void set_player_scene(gd::Ref<gd::PackedScene> scene); | ||||
|     gd::Ref<gd::PackedScene> get_player_scene() const; | ||||
|     void set_game_state(gd::Ref<GameState> state); | ||||
|     gd::Ref<GameState> get_game_state(); | ||||
| private: | ||||
|     Ref<PackedScene> player_scene{}; | ||||
|     Ref<GameState> game_state{}; | ||||
|     gd::Ref<gd::PackedScene> player_scene{}; | ||||
|     gd::Ref<GameState> game_state{}; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| #endif // !GAME_MODE_H
 | ||||
| #endif // !GAME_MODE_HPP
 | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include "level.hpp" | ||||
| #include "player.hpp" | ||||
| #include "player_input.hpp" | ||||
| #include "player.hpp" | ||||
| #include "spawn_point.hpp" | ||||
| #include <cstdint> | ||||
| #include <godot_cpp/classes/global_constants.hpp> | ||||
|  | @ -15,14 +16,14 @@ | |||
| #include <godot_cpp/variant/string_name.hpp> | ||||
| #include <godot_cpp/variant/utility_functions.hpp> | ||||
| 
 | ||||
| namespace godot { | ||||
| namespace utils { | ||||
| void GameRoot3D::_bind_methods() { | ||||
| #define CLASSNAME GameRoot3D | ||||
|     GDFUNCTION(reset_game_mode); | ||||
|     GDPROPERTY_HINTED(first_boot_level, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); | ||||
|     GDSIGNAL("player_connected", PropertyInfo(Variant::OBJECT, "player_input", PROPERTY_HINT_NODE_TYPE, "PlayerInput")); | ||||
|     GDSIGNAL("player_disconnected", PropertyInfo(Variant::OBJECT, "player_input", PROPERTY_HINT_NODE_TYPE, "PlayerInput")); | ||||
|     GDSIGNAL("player_spawned",  PropertyInfo(Variant::OBJECT, "player_info", PROPERTY_HINT_NODE_TYPE, "Node")); | ||||
|     GDPROPERTY_HINTED(first_boot_level, gd::Variant::OBJECT, gd::PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); | ||||
|     GDSIGNAL("player_connected", gd::PropertyInfo(gd::Variant::OBJECT, "player_input", gd::PROPERTY_HINT_NODE_TYPE, "PlayerInput")); | ||||
|     GDSIGNAL("player_disconnected", gd::PropertyInfo(gd::Variant::OBJECT, "player_input", gd::PROPERTY_HINT_NODE_TYPE, "PlayerInput")); | ||||
|     GDSIGNAL("player_spawned", gd::PropertyInfo(gd::Variant::OBJECT, "player_info", gd::PROPERTY_HINT_NODE_TYPE, "Node")); | ||||
| } | ||||
| 
 | ||||
| GameRoot3D *GameRoot3D::get_singleton() { | ||||
|  | @ -53,16 +54,16 @@ void GameRoot3D::player_input_connected() { | |||
|     PlayerInput *input = memnew(PlayerInput); | ||||
|     this->add_child(input); | ||||
|     this->players.insert(this->next_player_id++, {input, nullptr}); | ||||
|     this->emit_signal(StringName("player_connected"), input); | ||||
|     this->emit_signal(gd::StringName("player_connected"), input); | ||||
| } | ||||
| 
 | ||||
| void GameRoot3D::remove_player(uint32_t player_id) { | ||||
|     if(!this->players.has(player_id)) | ||||
|         return; | ||||
|     // convert player object to node
 | ||||
|     Node *node = this->players.get(player_id).second->to_node(); | ||||
|     gd::Node *node = this->players.get(player_id).second->to_node(); | ||||
|     if(node == nullptr) { | ||||
|         UtilityFunctions::push_error("IPlayer::to_node failed for player with id '", player_id, "'"); | ||||
|         gd::UtilityFunctions::push_error("IPlayer::to_node failed for player with id '", player_id, "'"); | ||||
|         return; | ||||
|     } | ||||
|     node->queue_free(); | ||||
|  | @ -71,7 +72,7 @@ void GameRoot3D::remove_player(uint32_t player_id) { | |||
| 
 | ||||
| void GameRoot3D::remove_all_players() { | ||||
|     // free all player instances in use
 | ||||
|     for(KeyValue<uint32_t, Pair<PlayerInput*, IPlayer*>> &pair : this->players) { | ||||
|     for(gd::KeyValue<uint32_t, gd::Pair<PlayerInput*, IPlayer*>> &pair : this->players) { | ||||
|         // skip unused player slots
 | ||||
|         if(pair.value.second == nullptr) | ||||
|             continue; | ||||
|  | @ -84,7 +85,7 @@ bool GameRoot3D::initialize_player(IPlayer *player, uint32_t id) { | |||
|     if(!this->players.has(id)) | ||||
|         return false; | ||||
|     // register the player
 | ||||
|     Pair<PlayerInput*, IPlayer*> &found{this->players.get(id)}; | ||||
|     gd::Pair<PlayerInput*, IPlayer*> &found{this->players.get(id)}; | ||||
|     found.second = player; | ||||
|     // set player id
 | ||||
|     player->player_id = id; | ||||
|  | @ -95,20 +96,20 @@ bool GameRoot3D::initialize_player(IPlayer *player, uint32_t id) { | |||
| } | ||||
| 
 | ||||
| void GameRoot3D::reset_game_mode() { | ||||
|     this->set_game_mode(Ref<GameMode>()); | ||||
|     this->set_game_mode(gd::Ref<GameMode>()); | ||||
| } | ||||
| 
 | ||||
| Level3D *GameRoot3D::load_level(Ref<PackedScene> level) { | ||||
|     return this->load_level_at(level, Transform3D()); | ||||
| Level3D *GameRoot3D::load_level(gd::Ref<gd::PackedScene> level) { | ||||
|     return this->load_level_at(level, gd::Transform3D()); | ||||
| } | ||||
| 
 | ||||
| Level3D *GameRoot3D::load_level_at(Ref<PackedScene> level, Transform3D at) { | ||||
| Level3D *GameRoot3D::load_level_at(gd::Ref<gd::PackedScene> level, gd::Transform3D at) { | ||||
|     if(!GameRoot3D::is_valid_level(level)) { | ||||
|         return nullptr; | ||||
|     } | ||||
|     Level3D *instance = Object::cast_to<Level3D>(level->instantiate()); | ||||
|     if(instance == nullptr) { | ||||
|         UtilityFunctions::push_error("Unexpected failure to instantiate level scene '", level->get_path(), "'."); | ||||
|         gd::UtilityFunctions::push_error("Unexpected failure to instantiate level scene '", level->get_path(), "'."); | ||||
|         return nullptr; | ||||
|     } | ||||
|     this->levels.insert(level->get_path(), instance); | ||||
|  | @ -122,7 +123,7 @@ Level3D *GameRoot3D::load_level_at(Ref<PackedScene> level, Transform3D at) { | |||
|     this->add_child(instance); | ||||
|     instance->set_global_transform(at); | ||||
|     if(switch_game_mode && this->game_mode.is_valid()) { | ||||
|         for(KeyValue<uint32_t, Pair<PlayerInput *, IPlayer *>> const &kvp : this->players) { | ||||
|         for(gd::KeyValue<uint32_t, gd::Pair<PlayerInput *, IPlayer *>> const &kvp : this->players) { | ||||
|             this->place_player_at_spawnpoint(kvp.value.second); | ||||
|         } | ||||
|     } | ||||
|  | @ -130,21 +131,21 @@ Level3D *GameRoot3D::load_level_at(Ref<PackedScene> level, Transform3D at) { | |||
| } | ||||
| 
 | ||||
| void GameRoot3D::unload_all_levels() { | ||||
|     HashMap<StringName, Level3D*> levels = this->get_levels(); | ||||
|     for(KeyValue<StringName, Level3D*> &kvp : levels) | ||||
|     gd::HashMap<gd::StringName, Level3D*> levels = this->get_levels(); | ||||
|     for(gd::KeyValue<gd::StringName, Level3D*> &kvp : levels) | ||||
|         kvp.value->call_deferred("queue_free"); | ||||
|     this->get_levels().clear(); | ||||
|     this->reset_game_mode(); | ||||
| } | ||||
| 
 | ||||
| void GameRoot3D::replace_levels(Ref<PackedScene> scene) { | ||||
| void GameRoot3D::replace_levels(gd::Ref<gd::PackedScene> scene) { | ||||
|     this->unload_all_levels(); | ||||
|     this->load_level(scene); | ||||
| } | ||||
| 
 | ||||
| void GameRoot3D::register_spawn_point(SpawnPoint3D *spawn_point) { | ||||
|     if(this->spawn_points.has(spawn_point)) { | ||||
|         UtilityFunctions::push_error("Duplicate attempt to register spawnpoint '", spawn_point->get_path(), "'"); | ||||
|         gd::UtilityFunctions::push_error("Duplicate attempt to register spawnpoint '", spawn_point->get_path(), "'"); | ||||
|         return; | ||||
|     } | ||||
|     if(!this->spawn_points.has(spawn_point)) | ||||
|  | @ -153,7 +154,7 @@ void GameRoot3D::register_spawn_point(SpawnPoint3D *spawn_point) { | |||
| 
 | ||||
| void GameRoot3D::unregister_spawn_point(SpawnPoint3D *spawn_point) { | ||||
|     if(!this->spawn_points.has(spawn_point)) { | ||||
|         UtilityFunctions::push_error("Attempt to unregister spawnpoint '", spawn_point->get_path(), "', which is not registered."); | ||||
|         gd::UtilityFunctions::push_error("Attempt to unregister spawnpoint '", spawn_point->get_path(), "', which is not registered."); | ||||
|         return; | ||||
|     } | ||||
|     this->spawn_points.erase(spawn_point); | ||||
|  | @ -166,12 +167,12 @@ void GameRoot3D::place_player_at_spawnpoint(IPlayer *player) { | |||
| } | ||||
| 
 | ||||
| void GameRoot3D::player_despawned(uint32_t id) { | ||||
|     Pair<PlayerInput*, IPlayer*> &pair = this->players.get(id); | ||||
|     gd::Pair<PlayerInput*, IPlayer*> &pair = this->players.get(id); | ||||
|     pair.second = nullptr; | ||||
|     pair.first->clear_listeners(); | ||||
| } | ||||
| 
 | ||||
| void GameRoot3D::set_game_mode(Ref<GameMode> prototype) { | ||||
| void GameRoot3D::set_game_mode(gd::Ref<GameMode> prototype) { | ||||
|     this->remove_all_players(); | ||||
|     // allow "unsetting" the gamemode by passing an invalid gamemode
 | ||||
|     // shorthand for this behaviour is reset_game_mode
 | ||||
|  | @ -197,33 +198,33 @@ void GameRoot3D::set_game_mode(Ref<GameMode> prototype) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| Ref<GameMode> GameRoot3D::get_game_mode() const { | ||||
| gd::Ref<GameMode> GameRoot3D::get_game_mode() const { | ||||
|     return this->game_mode; | ||||
| } | ||||
| 
 | ||||
| Ref<GameState> GameRoot3D::get_game_state() const { | ||||
| gd::Ref<GameState> GameRoot3D::get_game_state() const { | ||||
|     return this->game_mode->get_game_state(); | ||||
| } | ||||
| 
 | ||||
| void GameRoot3D::set_first_boot_level(Ref<PackedScene> level) { | ||||
| void GameRoot3D::set_first_boot_level(gd::Ref<gd::PackedScene> level) { | ||||
|     if(level.is_null() || !level.is_valid()) { | ||||
|         this->first_boot_level.unref(); | ||||
|         return; | ||||
|     } | ||||
|     StringName const root_type = level->get_state()->get_node_type(0); | ||||
|     if(!ClassDB::is_parent_class(root_type, "Level3D")) { | ||||
|         UtilityFunctions::push_error("First boot level cannot be of type '", root_type, "'. First boot level has to inherit from Level3D"); | ||||
|     gd::StringName const root_type = level->get_state()->get_node_type(0); | ||||
|     if(!gd::ClassDB::is_parent_class(root_type, "Level3D")) { | ||||
|         gd::UtilityFunctions::push_error("First boot level cannot be of type '", root_type, "'. First boot level has to inherit from Level3D"); | ||||
|         this->first_boot_level.unref(); | ||||
|         return; | ||||
|     } | ||||
|     this->first_boot_level = level; | ||||
| } | ||||
| 
 | ||||
| Ref<PackedScene> GameRoot3D::get_first_boot_level() const { | ||||
| gd::Ref<gd::PackedScene> GameRoot3D::get_first_boot_level() const { | ||||
|     return this->first_boot_level; | ||||
| } | ||||
| 
 | ||||
| HashMap<StringName, Level3D *> &GameRoot3D::get_levels() { | ||||
| gd::HashMap<gd::StringName, Level3D *> &GameRoot3D::get_levels() { | ||||
|     return this->levels; | ||||
| } | ||||
| 
 | ||||
|  | @ -231,9 +232,9 @@ IPlayer *GameRoot3D::get_player(uint32_t id) { | |||
|     return this->players[id].second; | ||||
| } | ||||
| 
 | ||||
| Vector<IPlayer*> GameRoot3D::get_players() { | ||||
|     Vector<IPlayer*> players{}; | ||||
|     for(KeyValue<uint32_t, Pair<PlayerInput*, IPlayer*>> pair : this->players) { | ||||
| gd::Vector<IPlayer*> GameRoot3D::get_players() { | ||||
|     gd::Vector<IPlayer*> players{}; | ||||
|     for(gd::KeyValue<uint32_t, gd::Pair<PlayerInput*, IPlayer*>> pair : this->players) { | ||||
|         players.push_back(pair.value.second); | ||||
|     } | ||||
|     return players; | ||||
|  | @ -242,7 +243,7 @@ Vector<IPlayer*> GameRoot3D::get_players() { | |||
| void GameRoot3D::grab_singleton() { | ||||
|     if(GameRoot3D::has_singleton()) { | ||||
|         this->set_process_mode(PROCESS_MODE_DISABLED); | ||||
|         UtilityFunctions::push_error("More than one GameRoot instance active"); | ||||
|         gd::UtilityFunctions::push_error("More than one GameRoot instance active"); | ||||
|     } else { | ||||
|         GameRoot3D::singleton_instance = this; | ||||
|     } | ||||
|  | @ -252,12 +253,12 @@ void GameRoot3D::release_singleton() { | |||
|     if(GameRoot3D::singleton_instance == this) { | ||||
|         GameRoot3D::singleton_instance = nullptr; | ||||
|     } else { | ||||
|         UtilityFunctions::push_error("GameRoot instance attempted to release singleton while it is not the singleton instance"); | ||||
|         gd::UtilityFunctions::push_error("GameRoot instance attempted to release singleton while it is not the singleton instance"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| uint32_t GameRoot3D::find_empty_player_slot() const { | ||||
|     for(KeyValue<uint32_t, Pair<PlayerInput*, IPlayer*>> const &kvp : this->players) { | ||||
|     for(gd::KeyValue<uint32_t, gd::Pair<PlayerInput*, IPlayer*>> const &kvp : this->players) { | ||||
|         if(kvp.value.second == nullptr) { | ||||
|             return kvp.key; | ||||
|         } | ||||
|  | @ -267,17 +268,17 @@ uint32_t GameRoot3D::find_empty_player_slot() const { | |||
| 
 | ||||
| IPlayer *GameRoot3D::spawn_player(uint32_t id) { | ||||
|     if(id == 0) { | ||||
|         UtilityFunctions::push_error("Failed to find any valid player slot when spawning player"); | ||||
|         gd::UtilityFunctions::push_error("Failed to find any valid player slot when spawning player"); | ||||
|         return nullptr; | ||||
|     } | ||||
|     Node *player_node = this->game_mode->get_player_scene()->instantiate(); | ||||
|     if(player_node == nullptr) { | ||||
|         UtilityFunctions::push_error("Failed to instantiate player scene '", this->game_mode->get_player_scene()->get_path(), "'"); | ||||
|         gd::UtilityFunctions::push_error("Failed to instantiate player scene '", this->game_mode->get_player_scene()->get_path(), "'"); | ||||
|         return nullptr; | ||||
|     } | ||||
|     IPlayer *player = dynamic_cast<IPlayer*>(player_node); | ||||
|     if(player == nullptr) { | ||||
|         UtilityFunctions::push_error("Player scene does not implement required IPlayer interface"); | ||||
|         gd::UtilityFunctions::push_error("Player scene does not implement required IPlayer interface"); | ||||
|         player_node->queue_free(); | ||||
|         return nullptr; | ||||
|     } | ||||
|  | @ -285,18 +286,18 @@ IPlayer *GameRoot3D::spawn_player(uint32_t id) { | |||
|     return player; | ||||
| } | ||||
| 
 | ||||
| void GameRoot3D::level_unloaded(StringName scene_path) { | ||||
| void GameRoot3D::level_unloaded(gd::StringName scene_path) { | ||||
|     this->levels.erase(scene_path); | ||||
| } | ||||
| 
 | ||||
| bool GameRoot3D::is_valid_level(Ref<PackedScene> &level) { | ||||
| bool GameRoot3D::is_valid_level(gd::Ref<gd::PackedScene> &level) { | ||||
|     if(level.is_null() || !level.is_valid() || !level->can_instantiate()) { | ||||
|         UtilityFunctions::push_error("Can't load level from invalid packed scene"); | ||||
|         gd::UtilityFunctions::push_error("Can't load level from invalid packed scene"); | ||||
|         return false; | ||||
|     } | ||||
|     StringName const root_type = level->get_state()->get_node_type(0); | ||||
|     if(!ClassDB::is_parent_class(root_type, "Level3D")) { | ||||
|         UtilityFunctions::push_error("Can't load level with root type '", root_type, "'. Root node has to be of type Level3D"); | ||||
|     gd::StringName const root_type = level->get_state()->get_node_type(0); | ||||
|     if(!gd::ClassDB::is_parent_class(root_type, "Level3D")) { | ||||
|         gd::UtilityFunctions::push_error("Can't load level with root type '", root_type, "'. Root node has to be of type Level3D"); | ||||
|         return false; | ||||
|     } | ||||
|     return true; | ||||
|  |  | |||
|  | @ -2,23 +2,25 @@ | |||
| #define GAME_ROOT_HPP | ||||
| 
 | ||||
| #include "game_mode.hpp" | ||||
| #include "godot_cpp/classes/random_number_generator.hpp" | ||||
| #include "level.hpp" | ||||
| #include <godot_cpp/classes/node.hpp> | ||||
| #include <godot_cpp/classes/packed_scene.hpp> | ||||
| #include <godot_cpp/classes/random_number_generator.hpp> | ||||
| #include <godot_cpp/templates/hash_map.hpp> | ||||
| #include <godot_cpp/templates/hash_set.hpp> | ||||
| #include <godot_cpp/templates/pair.hpp> | ||||
| #include <godot_cpp/templates/pair.hpp> | ||||
| #include <godot_cpp/templates/vector.hpp> | ||||
| 
 | ||||
| namespace godot { | ||||
| namespace gd = godot; | ||||
| 
 | ||||
| namespace utils { | ||||
| class PlayerInput; | ||||
| class IPlayer; | ||||
| class SpawnPoint3D; | ||||
| 
 | ||||
| class GameRoot3D : public Node { | ||||
|     GDCLASS(GameRoot3D, Node); | ||||
| class GameRoot3D : public gd::Node { | ||||
|     GDCLASS(GameRoot3D, gd::Node); | ||||
|     static void _bind_methods(); | ||||
| public: | ||||
|     // get the current active singleton instance of GameRoot
 | ||||
|  | @ -46,12 +48,12 @@ public: | |||
|     void reset_game_mode(); | ||||
| 
 | ||||
|     // shorthand for load_level(level, Transform3D())
 | ||||
|     Level3D *load_level(Ref<PackedScene> level); | ||||
|     Level3D *load_level(gd::Ref<gd::PackedScene> level); | ||||
|     // load a level, only works if 'level' is a valid scene where the root Node can cast to 'Level3D'
 | ||||
|     // sets the level's root node's global transform
 | ||||
|     Level3D *load_level_at(Ref<PackedScene> level, Transform3D at); | ||||
|     Level3D *load_level_at(gd::Ref<gd::PackedScene> level, gd::Transform3D at); | ||||
|     void unload_all_levels(); | ||||
|     void replace_levels(Ref<PackedScene> level); | ||||
|     void replace_levels(gd::Ref<gd::PackedScene> level); | ||||
| 
 | ||||
|     // register a spawnpoint for use when spawning players
 | ||||
|     void register_spawn_point(SpawnPoint3D *spawn_point); | ||||
|  | @ -63,14 +65,14 @@ public: | |||
|     // ----- getter / setters -----
 | ||||
|     // override the current gamemode
 | ||||
|     // force-respawns all players
 | ||||
|     void set_game_mode(Ref<GameMode> prototype); | ||||
|     Ref<GameMode> get_game_mode() const; | ||||
|     Ref<GameState> get_game_state() const; | ||||
|     void set_first_boot_level(Ref<PackedScene> level); | ||||
|     Ref<PackedScene> get_first_boot_level() const; | ||||
|     HashMap<StringName, Level3D *> &get_levels(); | ||||
|     void set_game_mode(gd::Ref<GameMode> prototype); | ||||
|     gd::Ref<GameMode> get_game_mode() const; | ||||
|     gd::Ref<GameState> get_game_state() const; | ||||
|     void set_first_boot_level(gd::Ref<gd::PackedScene> level); | ||||
|     gd::Ref<gd::PackedScene> get_first_boot_level() const; | ||||
|     gd::HashMap<gd::StringName, Level3D *> &get_levels(); | ||||
|     IPlayer *get_player(uint32_t id); | ||||
|     Vector<IPlayer*> get_players(); | ||||
|     gd::Vector<IPlayer*> get_players(); | ||||
| protected: | ||||
|     // attempt to make 'this' the current singleton instance
 | ||||
|     void grab_singleton(); | ||||
|  | @ -79,20 +81,20 @@ protected: | |||
|     void release_singleton(); | ||||
|     uint32_t find_empty_player_slot() const; | ||||
|     IPlayer *spawn_player(uint32_t id); | ||||
|     void level_unloaded(StringName scene_path); | ||||
|     static bool is_valid_level(Ref<PackedScene> &level); | ||||
|     void level_unloaded(gd::StringName scene_path); | ||||
|     static bool is_valid_level(gd::Ref<gd::PackedScene> &level); | ||||
| protected: | ||||
|     static GameRoot3D *singleton_instance; | ||||
| 
 | ||||
|     uint32_t next_player_id{1}; // 0 is the "invalid" player id
 | ||||
|     HashMap<uint32_t, Pair<PlayerInput*, IPlayer*>> players{}; | ||||
|     Ref<GameMode> game_mode{}; | ||||
|     gd::HashMap<uint32_t, gd::Pair<PlayerInput*, IPlayer*>> players{}; | ||||
|     gd::Ref<GameMode> game_mode{}; | ||||
| private: | ||||
|     RandomNumberGenerator rng{}; | ||||
|     HashMap<StringName, Level3D*> levels{}; | ||||
|     Vector<SpawnPoint3D*> spawn_points{}; | ||||
|     gd::RandomNumberGenerator rng{}; | ||||
|     gd::HashMap<gd::StringName, Level3D*> levels{}; | ||||
|     gd::Vector<SpawnPoint3D*> spawn_points{}; | ||||
| 
 | ||||
|     Ref<PackedScene> first_boot_level{}; | ||||
|     gd::Ref<gd::PackedScene> first_boot_level{}; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #include "game_state.hpp" | ||||
| 
 | ||||
| namespace godot { | ||||
| using namespace godot; | ||||
| 
 | ||||
| namespace utils { | ||||
| void GameState::_bind_methods() { | ||||
| #define CLASSNAME GameState | ||||
| } | ||||
|  |  | |||
|  | @ -1,10 +1,11 @@ | |||
| #ifndef GAME_STATE_HPP | ||||
| #define GAME_STATE_HPP | ||||
| 
 | ||||
| #include "godot_cpp/classes/resource.hpp" | ||||
| namespace godot { | ||||
| class GameState : public Resource { | ||||
|     GDCLASS(GameState, Resource); | ||||
| #include <godot_cpp/classes/resource.hpp> | ||||
| 
 | ||||
| namespace utils { | ||||
| class GameState : public godot::Resource { | ||||
|     GDCLASS(GameState, godot::Resource); | ||||
|     static void _bind_methods(); | ||||
| public: | ||||
| }; | ||||
|  |  | |||
|  | @ -4,37 +4,33 @@ | |||
| #include "godot_cpp/classes/engine.hpp" | ||||
| #include "godot_cpp/core/class_db.hpp" | ||||
| 
 | ||||
| 
 | ||||
| #define MACRO_STRING_INNER(_Arg) #_Arg | ||||
| #define MACRO_STRING(_Arg) MACRO_STRING_INNER(_Arg) | ||||
| 
 | ||||
| #define GDPROPERTY(_PropName, _PropType)                                                                               \ | ||||
|     ClassDB::bind_method(D_METHOD("get_" #_PropName), &CLASSNAME::get_##_PropName);                                    \ | ||||
|     ClassDB::bind_method(D_METHOD("set_" #_PropName, "value"), &CLASSNAME::set_##_PropName);                           \ | ||||
|     ClassDB::add_property(MACRO_STRING(CLASSNAME), PropertyInfo(_PropType, #_PropName), "set_" #_PropName,             \ | ||||
|                           "get_" #_PropName) | ||||
| #define GDPROPERTY(_PropName, _PropType) \ | ||||
|     godot::ClassDB::bind_method(godot::D_METHOD("get_" #_PropName), &CLASSNAME::get_##_PropName); \ | ||||
|     godot::ClassDB::bind_method(godot::D_METHOD("set_" #_PropName, "value"), &CLASSNAME::set_##_PropName); \ | ||||
|     godot::ClassDB::add_property(MACRO_STRING(CLASSNAME), godot::PropertyInfo(_PropType, #_PropName), "set_" #_PropName, "get_" #_PropName) | ||||
| 
 | ||||
| #define GDPROPERTY_HINTED(_PropName, _PropType, ...)                                                                   \ | ||||
|     ClassDB::bind_method(D_METHOD("get_" #_PropName), &CLASSNAME::get_##_PropName);                                    \ | ||||
|     ClassDB::bind_method(D_METHOD("set_" #_PropName, "value"), &CLASSNAME::set_##_PropName);                           \ | ||||
|     ClassDB::add_property(MACRO_STRING(CLASSNAME), PropertyInfo(_PropType, #_PropName, __VA_ARGS__),                   \ | ||||
|                           "set_" #_PropName, "get_" #_PropName) | ||||
| #define GDPROPERTY_HINTED(_PropName, _PropType, ...) \ | ||||
|     godot::ClassDB::bind_method(godot::D_METHOD("get_" #_PropName), &CLASSNAME::get_##_PropName); \ | ||||
|     godot::ClassDB::bind_method(godot::D_METHOD("set_" #_PropName, "value"), &CLASSNAME::set_##_PropName); \ | ||||
|     godot::ClassDB::add_property(MACRO_STRING(CLASSNAME), godot::PropertyInfo(_PropType, #_PropName, __VA_ARGS__), "set_" #_PropName, "get_" #_PropName) | ||||
| 
 | ||||
| #define GDFUNCTION(_FnName) ClassDB::bind_method(D_METHOD(#_FnName), &CLASSNAME::_FnName) | ||||
| #define GDFUNCTION(_FnName) godot::ClassDB::bind_method(godot::D_METHOD(#_FnName), &CLASSNAME::_FnName) | ||||
| 
 | ||||
| #define GDFUNCTION_ARGS(_FnName, ...) ClassDB::bind_method(D_METHOD(#_FnName, __VA_ARGS__), &CLASSNAME::_FnName) | ||||
| #define GDFUNCTION_ARGS(_FnName, ...) godot::ClassDB::bind_method(godot::D_METHOD(#_FnName, __VA_ARGS__), &CLASSNAME::_FnName) | ||||
| 
 | ||||
| #define GDFUNCTION_STATIC(_FnName)                                                                                     \ | ||||
|     ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), D_METHOD(#_FnName), &CLASSNAME::_FnName) | ||||
| #define GDFUNCTION_STATIC(_FnName) godot::ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), godot::D_METHOD(#_FnName), &CLASSNAME::_FnName) | ||||
| 
 | ||||
| #define GDFUNCTION_STATIC_ARGS(_FnName, ...)                                                                           \ | ||||
|     ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), D_METHOD(#_FnName, __VA_ARGS__), &CLASSNAME::_FnName) | ||||
| #define GDFUNCTION_STATIC_ARGS(_FnName, ...) godot::ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), godot::D_METHOD(#_FnName, __VA_ARGS__), &CLASSNAME::_FnName) | ||||
| 
 | ||||
| #define GDSIGNAL(...)\ | ||||
|     ClassDB::add_signal(MACRO_STRING(CLASSNAME), MethodInfo(__VA_ARGS__)) | ||||
| #define GDSIGNAL(...) godot::ClassDB::add_signal(MACRO_STRING(CLASSNAME), godot::MethodInfo(__VA_ARGS__)) | ||||
| 
 | ||||
| #define GDRESOURCETYPE(_Class) vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, #_Class) | ||||
| #define GDRESOURCETYPE(_Class) godot::vformat("%s/%s:%s", godot::Variant::OBJECT, godot::PROPERTY_HINT_RESOURCE_TYPE, #_Class) | ||||
| 
 | ||||
| #define GDEDITORONLY() if(!Engine::get_singleton()->is_editor_hint()) return; | ||||
| #define GDGAMEONLY() if(Engine::get_singleton()->is_editor_hint()) return; | ||||
| #define GDEDITORONLY() if(!godot::Engine::get_singleton()->is_editor_hint()) return; | ||||
| #define GDGAMEONLY() if(godot::Engine::get_singleton()->is_editor_hint()) return; | ||||
| 
 | ||||
| #endif // !UC_GODOT_MACROS_H
 | ||||
|  |  | |||
							
								
								
									
										24
									
								
								level.cpp
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								level.cpp
									
									
									
									
									
								
							|  | @ -1,33 +1,17 @@ | |||
| #include "level.hpp" | ||||
| #include "utils/godot_macros.h" | ||||
| 
 | ||||
| namespace godot { | ||||
| namespace utils { | ||||
| void Level3D::_bind_methods() { | ||||
| #define CLASSNAME Level3D | ||||
|     GDPROPERTY_HINTED(game_mode_prototype, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "GameMode"); | ||||
|     GDPROPERTY_HINTED(game_mode_prototype, gd::Variant::OBJECT, gd::PROPERTY_HINT_RESOURCE_TYPE, "GameMode"); | ||||
| } | ||||
| 
 | ||||
| void Level3D::set_game_mode_prototype(Ref<GameMode> prototype) { | ||||
| void Level3D::set_game_mode_prototype(gd::Ref<GameMode> prototype) { | ||||
|     this->game_mode_prototype = prototype; | ||||
| } | ||||
| 
 | ||||
| Ref<GameMode> Level3D::get_game_mode_prototype() const { | ||||
| gd::Ref<GameMode> Level3D::get_game_mode_prototype() const { | ||||
|     return this->game_mode_prototype; | ||||
| } | ||||
| 
 | ||||
| #undef CLASSNAME // Level3D
 | ||||
| 
 | ||||
| void Level2D::_bind_methods() { | ||||
| #define CLASSNAME Level3D | ||||
|     GDPROPERTY_HINTED(game_mode_prototype, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "GameMode"); | ||||
| } | ||||
| 
 | ||||
| void Level2D::set_game_mode_prototype(Ref<GameMode> prototype) { | ||||
|     this->game_mode_prototype = prototype; | ||||
| } | ||||
| 
 | ||||
| Ref<GameMode> Level2D::get_game_mode_prototype() const { | ||||
|     return this->game_mode_prototype; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
							
								
								
									
										29
									
								
								level.hpp
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								level.hpp
									
									
									
									
									
								
							|  | @ -1,32 +1,21 @@ | |||
| #ifndef LEVEL_HPP | ||||
| #define LEVEL_HPP | ||||
| 
 | ||||
| #include <godot_cpp/classes/node2d.hpp> | ||||
| #include <godot_cpp/classes/node3d.hpp> | ||||
| #include "game_mode.hpp" | ||||
| #include <godot_cpp/classes/node3d.hpp> | ||||
| 
 | ||||
| namespace godot { | ||||
| class Level3D : public Node3D { | ||||
|     GDCLASS(Level3D, Node3D); | ||||
| namespace gd = godot; | ||||
| 
 | ||||
| namespace utils { | ||||
| class Level3D : public gd::Node3D { | ||||
|     GDCLASS(Level3D, gd::Node3D); | ||||
|     static void _bind_methods(); | ||||
| public: | ||||
|     void set_game_mode_prototype(Ref<GameMode> prototype); | ||||
|     Ref<GameMode> get_game_mode_prototype() const; | ||||
|     void set_game_mode_prototype(gd::Ref<GameMode> prototype); | ||||
|     gd::Ref<GameMode> get_game_mode_prototype() const; | ||||
| private: | ||||
|     Ref<GameMode> game_mode_prototype{}; | ||||
|     gd::Ref<GameMode> game_mode_prototype{}; | ||||
| }; | ||||
| 
 | ||||
| class Level2D : public Node2D { | ||||
|     GDCLASS(Level2D, Node2D); | ||||
|     static void _bind_methods(); | ||||
| public: | ||||
|     void set_game_mode_prototype(Ref<GameMode> prototype); | ||||
|     Ref<GameMode> get_game_mode_prototype() const; | ||||
| private: | ||||
|     Ref<GameMode> game_mode_prototype{}; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif // !LEVEL_HPP
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| #include "player.hpp" | ||||
| 
 | ||||
| namespace godot { | ||||
| namespace utils { | ||||
| uint32_t IPlayer::get_player_id() { | ||||
|     return this->player_id.value_or(0); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										11
									
								
								player.hpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								player.hpp
									
									
									
									
									
								
							|  | @ -5,16 +5,19 @@ | |||
| #include <optional> | ||||
| #include <godot_cpp/variant/transform3d.hpp> | ||||
| 
 | ||||
| namespace godot { | ||||
| namespace godot { class Node; } | ||||
| 
 | ||||
| namespace gd = godot; | ||||
| 
 | ||||
| namespace utils { | ||||
| class PlayerInput; | ||||
| class Node; | ||||
| 
 | ||||
| class IPlayer { | ||||
| friend class GameRoot3D; | ||||
| public: | ||||
|     virtual void setup_player_input(PlayerInput *input) = 0; | ||||
|     virtual Node *to_node() = 0; | ||||
|     virtual void spawn_at_position(Transform3D const &at) = 0; | ||||
|     virtual gd::Node *to_node() = 0; | ||||
|     virtual void spawn_at_position(gd::Transform3D const &at) = 0; | ||||
| 
 | ||||
|     uint32_t get_player_id(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,31 +1,32 @@ | |||
| #include "player_input.hpp" | ||||
| #include "godot_macros.h" | ||||
| #include "godot_cpp/classes/input.hpp" | ||||
| #include "godot_cpp/classes/input_event.hpp" | ||||
| #include "godot_cpp/classes/input_event_mouse_motion.hpp" | ||||
| #include "godot_cpp/variant/callable.hpp" | ||||
| #include <algorithm> | ||||
| #include <godot_cpp/classes/input.hpp> | ||||
| #include <godot_cpp/classes/input_event.hpp> | ||||
| #include <godot_cpp/classes/input_event_mouse_motion.hpp> | ||||
| #include <godot_cpp/variant/callable.hpp> | ||||
| #include <optional> | ||||
| 
 | ||||
| namespace godot { | ||||
| void PlayerInput::_bind_methods() {} | ||||
| namespace utils { | ||||
| void PlayerInput::_bind_methods() { | ||||
| #define CLASSNAME PlayerInput | ||||
| } | ||||
| 
 | ||||
| Vector2 PlayerInput::lastMouseMotion{0.f, 0.f}; | ||||
| gd::Vector2 PlayerInput::lastMouseMotion{0.f, 0.f}; | ||||
| bool PlayerInput::primaryExists{false}; | ||||
| 
 | ||||
| PlayerInput::Listener::Listener(String positive, String negative, Callable callable) | ||||
| PlayerInput::Listener::Listener(gd::String positive, gd::String negative, gd::Callable callable) | ||||
| : actionNegative{negative} | ||||
| , actionPositive{positive} | ||||
| , callable{callable} | ||||
| , isMouseEvent{positive.begins_with("_mouse_") || negative.begins_with("_mouse_")} {} | ||||
| 
 | ||||
| PlayerInput::Listener::Listener(String action, Callable callable) | ||||
| : PlayerInput::Listener::Listener(action, String(), callable) {} | ||||
| PlayerInput::Listener::Listener(gd::String action, gd::Callable callable) | ||||
| : PlayerInput::Listener::Listener(action, gd::String(), callable) {} | ||||
| 
 | ||||
| std::optional<float> PlayerInput::Listener::evaluate_action(String const &action) { | ||||
|     Input *input = Input::get_singleton(); | ||||
| std::optional<float> PlayerInput::Listener::evaluate_action(gd::String const &action) { | ||||
|     gd::Input *input = gd::Input::get_singleton(); | ||||
|     if(action.begins_with("_mouse_")) { | ||||
|         Vector2 vector = PlayerInput::get_last_mouse_motion(); | ||||
|         gd::Vector2 vector = PlayerInput::get_last_mouse_motion(); | ||||
|         if(action.ends_with("_up")) | ||||
|             return vector.y > 0.f ? vector.y : 0.f; | ||||
|         else if(action.ends_with("_down")) | ||||
|  | @ -42,14 +43,14 @@ std::optional<float> PlayerInput::Listener::evaluate_action(String const &action | |||
|     } | ||||
| } | ||||
| 
 | ||||
| bool PlayerInput::Listener::has_changed(Ref<InputEvent> const &event) { | ||||
| bool PlayerInput::Listener::has_changed(gd::Ref<gd::InputEvent> const &event) { | ||||
|     bool const mouse_changed{this->isMouseEvent && event->is_class("InputEventMouseMotion")}; | ||||
|     bool const negative_changed{!this->actionNegative.is_empty() && event->is_action(this->actionNegative)}; | ||||
|     bool const positive_changed{!this->actionPositive.is_empty() && event->is_action(this->actionPositive)}; | ||||
|     return mouse_changed || negative_changed || positive_changed; | ||||
| } | ||||
| 
 | ||||
| float PlayerInput::Listener::evaluate(Ref<InputEvent> const &event) { | ||||
| float PlayerInput::Listener::evaluate(gd::Ref<gd::InputEvent> const &event) { | ||||
|     std::optional<float> positive = PlayerInput::Listener::evaluate_action(this->actionPositive); | ||||
|     std::optional<float> negative = PlayerInput::Listener::evaluate_action(this->actionNegative); | ||||
|     if(!positive.has_value() || !negative.has_value()) | ||||
|  | @ -60,13 +61,13 @@ float PlayerInput::Listener::evaluate(Ref<InputEvent> const &event) { | |||
|     return (this->lastCached = newest); | ||||
| } | ||||
| 
 | ||||
| bool PlayerInput::Listener::operator==(godot::PlayerInput::Listener const& b) { | ||||
| bool PlayerInput::Listener::operator==(PlayerInput::Listener const& b) const { | ||||
|     return this->callable == b.callable | ||||
|         && this->actionNegative == b.actionNegative | ||||
|         && this->actionPositive == b.actionPositive; | ||||
| } | ||||
| 
 | ||||
| Vector2 PlayerInput::get_last_mouse_motion() { | ||||
| gd::Vector2 PlayerInput::get_last_mouse_motion() { | ||||
|     return PlayerInput::lastMouseMotion; | ||||
| } | ||||
| 
 | ||||
|  | @ -86,10 +87,10 @@ void PlayerInput::_exit_tree() { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void PlayerInput::_unhandled_input(Ref<InputEvent> const &event) { | ||||
| void PlayerInput::_unhandled_input(gd::Ref<gd::InputEvent> const &event) { | ||||
|     GDGAMEONLY(); | ||||
|     if(this->isPrimary && event->is_class("InputEventMouseMotion")) | ||||
|         PlayerInput::lastMouseMotion = Object::cast_to<InputEventMouseMotion>(*event)->get_relative(); | ||||
|         PlayerInput::lastMouseMotion = gd::Object::cast_to<gd::InputEventMouseMotion>(*event)->get_relative(); | ||||
|     for(Listener& listener: this->listeners) { | ||||
|         if(listener.has_changed(event)) { | ||||
|             listener.evaluate(event); | ||||
|  | @ -108,18 +109,16 @@ void PlayerInput::listen_to(Listener const& listener) { | |||
| 
 | ||||
| void PlayerInput::stop_listening(Node *node) { | ||||
|     for(size_t i = 0; i < this->listeners.size(); ++i) { | ||||
|         Listener& l = this->listeners.at(i); | ||||
|         Listener l = this->listeners.get(i); | ||||
|         if(l.callable.get_object() == node) { | ||||
|             this->listeners.erase(this->listeners.begin() + i); | ||||
|             this->listeners.remove_at(i); | ||||
|             i--; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void PlayerInput::stop_listening(Listener const& listener) { | ||||
|     std::vector<Listener>::iterator itr = std::find(this->listeners.begin(), this->listeners.end(), listener); | ||||
|     if(itr != this->listeners.end()) | ||||
|         this->listeners.erase(itr); | ||||
|     this->listeners.erase(listener); | ||||
| } | ||||
| 
 | ||||
| void PlayerInput::clear_listeners() { | ||||
|  |  | |||
|  | @ -1,55 +1,60 @@ | |||
| #ifndef PLAYER_INPUT_HPP | ||||
| #define PLAYER_INPUT_HPP | ||||
| 
 | ||||
| #include <vector> | ||||
| #include <optional> | ||||
| #include "godot_cpp/classes/input.hpp" | ||||
| #include "godot_cpp/classes/input_event.hpp" | ||||
| #include "godot_cpp/classes/node.hpp" | ||||
| #include "godot_cpp/variant/callable.hpp" | ||||
| #include <godot_cpp/classes/input.hpp> | ||||
| #include <godot_cpp/classes/input_event.hpp> | ||||
| #include <godot_cpp/classes/node.hpp> | ||||
| #include <godot_cpp/templates/vector.hpp> | ||||
| #include <godot_cpp/variant/callable.hpp> | ||||
| 
 | ||||
| namespace godot { | ||||
| class PlayerInput : public Node { | ||||
|     GDCLASS(PlayerInput, Node) | ||||
| namespace gd = godot; | ||||
| 
 | ||||
| namespace utils { | ||||
| /*! An event-driven input observer.
 | ||||
|  * | ||||
|  * Listen for events with `listen_to`, registering godot input action names to callbacks. It's possible to register an "axis" by registering a listener with a positive and negative action. | ||||
|  */ | ||||
| class PlayerInput : public gd::Node { | ||||
|     GDCLASS(PlayerInput, gd::Node) | ||||
|     static void _bind_methods(); | ||||
| public: | ||||
|     // a listener is a combination of a positive and negative action and a listener function.
 | ||||
|     // listener functions use godot's Object::call function.
 | ||||
|     // So they require a Node instance and a function name.
 | ||||
|     // The expected signature is void(Ref<InputEvent>, float)
 | ||||
|     // actions can also be "special" actions prefixed with _.
 | ||||
|     // special actions include _mouse_up, _mouse_down, _mouse_left and _mouse_right
 | ||||
|     // which rather than checking action_is_down,
 | ||||
|     // will use PlayerInput::get_last_mouse_motion() to poll the current state.
 | ||||
|     /*! A PlayerInput action listener.
 | ||||
|      * A listener is a combination of a positive and negative action and a callable. | ||||
|      * The expected callable signature is `void (godot::Ref<godot::InputEvent> event, float value)` | ||||
|      * actions can also be "special" actions prefixed with `_`. | ||||
|      * Special actions include `_mouse_up`, `_mouse_down`, `_mouse_left`, and `_mouse_right`. | ||||
|      */ | ||||
|     struct Listener { | ||||
|         friend class PlayerInput; | ||||
|     private: | ||||
|         // the two actions, evaluated as positive - negative
 | ||||
|         String actionNegative{""}; | ||||
|         String actionPositive{""}; | ||||
|         gd::String actionNegative{""}; | ||||
|         gd::String actionPositive{""}; | ||||
|         // the last cached action, if the newest result matches this, the event will be considered
 | ||||
|         // duplicate and ignored (not passed to listener)
 | ||||
|         float lastCached{0.f}; | ||||
|         Callable callable; | ||||
|         gd::Callable callable; | ||||
|         // if either actionNegative or actionPositive is a _mouse_ event this will be true
 | ||||
|         bool isMouseEvent{false}; | ||||
| 
 | ||||
|     public: | ||||
|         Listener(String positive, String negative, Callable callable); | ||||
|         Listener(String action, Callable callable); | ||||
|         Listener() = default; | ||||
|         Listener(gd::String positive, gd::String negative, gd::Callable callable); | ||||
|         Listener(gd::String action, gd::Callable callable); | ||||
|         // evaluate the current state of an action.
 | ||||
|         static std::optional<float> evaluate_action(String const &action); | ||||
|         static std::optional<float> evaluate_action(gd::String const &action); | ||||
|         // check if this event has any chance to result in a trigger, does not evaluate the event or
 | ||||
|         // poll current input state
 | ||||
|         bool has_changed(Ref<InputEvent> const &event); | ||||
|         bool has_changed(gd::Ref<gd::InputEvent> const &event); | ||||
|         // evaluate the event for changes to either actionPositive or actionNegative
 | ||||
|         float evaluate(Ref<InputEvent> const &event); | ||||
|         float evaluate(gd::Ref<gd::InputEvent> const &event); | ||||
| 
 | ||||
|         bool operator==(godot::PlayerInput::Listener const& b); | ||||
|         bool operator==(PlayerInput::Listener const& b) const; | ||||
|     }; | ||||
| private: | ||||
|     // the last mouse motion, updated by the primary instance
 | ||||
|     static Vector2 lastMouseMotion; | ||||
|     static gd::Vector2 lastMouseMotion; | ||||
|     // does a primary instance exist
 | ||||
|     static bool primaryExists; | ||||
|     // is this the primary instance
 | ||||
|  | @ -58,18 +63,18 @@ private: | |||
|     bool isPrimary{false}; | ||||
| 
 | ||||
|     // current listeners for this instance
 | ||||
|     std::vector<Listener> listeners{}; | ||||
|     gd::Vector<Listener> listeners{}; | ||||
| public: | ||||
|     static Vector2 get_last_mouse_motion(); | ||||
|     static gd::Vector2 get_last_mouse_motion(); | ||||
| 
 | ||||
|     virtual void _enter_tree() override; | ||||
|     virtual void _exit_tree() override; | ||||
|     virtual void _unhandled_input(Ref<InputEvent> const &event) override; | ||||
|     virtual void _unhandled_input(gd::Ref<gd::InputEvent> const &event) override; | ||||
|     virtual void _process(double deltaTime) override; | ||||
| 
 | ||||
|     void listen_to(Listener const& listener); | ||||
|     void listen_to(Listener const &listener); | ||||
|     void stop_listening(Node *node); | ||||
|     void stop_listening(Listener const& listener); | ||||
|     void stop_listening(Listener const &listener); | ||||
|     void clear_listeners(); | ||||
| }; | ||||
| } | ||||
|  |  | |||
|  | @ -1,17 +1,21 @@ | |||
| #include "register_types.hpp" | ||||
| #include <godot_cpp/core/class_db.hpp> | ||||
| #include "game_root.hpp" | ||||
| #include "game_mode.hpp" | ||||
| #include "game_root.hpp" | ||||
| #include "game_state.hpp" | ||||
| #include "level.hpp" | ||||
| #include "player_input.hpp" | ||||
| #include "spawn_point.hpp" | ||||
| #include <godot_cpp/core/class_db.hpp> | ||||
| 
 | ||||
| using namespace godot; | ||||
| namespace gd = godot; | ||||
| 
 | ||||
| namespace utils { | ||||
| void godot_cpp_utils_register_types() { | ||||
|     ClassDB::register_class<GameRoot3D>(); | ||||
|     ClassDB::register_class<GameMode>(); | ||||
|     ClassDB::register_class<GameState>(); | ||||
|     ClassDB::register_class<Level3D>(); | ||||
|     ClassDB::register_class<SpawnPoint3D>(); | ||||
|     ClassDB::register_class<PlayerInput>(); | ||||
|     gd::ClassDB::register_class<utils::GameMode>(); | ||||
|     gd::ClassDB::register_class<utils::GameRoot3D>(); | ||||
|     gd::ClassDB::register_class<utils::GameState>(); | ||||
|     gd::ClassDB::register_class<utils::Level3D>(); | ||||
|     gd::ClassDB::register_class<utils::PlayerInput>(); | ||||
|     gd::ClassDB::register_class<utils::SpawnPoint3D>(); | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #ifndef UTILS_REGISTER_TYPES_HPP | ||||
| #define UTILS_REGISTER_TYPES_HPP | ||||
| 
 | ||||
| namespace utils { | ||||
| void godot_cpp_utils_register_types(); | ||||
| } | ||||
| 
 | ||||
| #endif // !UTILS_REGISTER_TYPES_HPP
 | ||||
|  |  | |||
|  | @ -1,12 +1,12 @@ | |||
| #include "spawn_point.hpp" | ||||
| #include "utils/game_root.hpp" | ||||
| 
 | ||||
| namespace godot { | ||||
| namespace utils { | ||||
| void SpawnPoint3D::_bind_methods() { | ||||
| } | ||||
| 
 | ||||
| void SpawnPoint3D::_enter_tree() { | ||||
|     GameRoot3D *root = Object::cast_to<GameRoot3D>(GameRoot3D::get_singleton()); | ||||
|     GameRoot3D *root = gd::Object::cast_to<GameRoot3D>(GameRoot3D::get_singleton()); | ||||
|     if(root == nullptr) { | ||||
|         return; | ||||
|     } | ||||
|  |  | |||
|  | @ -1,10 +1,13 @@ | |||
| #ifndef UTILS_SPAWN_POINT_HPP | ||||
| #define UTILS_SPAWN_POINT_HPP | ||||
| 
 | ||||
| #include "godot_cpp/classes/node3d.hpp" | ||||
| namespace godot { | ||||
| class SpawnPoint3D : public Node3D { | ||||
|     GDCLASS(SpawnPoint3D, Node3D); | ||||
| #include <godot_cpp/classes/node3d.hpp> | ||||
| 
 | ||||
| namespace gd = godot; | ||||
| 
 | ||||
| namespace utils { | ||||
| class SpawnPoint3D : public gd::Node3D { | ||||
|     GDCLASS(SpawnPoint3D, gd::Node3D); | ||||
|     static void _bind_methods(); | ||||
| public: | ||||
|     virtual void _enter_tree() override; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Sara
						Sara