]> git.localhorst.tv Git - blobs.git/blob - src/creature/Creature.hpp
44107bea32dd62b3f390b1e1b0575cb39d232fdf
[blobs.git] / src / creature / Creature.hpp
1 #ifndef BLOBS_CREATURE_CREATURE_HPP_
2 #define BLOBS_CREATURE_CREATURE_HPP_
3
4 #include "Composition.hpp"
5 #include "Genome.hpp"
6 #include "Goal.hpp"
7 #include "Memory.hpp"
8 #include "Situation.hpp"
9 #include "Steering.hpp"
10 #include "../graphics/SimpleVAO.hpp"
11 #include "../math/glm.hpp"
12
13 #include <memory>
14 #include <string>
15 #include <vector>
16
17
18 namespace blobs {
19 namespace app {
20         struct Assets;
21 }
22 namespace graphics {
23         class Viewport;
24 }
25 namespace world {
26         class Body;
27         class Planet;
28         class Simulation;
29 }
30 namespace creature {
31
32 class Creature {
33
34 public:
35         using Callback = std::function<void(Creature &)>;
36
37         struct Stat {
38                 // [0,1], zero being good, one bad
39                 double value = 0.0;
40                 // static gain per second
41                 double gain = 0.0;
42                 // adjust value by delta
43                 void Add(double delta) noexcept {
44                         value = glm::clamp(value + delta, 0.0, 1.0);
45                 }
46                 bool Empty() const noexcept { return value < 0.000001; }
47                 bool Good() const noexcept { return value < 0.25; }
48                 bool Okay() const noexcept { return value < 0.5; }
49                 bool Bad() const noexcept { return !Okay(); }
50                 bool Critical() const noexcept { return value > 0.75; }
51                 bool Full() const noexcept { return value > 0.999999; }
52         };
53         struct Stats {
54                 Stat stat[7];
55                 Stat &Damage() noexcept { return stat[0]; }
56                 const Stat &Damage() const noexcept { return stat[0]; }
57                 Stat &Breath() noexcept { return stat[1]; }
58                 const Stat &Breath() const noexcept { return stat[1]; }
59                 Stat &Thirst() noexcept { return stat[2]; }
60                 const Stat &Thirst() const noexcept { return stat[2]; }
61                 Stat &Hunger() noexcept { return stat[3]; }
62                 const Stat &Hunger() const noexcept { return stat[3]; }
63                 Stat &Exhaustion() noexcept { return stat[4]; }
64                 const Stat &Exhaustion() const noexcept { return stat[4]; }
65                 Stat &Fatigue() noexcept { return stat[5]; }
66                 const Stat &Fatigue() const noexcept { return stat[5]; }
67                 Stat &Boredom() noexcept { return stat[6]; }
68                 const Stat &Boredom() const noexcept { return stat[6]; }
69         };
70
71 public:
72         explicit Creature(world::Simulation &);
73         ~Creature();
74
75         Creature(const Creature &) = delete;
76         Creature &operator =(const Creature &) = delete;
77
78         Creature(Creature &&) = delete;
79         Creature &operator =(Creature &&) = delete;
80
81 public:
82         world::Simulation &GetSimulation() noexcept { return sim; }
83         const world::Simulation &GetSimulation() const noexcept { return sim; }
84
85         void Name(const std::string &n) noexcept { name = n; }
86         const std::string &Name() const noexcept { return name; }
87
88         Genome &GetGenome() noexcept { return genome; }
89         const Genome &GetGenome() const noexcept { return genome; }
90
91         Genome::Properties<double> &GetProperties() noexcept { return properties; }
92         const Genome::Properties<double> &GetProperties() const noexcept { return properties; }
93
94         void AddMass(int res, double amount);
95         const Composition &GetComposition() const noexcept { return composition; }
96
97         void BaseColor(const glm::dvec3 &c) noexcept { base_color = c; }
98         const glm::dvec3 &BaseColor() const noexcept { return base_color; }
99
100         void HighlightColor(const glm::dvec3 &c) noexcept;
101         glm::dvec4 HighlightColor() const noexcept { return highlight_color; }
102
103         void Mass(double m) noexcept { mass = m; }
104         double Mass() const noexcept { return mass; }
105         void Ingest(int res, double amount) noexcept;
106
107         void Size(double s) noexcept { size = s; }
108         double Size() const noexcept { return size; }
109
110         double Born() const noexcept { return birth; }
111         double Age() const noexcept;
112         /// age-depended multiplier, peak being the maximum in lifetime [0,1]
113         double AgeFactor(double peak) const noexcept;
114
115         double ExhaustionFactor() const noexcept;
116         double FatigueFactor() const noexcept;
117
118         // stats with effects applied
119         double Strength() const noexcept;
120         double Stamina() const noexcept;
121         double Dexerty() const noexcept;
122         double Intelligence() const noexcept;
123         double Lifetime() const noexcept;
124         double Fertility() const noexcept;
125         double Mutability() const noexcept;
126         double OffspringMass() const noexcept;
127
128         /// chance of giving birth per tick
129         double OffspringChance() const noexcept;
130         /// chance of random genetic mutation per tick
131         double MutateChance() const noexcept;
132
133         void Hurt(double d) noexcept;
134         void Die() noexcept;
135         void OnDeath(Callback cb) noexcept { on_death = cb; }
136         void Remove() noexcept { removable = true; }
137         bool Removable() const noexcept { return removable; }
138
139         Stats &GetStats() noexcept { return stats; }
140         const Stats &GetStats() const noexcept { return stats; }
141
142         Memory &GetMemory() noexcept { return memory; }
143         const Memory &GetMemory() const noexcept { return memory; }
144
145         /// constantly active goal. every creature in the simulation is required to have one
146         void SetBackgroundTask(std::unique_ptr<Goal> &&g) { bg_task = std::move(g); }
147         Goal &BackgroundTask() { return *bg_task; }
148
149         void AddGoal(std::unique_ptr<Goal> &&);
150         const std::vector<std::unique_ptr<Goal>> &Goals() const noexcept { return goals; }
151
152         void Tick(double dt);
153
154         Situation &GetSituation() noexcept { return situation; }
155         const Situation &GetSituation() const noexcept { return situation; }
156
157         Steering &GetSteering() noexcept { return steering; }
158         const Steering &GetSteering() const noexcept { return steering; }
159
160         glm::dmat4 LocalTransform() noexcept;
161
162         void BuildVAO();
163         void Draw(graphics::Viewport &);
164
165 private:
166         void TickState(double dt);
167         void TickStats(double dt);
168         void TickBrain(double dt);
169         Situation::Derivative Step(const Situation::Derivative &ds, double dt) const noexcept;
170
171 private:
172         world::Simulation &sim;
173         std::string name;
174
175         Genome genome;
176         Genome::Properties<double> properties;
177         Composition composition;
178
179         glm::dvec3 base_color;
180         glm::dvec4 highlight_color;
181
182         double mass;
183         double size;
184
185         double birth;
186         Callback on_death;
187         bool removable;
188
189         Stats stats;
190         Memory memory;
191
192         std::unique_ptr<Goal> bg_task;
193         std::vector<std::unique_ptr<Goal>> goals;
194
195         Situation situation;
196         Steering steering;
197
198         struct Attributes {
199                 glm::vec3 position;
200                 glm::vec3 normal;
201                 glm::vec3 texture;
202         };
203         graphics::SimpleVAO<Attributes, unsigned short> vao;
204
205 };
206
207 /// put creature on planet and configure it to (hopefully) survive
208 void Spawn(Creature &, world::Planet &);
209
210 /// split the creature into two
211 void Split(Creature &);
212
213 }
214 }
215
216 #endif