godot-cpp-utils/game_root.hpp

74 lines
2.1 KiB
C++

#ifndef GAME_ROOT_HPP
#define GAME_ROOT_HPP
#include <godot_cpp/classes/packed_scene.hpp>
#include <godot_cpp/classes/node.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/vector.hpp>
#include <godot_cpp/templates/pair.hpp>
#include "game_mode.hpp"
#include "level.hpp"
namespace godot {
class PlayerInput;
class IPlayer;
class SpawnPoint3D;
class GameRoot : public Node {
GDCLASS(GameRoot, Node);
static void _bind_methods();
public:
static GameRoot *get_singleton();
static bool has_singleton();
virtual void _enter_tree() override;
virtual void _exit_tree() override;
void player_connected();
void player_disconnected(uint32_t player_id);
bool initialize_player(IPlayer *player, uint32_t id);
void reset_game_mode();
protected:
void grab_singleton();
void release_singleton();
uint32_t find_empty_player_slot() const;
void set_game_mode(Ref<GameMode> prototype);
virtual IPlayer *spawn_player(uint32_t id);
protected:
static GameRoot *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{};
};
class GameRoot3D : public GameRoot {
GDCLASS(GameRoot3D, GameRoot);
static void _bind_methods();
public:
virtual void _ready() override;
Level3D *load_level(Ref<PackedScene> level);
Level3D *load_level_at(Ref<PackedScene> level, Transform3D at);
void register_spawn_point(SpawnPoint3D *spawn_point);
void unregister_spawn_point(SpawnPoint3D *spawn_point);
void set_first_boot_level(Ref<PackedScene> level);
Ref<PackedScene> get_first_boot_level() const;
protected:
virtual IPlayer *spawn_player(uint32_t id) override;
private:
static bool is_valid_level(Ref<PackedScene> &level);
private:
HashMap<StringName, Level3D*> levels{};
HashSet<SpawnPoint3D*> spawn_points{};
Ref<PackedScene> first_boot_level{};
};
}
#endif // !GAME_ROOT_HPP