feat: npc unit will now deallocate itself when all npc members are killed
This commit is contained in:
parent
8a9d70b37e
commit
b3090243e0
|
@ -8,6 +8,24 @@
|
||||||
void NpcUnit::_bind_methods() {
|
void NpcUnit::_bind_methods() {
|
||||||
BIND_HPROPERTY(Variant::OBJECT, patrol_path, PROPERTY_HINT_NODE_TYPE, "PatrolPath");
|
BIND_HPROPERTY(Variant::OBJECT, patrol_path, PROPERTY_HINT_NODE_TYPE, "PatrolPath");
|
||||||
BIND_PROPERTY(Variant::FLOAT, patrol_speed);
|
BIND_PROPERTY(Variant::FLOAT, patrol_speed);
|
||||||
|
BIND_HPROPERTY(Variant::OBJECT, region, PROPERTY_HINT_NODE_TYPE, "MapRegion");
|
||||||
|
}
|
||||||
|
|
||||||
|
void NpcUnit::on_npc_death() {
|
||||||
|
// remove any dead npcs from the list
|
||||||
|
// leaving their bodies as separate nodes part of the tree
|
||||||
|
for (EnemyBody *npc : this->npcs) {
|
||||||
|
if (npc->get_health()->get_health() <= 0) {
|
||||||
|
this->get_parent()->add_child(npc);
|
||||||
|
this->npcs.erase(npc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove unit from world once all npcs are dead
|
||||||
|
if (this->npcs.size() <= 0) {
|
||||||
|
this->set_region(nullptr); // de-register from region
|
||||||
|
this->queue_free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NpcUnit::on_npc_awareness_changed(bool value) {
|
void NpcUnit::on_npc_awareness_changed(bool value) {
|
||||||
|
@ -22,9 +40,6 @@ void NpcUnit::child_added(Node *node) {
|
||||||
npc->set_unit(this);
|
npc->set_unit(this);
|
||||||
Vector3 const offset{ npc->get_global_position() - get_global_position() };
|
Vector3 const offset{ npc->get_global_position() - get_global_position() };
|
||||||
npc->set_unit_offset({ offset.x, offset.z });
|
npc->set_unit_offset({ offset.x, offset.z });
|
||||||
if (PlayerDetector * detector{ cast_to<PlayerDetector>(npc->get_node(NodePath("%PlayerDetector"))) }) {
|
|
||||||
detector->connect(PlayerDetector::sig_awareness_changed, callable_mp(this, &self_type::on_npc_awareness_changed));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +47,19 @@ void NpcUnit::enter_tree() {
|
||||||
this->connect("child_entered_tree", callable_mp(this, &self_type::child_added));
|
this->connect("child_entered_tree", callable_mp(this, &self_type::child_added));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NpcUnit::ready() {
|
||||||
|
for (EnemyBody *npc : this->npcs) {
|
||||||
|
if (PlayerDetector * detector{ cast_to<PlayerDetector>(npc->get_node(NodePath("%PlayerDetector"))) }) {
|
||||||
|
detector->connect(PlayerDetector::sig_awareness_changed, callable_mp(this, &self_type::on_npc_awareness_changed));
|
||||||
|
}
|
||||||
|
if (HealthStatus * health{ npc->get_health() }) {
|
||||||
|
health->connect(HealthStatus::sig_death, callable_mp(this, &self_type::on_npc_death));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NpcUnit::_notification(int what) {
|
void NpcUnit::_notification(int what) {
|
||||||
|
// only run in-game
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +69,9 @@ void NpcUnit::_notification(int what) {
|
||||||
case NOTIFICATION_ENTER_TREE:
|
case NOTIFICATION_ENTER_TREE:
|
||||||
enter_tree();
|
enter_tree();
|
||||||
return;
|
return;
|
||||||
|
case NOTIFICATION_READY:
|
||||||
|
ready();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,13 +97,17 @@ float NpcUnit::get_patrol_speed() const {
|
||||||
|
|
||||||
void NpcUnit::set_region(MapRegion *region) {
|
void NpcUnit::set_region(MapRegion *region) {
|
||||||
if (this->region == region) {
|
if (this->region == region) {
|
||||||
return;
|
return; // don't re-register
|
||||||
}
|
}
|
||||||
if (this->region != nullptr) {
|
if (this->region != nullptr) {
|
||||||
this->region->remove_unit(this);
|
this->region->remove_unit(this);
|
||||||
|
this->region->disconnect(MapRegion::sig_phase_changed, callable_mp(this, &self_type::on_npc_awareness_changed));
|
||||||
}
|
}
|
||||||
this->region = region;
|
this->region = region;
|
||||||
|
if (region != nullptr) {
|
||||||
region->register_unit(this);
|
region->register_unit(this);
|
||||||
|
region->connect(MapRegion::sig_phase_changed, callable_mp(this, &self_type::on_npc_awareness_changed));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRegion *NpcUnit::get_region() const {
|
MapRegion *NpcUnit::get_region() const {
|
||||||
|
|
|
@ -10,9 +10,11 @@ class MapRegion;
|
||||||
class NpcUnit : public Node3D {
|
class NpcUnit : public Node3D {
|
||||||
GDCLASS(NpcUnit, Node3D);
|
GDCLASS(NpcUnit, Node3D);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
void on_npc_death();
|
||||||
void on_npc_awareness_changed(bool seen);
|
void on_npc_awareness_changed(bool seen);
|
||||||
void child_added(Node *node);
|
void child_added(Node *node);
|
||||||
void enter_tree();
|
void enter_tree();
|
||||||
|
void ready();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int what);
|
void _notification(int what);
|
||||||
|
|
Loading…
Reference in a new issue