feat: implemented enemy wretched patrol and chase states
This commit is contained in:
parent
1b0e4384b9
commit
9517588415
12 changed files with 224 additions and 17 deletions
74
modules/wave_survival/player_detector.cpp
Normal file
74
modules/wave_survival/player_detector.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include "player_detector.h"
|
||||
|
||||
String PlayerDetector::sig_awareness_changed{ "awareness_changed" };
|
||||
|
||||
void PlayerDetector::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo(sig_awareness_changed, PropertyInfo(Variant::BOOL, "aware")));
|
||||
}
|
||||
|
||||
// Check if the player is in a bounded area in front of the detector and unobscured.
|
||||
// As all tests are required to pass, we do them in increasing order of complexity, to minimize unneeded resource use.
|
||||
bool PlayerDetector::check() const {
|
||||
Vector3 const forward{ get_global_basis().get_column(2) };
|
||||
Vector3 const position{ get_global_position() };
|
||||
Vector3 const target{ PlayerBody::get_singleton()->get_global_position() + Vector3{ 0.f, 1.5f, 0.f } };
|
||||
// check if the target is in a view cone
|
||||
if (forward.dot(target - position) < this->min_dot) {
|
||||
return false;
|
||||
}
|
||||
// check if the target is in range
|
||||
if (position.distance_squared_to(target) > this->max_distance * this->max_distance) {
|
||||
return false;
|
||||
}
|
||||
// check if the target is obscured
|
||||
PhysicsDirectSpaceState3D::RayParameters params{ this->ray_params };
|
||||
params.from = position;
|
||||
params.to = target;
|
||||
PhysicsDirectSpaceState3D *space{ get_world_3d()->get_direct_space_state() };
|
||||
PhysicsDirectSpaceState3D::RayResult result{};
|
||||
space->intersect_ray(params, result);
|
||||
return result.collider == nullptr;
|
||||
}
|
||||
|
||||
void PlayerDetector::ready() {
|
||||
this->ray_params.exclude.insert(PlayerBody::get_singleton()->get_rid());
|
||||
}
|
||||
|
||||
void PlayerDetector::process(double delta) {
|
||||
if (this->query_timer > 0.0) {
|
||||
this->query_timer -= delta;
|
||||
} else {
|
||||
this->query_timer = this->query_time;
|
||||
bool const new_awareness{ check() };
|
||||
if (new_awareness != this->aware_of_player) {
|
||||
set_aware_of_player(new_awareness);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerDetector::set_aware_of_player(bool value) {
|
||||
print_line(vformat("awareness changed to %s", value));
|
||||
emit_signal(sig_awareness_changed, value);
|
||||
this->aware_of_player = value;
|
||||
}
|
||||
|
||||
void PlayerDetector::_notification(int what) {
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
return;
|
||||
}
|
||||
switch (what) {
|
||||
default:
|
||||
return;
|
||||
case NOTIFICATION_READY:
|
||||
set_process(true);
|
||||
ready();
|
||||
return;
|
||||
case NOTIFICATION_PROCESS:
|
||||
process(get_process_delta_time());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool PlayerDetector::is_aware_of_player() const {
|
||||
return this->aware_of_player;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue