]> git.localhorst.tv Git - blank.git/blob - src/ai/ai.cpp
get rid of angular velocity
[blank.git] / src / ai / ai.cpp
1 #include "Chaser.hpp"
2 #include "Controller.hpp"
3 #include "RandomWalk.hpp"
4
5 #include "../model/geometry.hpp"
6 #include "../world/Entity.hpp"
7 #include "../world/World.hpp"
8 #include "../world/WorldCollision.hpp"
9
10 #include <glm/glm.hpp>
11
12
13 namespace blank {
14
15 Chaser::Chaser(World &world, Entity &ctrl, Entity &tgt) noexcept
16 : Controller(ctrl)
17 , world(world)
18 , tgt(tgt)
19 , chase_speed(2.0f)
20 , flee_speed(-5.0f)
21 , stop_dist(10)
22 , flee_dist(5) {
23         tgt.Ref();
24 }
25
26 Chaser::~Chaser() {
27         tgt.UnRef();
28 }
29
30 void Chaser::Update(int dt) {
31         if (Target().Dead()) {
32                 Controlled().Kill();
33                 return;
34         }
35
36         glm::vec3 diff(Target().AbsoluteDifference(Controlled()));
37         float dist = length(diff);
38         if (dist < std::numeric_limits<float>::epsilon()) {
39                 Controlled().TargetVelocity(glm::vec3(0.0f));
40                 return;
41         }
42         glm::vec3 norm_diff(diff / dist);
43
44         bool line_of_sight = true;
45         Ray aim{Target().Position() - diff, norm_diff};
46         WorldCollision coll;
47         if (world.Intersection(aim, glm::mat4(1.0f), Target().ChunkCoords(), coll)) {
48                 line_of_sight = coll.depth > dist;
49         }
50
51         if (!line_of_sight) {
52                 Controlled().TargetVelocity(glm::vec3(0.0f));
53         } else if (dist > stop_dist) {
54                 Controlled().TargetVelocity(norm_diff * chase_speed);
55         } else if (dist < flee_dist) {
56                 Controlled().TargetVelocity(norm_diff * flee_speed);
57         } else {
58                 Controlled().TargetVelocity(glm::vec3(0.0f));
59         }
60 }
61
62
63 Controller::Controller(Entity &e) noexcept
64 : entity(e) {
65         entity.Ref();
66 }
67
68 Controller::~Controller() {
69         entity.UnRef();
70 }
71
72
73 RandomWalk::RandomWalk(Entity &e, std::uint64_t seed) noexcept
74 : Controller(e)
75 , random(seed)
76 , start_vel(e.Velocity())
77 , target_vel(start_vel)
78 , switch_time(0)
79 , lerp_max(1.0f)
80 , lerp_time(0.0f) {
81
82 }
83
84 RandomWalk::~RandomWalk() {
85
86 }
87
88 void RandomWalk::Update(int dt) {
89         switch_time -= dt;
90         lerp_time -= dt;
91         if (switch_time < 0) {
92                 switch_time += 2500 + (random.Next<unsigned short>() % 5000);
93                 lerp_max = 1500 + (random.Next<unsigned short>() % 1000);
94                 lerp_time = lerp_max;
95                 Change();
96         } else if (lerp_time > 0) {
97                 float a = std::min(lerp_time / lerp_max, 1.0f);
98                 Controlled().TargetVelocity(mix(target_vel, start_vel, a));
99         } else {
100                 Controlled().TargetVelocity(target_vel);
101         }
102 }
103
104 void RandomWalk::Change() noexcept {
105         start_vel = target_vel;
106
107         constexpr float base = 0.001f;
108
109         target_vel.x = base * (random.Next<short>() % 1024);
110         target_vel.y = base * (random.Next<short>() % 1024);
111         target_vel.z = base * (random.Next<short>() % 1024);
112 }
113
114 }