Compare commits

..

9 commits

14 changed files with 165 additions and 92 deletions

View file

@ -4,6 +4,7 @@
void EnemyBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_movement_direction", "direction"), &self_type::set_movement_direction);
ClassDB::bind_method(D_METHOD("get_unit"), &self_type::get_unit);
}
void EnemyBody::on_child_added(Node *node) {

View file

@ -60,7 +60,7 @@ void EnemySpawner::on_phase_change(bool hunt) {
return;
}
unit_3d->set_patrol_path(this->patrol_path);
add_child(unit_3d);
callable_mp(cast_to<Node>(this->region), &Node::add_child).call_deferred(unit_3d, false, INTERNAL_MODE_DISABLED);
unit_3d->set_global_transform(this->get_global_transform());
}

View file

@ -1,5 +1,6 @@
#include "map_region.h"
#include "enemy_body.h"
#include "player_body.h"
String const MapRegion::sig_difficulty_increased{ "difficulty_increased" };
String const MapRegion::sig_phase_changed{ "hunt_phase" };
@ -7,16 +8,33 @@ String const MapRegion::sig_phase_changed{ "hunt_phase" };
void MapRegion::_bind_methods() {
ADD_SIGNAL(MethodInfo(sig_difficulty_increased));
ADD_SIGNAL(MethodInfo(sig_phase_changed, PropertyInfo(Variant::BOOL, "hunt")));
ClassDB::bind_method(D_METHOD("raise_difficulty", "amount"), &self_type::raise_difficulty);
}
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::on_node_entered(Node3D *node) {
if (cast_to<PlayerBody>(node) != nullptr) {
this->has_player = true;
}
}
void MapRegion::on_node_exited(Node3D *node) {
if (cast_to<PlayerBody>(node) != nullptr) {
this->has_player = false;
}
}
void MapRegion::on_child_entered_tree(Node *node) {
if (NpcUnit * unit{ cast_to<NpcUnit>(node) }) {
if (!this->units.has(unit)) {
unit->set_region(this);
}
}
}
void MapRegion::enter_tree() {
connect("child_entered_tree", callable_mp(this, &self_type::on_child_entered_tree));
}
void MapRegion::ready() {
connect("body_entered", callable_mp(this, &self_type::on_node_entered));
}
@ -28,6 +46,9 @@ void MapRegion::_notification(int what) {
switch (what) {
default:
return;
case NOTIFICATION_ENTER_TREE:
enter_tree();
return;
case NOTIFICATION_READY:
ready();
return;
@ -50,10 +71,12 @@ void MapRegion::raise_difficulty(double amount) {
if (this->hunt_phase) {
return;
}
double const new_difficulty{ this->difficulty + amount };
int const new_trunc{ (int)Math::floor(new_difficulty) };
print_line("Difficutly Increased");
int const old_trunc{ (int)Math::floor(this->difficulty) };
this->difficulty += amount;
int const new_trunc{ (int)Math::floor(this->difficulty) };
if (new_trunc != old_trunc) {
print_line("Hunt Phase Started");
emit_signal(sig_difficulty_increased);
emit_signal(sig_phase_changed, true);
this->hunt_phase = true;

View file

@ -8,7 +8,10 @@
class MapRegion : public Area3D {
GDCLASS(MapRegion, Area3D);
static void _bind_methods();
void on_node_entered(Node *node);
void on_node_entered(Node3D *node);
void on_node_exited(Node3D *node);
void on_child_entered_tree(Node *node);
void enter_tree();
void ready();
protected:
@ -24,6 +27,7 @@ private:
double difficulty{ 0.f };
bool hunt_phase{ false };
HashSet<NpcUnit *> units{ nullptr };
bool has_player{ false };
public:
static String const sig_difficulty_increased;

View file

@ -8,6 +8,24 @@
void NpcUnit::_bind_methods() {
BIND_HPROPERTY(Variant::OBJECT, patrol_path, PROPERTY_HINT_NODE_TYPE, "PatrolPath");
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) {
@ -22,9 +40,6 @@ void NpcUnit::child_added(Node *node) {
npc->set_unit(this);
Vector3 const offset{ npc->get_global_position() - get_global_position() };
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));
}
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) {
// only run in-game
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
@ -42,6 +69,9 @@ void NpcUnit::_notification(int what) {
case NOTIFICATION_ENTER_TREE:
enter_tree();
return;
case NOTIFICATION_READY:
ready();
return;
}
}
@ -67,13 +97,17 @@ float NpcUnit::get_patrol_speed() const {
void NpcUnit::set_region(MapRegion *region) {
if (this->region == region) {
return;
return; // don't re-register
}
if (this->region != nullptr) {
this->region->remove_unit(this);
this->region->disconnect(MapRegion::sig_phase_changed, callable_mp(this, &self_type::on_npc_awareness_changed));
}
this->region = region;
region->register_unit(this);
if (region != nullptr) {
region->register_unit(this);
region->connect(MapRegion::sig_phase_changed, callable_mp(this, &self_type::on_npc_awareness_changed));
}
}
MapRegion *NpcUnit::get_region() const {

View file

@ -10,9 +10,11 @@ class MapRegion;
class NpcUnit : public Node3D {
GDCLASS(NpcUnit, Node3D);
static void _bind_methods();
void on_npc_death();
void on_npc_awareness_changed(bool seen);
void child_added(Node *node);
void enter_tree();
void ready();
protected:
void _notification(int what);

File diff suppressed because one or more lines are too long

View file

@ -5,12 +5,15 @@
[sub_resource type="GDScript" id="GDScript_qot2n"]
script/source = "extends EnemyWretched
@export var difficulty_weight : float = 0.25
func _on_health_status_death() -> void:
%StateMachine.process_mode = Node.PROCESS_MODE_DISABLED
%NavigationAgent3D.process_mode = Node.PROCESS_MODE_DISABLED
$wretched/AnimationPlayer.play(\"death\")
$CollisionShape3D.disabled = true
set_movement_direction(Vector2())
get_unit().region.raise_difficulty(difficulty_weight)
"
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ng1ul"]