diff --git a/src/projectile_pool.cpp b/src/projectile_pool.cpp index b18c219..e8ce504 100644 --- a/src/projectile_pool.cpp +++ b/src/projectile_pool.cpp @@ -1,5 +1,6 @@ #include "projectile_pool.hpp" #include "projectile.hpp" +#include "weapon_data.hpp" #include #include @@ -9,21 +10,20 @@ void ProjectilePool::_bind_methods() { } void ProjectilePool::_exit_tree() { - if(this->data.is_valid()) { - for(Node3D *node : this->inactive) { - node->queue_free(); - } + for(Node3D *node : this->inactive) { + node->queue_free(); } } -void ProjectilePool::set_data(Ref data) { +void ProjectilePool::set_data(Ref value) { + UtilityFunctions::print("ProjectilePool::set_data"); if(!this->data.is_null()) { this->active.clear(); for(Node3D *node : this->inactive) node->queue_free(); } - this->data = data; - if(!data.is_valid()) + this->data = value; + if(!value.is_valid()) return; this->count = this->data->get_projectile_count() * this->data->get_rounds_per_second() * 2; for(size_t i{0}; i < this->count; ++i) @@ -48,26 +48,31 @@ Node3D *ProjectilePool::claim_projectile() { void ProjectilePool::return_projectile(Node3D *node) { if(this->active.has(node)) { + this->remove_child(node); this->active.erase(node); this->inactive.push_back(node); - node->get_parent()->remove_child(node); } else { // leftover from previous weapon, free node->queue_free(); } } -Node3D *ProjectilePool::instantiate_new() const { +Node3D *ProjectilePool::instantiate_new(bool active) { Ref scene = this->data->get_projectile_scene(); - if(!scene.is_valid() || !ClassDB::is_parent_class("Node3D", scene->get_state()->get_node_type(0))) + if(!scene.is_valid() || !ClassDB::is_parent_class(scene->get_state()->get_node_type(0), "Projectile")) { + UtilityFunctions::push_error("Attempt to instantiate pooled projectile failed, scene is ", scene.is_valid() ? (scene->get_state()->get_node_type(0) + String(" not inherited from Projectile")) : "not a valid scene resource"); return nullptr; - Node3D *node = Object::cast_to(this->data->get_projectile_scene()->instantiate()); - IProjectile *projectile = dynamic_cast(node); - if(projectile != nullptr) { - projectile->set_weapon_data(this->data); - } else { - UtilityFunctions::push_warning("Projectile scene ", scene->get_path(), "' root node does not implement IProjectile"); } - return node; + Projectile *projectile = Object::cast_to(this->data->get_projectile_scene()->instantiate()); + if(!projectile) { + UtilityFunctions::push_error("Failed to instantiate projectile"); + return nullptr; + } + if(active) + this->add_child(projectile); + projectile->set_weapon_data(this->data); + projectile->set_projectile_pool(this); + projectile->set_as_top_level(true); + return projectile; } } diff --git a/src/projectile_pool.hpp b/src/projectile_pool.hpp index 3c75a18..742a7af 100644 --- a/src/projectile_pool.hpp +++ b/src/projectile_pool.hpp @@ -11,13 +11,13 @@ class ProjectilePool : public Node { static void _bind_methods(); public: virtual void _exit_tree() override; - void set_data(Ref data); + void set_data(Ref data); Ref get_data() const; Node3D *claim_projectile(); void return_projectile(Node3D *node); protected: - Node3D *instantiate_new() const; + Node3D *instantiate_new(bool active = false); private: Ref data{}; size_t count{0};