From a34fbcb0581056bd464158acfa30289a3e2c2c2d Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Fri, 7 Aug 2015 16:49:24 +0200 Subject: [PATCH] check line of sight in chase ai --- src/ai/Chaser.hpp | 8 ++++++-- src/ai/Spawner.cpp | 2 +- src/ai/ai.cpp | 36 +++++++++++++++++++++++++++--------- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/ai/Chaser.hpp b/src/ai/Chaser.hpp index 6daaf36..43667c0 100644 --- a/src/ai/Chaser.hpp +++ b/src/ai/Chaser.hpp @@ -6,11 +6,13 @@ namespace blank { +class World; + class Chaser : public Controller { public: - Chaser(Entity &ctrl, Entity &tgt) noexcept; + Chaser(World &, Entity &ctrl, Entity &tgt) noexcept; ~Chaser(); Entity &Target() noexcept { return tgt; } @@ -19,8 +21,10 @@ public: void Update(int dt) override; private: + World &world; Entity &tgt; - float speed; + float chase_speed; + float flee_speed; float stop_dist; float flee_dist; diff --git a/src/ai/Spawner.cpp b/src/ai/Spawner.cpp index c73bcde..612c3cc 100644 --- a/src/ai/Spawner.cpp +++ b/src/ai/Spawner.cpp @@ -111,7 +111,7 @@ void Spawner::Spawn(const glm::ivec3 &chunk, const glm::vec3 &pos) { if (rand() % 2) { ctrl = new RandomWalk(e); } else { - ctrl = new Chaser(e, world.Player()); + ctrl = new Chaser(world, e, world.Player()); } controllers.emplace_back(ctrl); } diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp index b3e1a0c..6b380e4 100644 --- a/src/ai/ai.cpp +++ b/src/ai/ai.cpp @@ -2,19 +2,23 @@ #include "Controller.hpp" #include "RandomWalk.hpp" +#include "../model/geometry.hpp" #include "../world/Entity.hpp" +#include "../world/World.hpp" #include namespace blank { -Chaser::Chaser(Entity &ctrl, Entity &tgt) noexcept +Chaser::Chaser(World &world, Entity &ctrl, Entity &tgt) noexcept : Controller(ctrl) +, world(world) , tgt(tgt) -, speed(0.002f) -, stop_dist(5 * 5) -, flee_dist(3 * 3) { +, chase_speed(0.002f) +, flee_speed(-0.005f) +, stop_dist(10) +, flee_dist(5) { } @@ -24,12 +28,26 @@ Chaser::~Chaser() { void Chaser::Update(int dt) { glm::vec3 diff(Target().AbsoluteDifference(Controlled())); - float dist = dot (diff, diff); - // TODO: line of sight test - if (dist > stop_dist) { - Controlled().Velocity(normalize(diff) * speed); + float dist = length(diff); + glm::vec3 norm_diff(diff / dist); + + bool line_of_sight = true; + // FIXME: this only works if target is in the reference chunk (which is true for the player) + Ray aim{Target().Position() - diff, norm_diff}; + Chunk *chunk; + int blkid; + float distance; + glm::vec3 normal; + if (world.Intersection(aim, glm::mat4(1.0f), chunk, blkid, distance, normal)) { + line_of_sight = distance > dist; + } + + if (!line_of_sight) { + Controlled().Velocity(glm::vec3(0.0f)); + } else if (dist > stop_dist) { + Controlled().Velocity(norm_diff * chase_speed); } else if (dist < flee_dist) { - Controlled().Velocity(normalize(diff) * -speed); + Controlled().Velocity(norm_diff * flee_speed); } else { Controlled().Velocity(glm::vec3(0.0f)); } -- 2.39.2