feat: refactored how players are removed

stripped
Sara 2024-03-17 14:49:35 +01:00
parent 1cb000aa98
commit c85947f187
2 changed files with 34 additions and 19 deletions

View File

@ -50,19 +50,39 @@ void GameRoot::player_input_connected() {
this->emit_signal(StringName("player_connected"), input); this->emit_signal(StringName("player_connected"), input);
} }
void GameRoot::player_removed(uint32_t player_id) { void GameRoot::remove_player(uint32_t player_id) {
if(!this->players.has(player_id)) if(!this->players.has(player_id))
return; return;
// convert player object to node
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, "'");
return;
}
node->queue_free();
this->players.get(player_id).second = nullptr; this->players.get(player_id).second = nullptr;
} }
void GameRoot::remove_all_players() {
// free all player instances in use
for(KeyValue<uint32_t, Pair<PlayerInput*, IPlayer*>> &pair : this->players) {
// skip unused player slots
if(pair.value.second == nullptr)
continue;
else
this->remove_player(pair.key);
}
}
bool GameRoot::initialize_player(IPlayer *player, uint32_t id) { bool GameRoot::initialize_player(IPlayer *player, uint32_t id) {
if(!this->players.has(id)) if(!this->players.has(id))
return false; return false;
// register the player
Pair<PlayerInput*, IPlayer*> &found{this->players.get(id)}; Pair<PlayerInput*, IPlayer*> &found{this->players.get(id)};
this->add_child(player->to_node());
player->player_id = id;
found.second = player; found.second = player;
// set player id
player->player_id = id;
this->add_child(player->to_node());
player->setup_player_input(found.first); player->setup_player_input(found.first);
return true; return true;
} }
@ -98,16 +118,7 @@ uint32_t GameRoot::find_empty_player_slot() const {
} }
void GameRoot::set_game_mode(Ref<GameMode> prototype) { void GameRoot::set_game_mode(Ref<GameMode> prototype) {
// free all player instances in use this->remove_all_players();
for(KeyValue<uint32_t, Pair<PlayerInput*, IPlayer*>> &pair : this->players) {
if(pair.value.second == nullptr) continue;
Node *node = dynamic_cast<Node*>(pair.value.second);
if(node == nullptr) {
UtilityFunctions::push_error("Attempt to cast player '", pair.key, "' to node failed");
} else {
node->queue_free();
}
}
// allow "unsetting" the gamemode by passing an invalid gamemode // allow "unsetting" the gamemode by passing an invalid gamemode
// shorthand for this behaviour is reset_game_mode // shorthand for this behaviour is reset_game_mode
if(prototype.is_null() || !prototype.is_valid()) { if(prototype.is_null() || !prototype.is_valid()) {

View File

@ -1,15 +1,15 @@
#ifndef GAME_ROOT_HPP #ifndef GAME_ROOT_HPP
#define GAME_ROOT_HPP #define GAME_ROOT_HPP
#include <godot_cpp/classes/packed_scene.hpp> #include "game_mode.hpp"
#include "level.hpp"
#include <godot_cpp/classes/node.hpp> #include <godot_cpp/classes/node.hpp>
#include <godot_cpp/classes/packed_scene.hpp>
#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/vector.hpp>
#include <godot_cpp/templates/pair.hpp> #include <godot_cpp/templates/pair.hpp>
#include "game_mode.hpp" #include <godot_cpp/templates/vector.hpp>
#include "level.hpp"
namespace godot { namespace godot {
class PlayerInput; class PlayerInput;
@ -31,8 +31,12 @@ public:
void player_input_connected(); void player_input_connected();
// force-disconnect a player // force-disconnect a player
// calls queue_free on the IPlayer instance // calls queue_free on the IPlayer instance
void player_removed(uint32_t player_id); void remove_player(uint32_t player_id);
// calls remove_player for every used player input slot
void remove_all_players();
// initialize and register a player instance // initialize and register a player instance
// the player will be added to the tree and AFTER setup_player_input will be called
// this way the player can initialize before setting up input
bool initialize_player(IPlayer *player, uint32_t id); bool initialize_player(IPlayer *player, uint32_t id);
// shorthand for set_game_mode(Ref<GameMode>()) // shorthand for set_game_mode(Ref<GameMode>())