feat: defining map region unit un-/registering behaviour

This commit is contained in:
Sara 2025-08-17 17:55:09 +02:00
parent 92c38e54b6
commit d8ae45df0f
7 changed files with 87 additions and 1 deletions

View file

@ -6,6 +6,15 @@ void EnemyBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_movement_direction", "direction"), &self_type::set_movement_direction);
}
void EnemyBody::on_child_added(Node *node) {
if (StateMachine *fsm{ cast_to<StateMachine>(node) }) {
this->fsm = fsm;
}
if (NavigationAgent3D *nav{ cast_to<NavigationAgent3D>(node) }) {
this->nav = nav;
}
}
void EnemyBody::ready() {
this->fsm = cast_to<StateMachine>(get_node(NodePath("%StateMachine")));
this->nav = cast_to<NavigationAgent3D>(get_node(NodePath("%NavigationAgent3D")));
@ -50,6 +59,10 @@ NpcUnit *EnemyBody::get_unit() const {
return this->unit;
}
HealthStatus *EnemyBody::get_health() const {
return this->health;
}
NavigationAgent3D *EnemyBody::get_nav() const {
return this->nav;
}

View file

@ -10,6 +10,7 @@ class NpcUnit;
class EnemyBody : public CharacterBody3D {
GDCLASS(EnemyBody, CharacterBody3D);
static void _bind_methods();
void on_child_added(Node *node);
void ready();
void physics_process(double delta);
@ -20,6 +21,7 @@ public:
void set_unit(NpcUnit *unit);
NpcUnit *get_unit() const;
HealthStatus *get_health() const;
NavigationAgent3D *get_nav() const;
void set_movement_speed(float value);
float get_movement_speed() const;
@ -33,6 +35,7 @@ private:
StateMachine *fsm{ nullptr };
NpcUnit *unit{ nullptr };
HealthStatus *health{ nullptr };
NavigationAgent3D *nav{ nullptr };
Vector2 unit_offset{ 0, 0 };
};

View file

@ -1,7 +1,45 @@
#include "map_region.h"
#include "enemy_body.h"
String const MapRegion::sig_phase_changed{ "phase_changed" };
void MapRegion::_bind_methods() {
ADD_SIGNAL(MethodInfo(sig_phase_changed, PropertyInfo(Variant::BOOL, "hunt_phase")));
}
void MapRegion::on_node_entered(Node *node) {
if (EnemyBody * body{ cast_to<EnemyBody>(node) }) {
if (!this->units.has(body->get_unit())) {
body->get_unit()->set_region(this);
}
}
}
void MapRegion::ready() {
connect("body_entered", callable_mp(this, &self_type::on_node_entered));
}
void MapRegion::_notification(int what) {
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
switch (what) {
default:
return;
case NOTIFICATION_READY:
ready();
return;
}
}
void MapRegion::register_unit(NpcUnit *unit) {
if (!this->units.has(unit)) {
this->units.insert(unit);
}
}
void MapRegion::remove_unit(NpcUnit *unit) {
if (this->units.has(unit)) {
this->units.erase(unit);
}
}

View file

@ -1,15 +1,27 @@
#ifndef MAP_REGION_H
#define MAP_REGION_H
#include "core/templates/hash_set.h"
#include "npc_unit.h"
#include "scene/3d/physics/area_3d.h"
class MapRegion : public Area3D {
GDCLASS(MapRegion, Area3D);
static void _bind_methods();
void on_node_entered(Node *node);
void ready();
protected:
void _notification(int what);
public:
void register_unit(NpcUnit *unit);
void remove_unit(NpcUnit *unit);
private:
float awareness{ 0.f };
bool hunt_phase{ false };
HashSet<NpcUnit *> units{ nullptr };
public:
static String const sig_phase_changed;

View file

@ -1,6 +1,7 @@
#include "npc_unit.h"
#include "enemy_body.h"
#include "macros.h"
#include "map_region.h"
#include "patrol_path.h"
#include "player_detector.h"
@ -63,3 +64,18 @@ void NpcUnit::set_patrol_speed(float speed) {
float NpcUnit::get_patrol_speed() const {
return this->patrol_speed;
}
void NpcUnit::set_region(MapRegion *region) {
if (this->region == region) {
return;
}
if (this->region != nullptr) {
this->region->remove_unit(this);
}
this->region = region;
region->register_unit(this);
}
MapRegion *NpcUnit::get_region() const {
return this->region;
}

View file

@ -5,6 +5,7 @@
class StateMachine;
class EnemyBody;
class PatrolPath;
class MapRegion;
class NpcUnit : public Node3D {
GDCLASS(NpcUnit, Node3D);
@ -22,12 +23,15 @@ public:
bool is_aware_of_player() const; //!< becomes true when any individual in the unit sees the player.
void set_patrol_speed(float value);
float get_patrol_speed() const;
void set_region(MapRegion *region);
MapRegion *get_region() const;
private:
bool aware_of_player{ false };
Vector<EnemyBody *> npcs{};
PatrolPath *patrol_path{ nullptr };
float patrol_speed{ 1.f };
MapRegion *region{ nullptr };
};
#endif // !NPC_UNIT_H

View file

@ -9,6 +9,7 @@
#include "wave_survival/hitbox.h"
#include "wave_survival/hitscan_muzzle.h"
#include "wave_survival/interactable.h"
#include "wave_survival/map_region.h"
#include "wave_survival/muzzle_effect.h"
#include "wave_survival/npc_unit.h"
#include "wave_survival/patrol_path.h"
@ -22,7 +23,6 @@
#include "wave_survival/state.h"
#include "wave_survival/state_machine.h"
#include "wave_survival/weapon_base.h"
#include "wave_survival/map_region.h"
#include "wave_survival/weapon_inventory.h"
#include "wave_survival/weapons/revolver.h"
#include "wave_survival/weapons/rifle.h"