Compare commits

...

10 Commits

8 changed files with 32 additions and 41 deletions

View File

@ -2,7 +2,7 @@
#include <godot_cpp/classes/global_constants.hpp> #include <godot_cpp/classes/global_constants.hpp>
#include <godot_cpp/classes/packed_scene.hpp> #include <godot_cpp/classes/packed_scene.hpp>
#include <godot_cpp/classes/scene_state.hpp> #include <godot_cpp/classes/scene_state.hpp>
#include "utils/godot_macros.hpp" #include "godot_macros.hpp"
namespace utils { namespace utils {
void GameMode::_bind_methods() { void GameMode::_bind_methods() {

View File

@ -6,12 +6,13 @@
#include "player_input.hpp" #include "player_input.hpp"
#include "player.hpp" #include "player.hpp"
#include "spawn_point.hpp" #include "spawn_point.hpp"
#include "utils/game_state.hpp" #include "game_state.hpp"
#include <cstdint> #include <cstdint>
#include <godot_cpp/classes/global_constants.hpp> #include <godot_cpp/classes/global_constants.hpp>
#include <godot_cpp/classes/input.hpp> #include <godot_cpp/classes/input.hpp>
#include <godot_cpp/classes/packed_scene.hpp> #include <godot_cpp/classes/packed_scene.hpp>
#include <godot_cpp/classes/scene_state.hpp> #include <godot_cpp/classes/scene_state.hpp>
#include <godot_cpp/classes/resource_loader.hpp>
#include <godot_cpp/core/class_db.hpp> #include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/templates/pair.hpp> #include <godot_cpp/templates/pair.hpp>
#include <godot_cpp/variant/string_name.hpp> #include <godot_cpp/variant/string_name.hpp>
@ -36,19 +37,21 @@ bool GameRoot3D::has_singleton() {
return GameRoot3D::singleton_instance != nullptr; return GameRoot3D::singleton_instance != nullptr;
} }
void GameRoot3D::_enter_tree() { GDGAMEONLY(); void GameRoot3D::_enter_tree() {
// TODO: Replace this with detecting input devices // TODO: Replace this with detecting input devices
this->player_input_connected(); this->player_input_connected();
this->grab_singleton(); this->grab_singleton();
this->rng = godot::Ref<godot::RandomNumberGenerator>(memnew(godot::RandomNumberGenerator));
} }
void GameRoot3D::_ready() { GDGAMEONLY(); void GameRoot3D::_ready() {
this->game_state = gd::ResourceLoader::get_singleton()->load("user://savegame.res");
if(!this->game_state.is_valid())
this->game_state = this->game_state_prototype->duplicate(true);
this->load_level(this->first_boot_level); this->load_level(this->first_boot_level);
// TODO: try load save data from file.
this->game_state = this->game_state_prototype->duplicate(true);
} }
void GameRoot3D::_exit_tree() { GDGAMEONLY(); void GameRoot3D::_exit_tree() {
this->release_singleton(); this->release_singleton();
} }
@ -119,7 +122,7 @@ Level3D *GameRoot3D::load_level_at(gd::Ref<gd::PackedScene> level, gd::Transform
// store and add to tree at desired transform // store and add to tree at desired transform
// if this is the first level containing a game mode currently active use it's gamemode as a prototype // if this is the first level containing a game mode currently active use it's gamemode as a prototype
gd::Ref<gd::PackedScene> game_mode_prototype{instance->get_game_mode_prototype()}; gd::Ref<gd::PackedScene> game_mode_prototype{instance->get_game_mode_prototype()};
bool const switch_game_mode{!this->game_mode || this->game_mode->get_scene_file_path() != game_mode_prototype->get_path()}; bool const switch_game_mode{!this->game_mode || !game_mode_prototype.is_valid() || this->game_mode->get_scene_file_path() != game_mode_prototype->get_path()};
if(switch_game_mode) { if(switch_game_mode) {
this->set_game_mode(instance->get_game_mode_prototype()); this->set_game_mode(instance->get_game_mode_prototype());
} }
@ -138,7 +141,7 @@ void GameRoot3D::unload_all_levels() {
gd::HashMap<gd::StringName, Level3D*> levels = this->get_levels(); gd::HashMap<gd::StringName, Level3D*> levels = this->get_levels();
for(gd::KeyValue<gd::StringName, Level3D*> &kvp : levels) for(gd::KeyValue<gd::StringName, Level3D*> &kvp : levels)
kvp.value->call_deferred("queue_free"); kvp.value->call_deferred("queue_free");
this->get_levels().clear(); this->levels.clear();
this->reset_game_mode(); this->reset_game_mode();
} }
@ -180,8 +183,10 @@ void GameRoot3D::set_game_mode(gd::Ref<gd::PackedScene> prototype) {
this->remove_all_players(); this->remove_all_players();
if(this->game_mode != nullptr) if(this->game_mode != nullptr)
this->game_mode->queue_free(); this->game_mode->queue_free();
if(prototype.is_null() || !prototype.is_valid()) if(prototype.is_null() || !prototype.is_valid()) {
this->game_mode = nullptr;
return; // allow "unsetting" the gamemode by passing an invalid gamemode return; // allow "unsetting" the gamemode by passing an invalid gamemode
}
// Detect passing of valid scene that is an invalid game mode // Detect passing of valid scene that is an invalid game mode
if(!gd::ClassDB::is_parent_class(prototype->get_state()->get_node_type(0), "GameMode")) { if(!gd::ClassDB::is_parent_class(prototype->get_state()->get_node_type(0), "GameMode")) {
gd::UtilityFunctions::push_error("Attempted to load non-gamemode scene as gamemode"); gd::UtilityFunctions::push_error("Attempted to load non-gamemode scene as gamemode");

View File

@ -10,7 +10,6 @@
#include <godot_cpp/templates/hash_map.hpp> #include <godot_cpp/templates/hash_map.hpp>
#include <godot_cpp/templates/hash_set.hpp> #include <godot_cpp/templates/hash_set.hpp>
#include <godot_cpp/templates/pair.hpp> #include <godot_cpp/templates/pair.hpp>
#include <godot_cpp/templates/pair.hpp>
#include <godot_cpp/templates/vector.hpp> #include <godot_cpp/templates/vector.hpp>
namespace gd = godot; namespace gd = godot;
@ -159,7 +158,7 @@ private:
* *
* `*get_game_mode()` * `*get_game_mode()`
*/ */
GameMode *game_mode{}; GameMode *game_mode{};
/*! Active game state. /*! Active game state.
* *
* Will be assigned loaded save data, or game_state_prototype if no save data is found. * Will be assigned loaded save data, or game_state_prototype if no save data is found.
@ -171,14 +170,14 @@ private:
* *
* `get_first_boot_level()` `set_first_boot_level(value)` * `get_first_boot_level()` `set_first_boot_level(value)`
*/ */
gd::Ref<gd::PackedScene> first_boot_level{}; gd::Ref<gd::PackedScene> first_boot_level{};
/*! The default game state data. /*! The default game state data.
* *
* Duplicated and assigned to game_state if no save data is available. * Duplicated and assigned to game_state if no save data is available.
* *
* `get_game_state_prototype()` `set_game_state_prototype(value)` * `get_game_state_prototype()` `set_game_state_prototype(value)`
*/ */
gd::Ref<GameState> game_state_prototype{}; gd::Ref<GameState> game_state_prototype{};
}; };
} }

View File

@ -37,28 +37,28 @@
/*! \def GDFUNCTION(FnName_) /*! \def GDFUNCTION(FnName_)
* \brief Register a function CLASSNAME::FnName_() to godot. * \brief Register a function CLASSNAME::FnName_() to godot.
* *
* Requires setting CLASSNAME as a #define first. * Requires setting CLASSNAME as a #define first.
*/ */
#define GDFUNCTION(FnName_) godot::ClassDB::bind_method(godot::D_METHOD(#FnName_), &CLASSNAME::FnName_) #define GDFUNCTION(FnName_) godot::ClassDB::bind_method(godot::D_METHOD(#FnName_), &CLASSNAME::FnName_)
/*! \def GDFUNCTION_ARGS(FnName_, ...) /*! \def GDFUNCTION_ARGS(FnName_, ...)
* \brief Register a function CLASSNAME::FnName_(...) to godot. * \brief Register a function CLASSNAME::FnName_(...) to godot.
* *
* Requires setting CLASSNAME as a #define first. * Requires setting CLASSNAME as a #define first.
*/ */
#define GDFUNCTION_ARGS(FnName_, ...) godot::ClassDB::bind_method(godot::D_METHOD(#FnName_, __VA_ARGS__), &CLASSNAME::FnName_) #define GDFUNCTION_ARGS(FnName_, ...) godot::ClassDB::bind_method(godot::D_METHOD(#FnName_, __VA_ARGS__), &CLASSNAME::FnName_)
/*! \def GDFUNCTION_STATIC(FnName_) /*! \def GDFUNCTION_STATIC(FnName_)
* \brief Register a static member function CLASSNAME::FnName_() to godot. * \brief Register a static member function CLASSNAME::FnName_() to godot.
* *
* Requires setting CLASSNAME as a #define first. * Requires setting CLASSNAME as a #define first.
*/ */
#define GDFUNCTION_STATIC(FnName_) godot::ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), godot::D_METHOD(#FnName_), &CLASSNAME::_FnName) #define GDFUNCTION_STATIC(FnName_) godot::ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), godot::D_METHOD(#FnName_), &CLASSNAME::_FnName)
/*! \def GDFUNCTION_STATIC_ARGS(FnName_, ...) /*! \def GDFUNCTION_STATIC_ARGS(FnName_, ...)
* \brief Register a static member function CLASSNAME::FnName_(...) to godot. * \brief Register a static member function CLASSNAME::FnName_(...) to godot.
* *
* Requires setting CLASSNAME as a #define first. * Requires setting CLASSNAME as a #define first.
*/ */
#define GDFUNCTION_STATIC_ARGS(FnName_, ...) godot::ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), godot::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_)
@ -77,19 +77,6 @@
#define GDNODETYPE(Class_) godot::vformat("%s/%s:%s", godot::Variant::OBJECT, godot::PROPERTY_HINT_NODE_TYPE, Class_) #define GDNODETYPE(Class_) godot::vformat("%s/%s:%s", godot::Variant::OBJECT, godot::PROPERTY_HINT_NODE_TYPE, Class_)
#define GDENUMTYPE(EnumString_) godot::vformat("%s/%s:%s", godot::Variant::INT, godot::PROPERTY_HINT_ENUM, EnumString_) #define GDENUMTYPE(EnumString_) godot::vformat("%s/%s:%s", godot::Variant::INT, godot::PROPERTY_HINT_ENUM, EnumString_)
/*! \def GDEDITORONLY()
* \brief Execute the rest of the function only if currently running as editor.
*
* Useful for _ready, _enter/_exit, _process, etc. functions.
*/
#define GDEDITORONLY() if(!godot::Engine::get_singleton()->is_editor_hint()) return;
/*! \def GDGAMEONLY()
* \brief Execute the rest of the function only if currently running as game.
*
* Useful for _ready, _enter/_exit, _process, etc. functions.
*/
#define GDGAMEONLY() if(godot::Engine::get_singleton()->is_editor_hint()) return;
/*! \def GDENUM(Name_, ...) /*! \def GDENUM(Name_, ...)
* \brief Declare a scoped enum struct. * \brief Declare a scoped enum struct.
* *

View File

@ -1,6 +1,6 @@
#include "level.hpp" #include "level.hpp"
#include "godot_macros.hpp"
#include <godot_cpp/core/class_db.hpp> #include <godot_cpp/core/class_db.hpp>
#include "utils/godot_macros.hpp"
#include <godot_cpp/classes/scene_state.hpp> #include <godot_cpp/classes/scene_state.hpp>
namespace utils { namespace utils {

View File

@ -74,21 +74,21 @@ gd::Vector2 PlayerInput::get_last_mouse_motion() {
return PlayerInput::lastMouseMotion; return PlayerInput::lastMouseMotion;
} }
void PlayerInput::_enter_tree() { GDGAMEONLY(); void PlayerInput::_enter_tree() {
if(!PlayerInput::primaryExists) { if(!PlayerInput::primaryExists) {
this->isPrimary = true; this->isPrimary = true;
PlayerInput::primaryExists = true; PlayerInput::primaryExists = true;
} }
} }
void PlayerInput::_exit_tree() { GDGAMEONLY(); void PlayerInput::_exit_tree() {
if(this->isPrimary) { if(this->isPrimary) {
this->isPrimary = false; this->isPrimary = false;
PlayerInput::primaryExists = false; PlayerInput::primaryExists = false;
} }
} }
void PlayerInput::_unhandled_input(gd::Ref<gd::InputEvent> const &event) { GDGAMEONLY(); void PlayerInput::_unhandled_input(gd::Ref<gd::InputEvent> const &event) {
if(this->isPrimary && event->is_class("InputEventMouseMotion")) if(this->isPrimary && event->is_class("InputEventMouseMotion"))
PlayerInput::lastMouseMotion = gd::Object::cast_to<gd::InputEventMouseMotion>(*event)->get_relative(); PlayerInput::lastMouseMotion = gd::Object::cast_to<gd::InputEventMouseMotion>(*event)->get_relative();
for(Listener& listener: this->listeners) { for(Listener& listener: this->listeners) {

View File

@ -9,11 +9,11 @@
namespace utils { namespace utils {
void godot_cpp_utils_register_types() { void godot_cpp_utils_register_types() {
GDREGISTER_CLASS(utils::GameMode); GDREGISTER_RUNTIME_CLASS(utils::GameMode);
GDREGISTER_CLASS(utils::GameRoot3D); GDREGISTER_RUNTIME_CLASS(utils::GameRoot3D);
GDREGISTER_CLASS(utils::GameState); GDREGISTER_CLASS(utils::GameState);
GDREGISTER_CLASS(utils::Level3D); GDREGISTER_RUNTIME_CLASS(utils::Level3D);
GDREGISTER_CLASS(utils::PlayerInput); GDREGISTER_RUNTIME_CLASS(utils::PlayerInput);
GDREGISTER_CLASS(utils::SpawnPoint3D); GDREGISTER_RUNTIME_CLASS(utils::SpawnPoint3D);
} }
} }

View File

@ -1,5 +1,5 @@
#include "spawn_point.hpp" #include "spawn_point.hpp"
#include "utils/game_root.hpp" #include "game_root.hpp"
namespace utils { namespace utils {
void SpawnPoint3D::_bind_methods() { void SpawnPoint3D::_bind_methods() {